feat: 公告開關
This commit is contained in:
@@ -1,209 +0,0 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
export interface LoginAnnouncementItem {
|
||||
id: string | number
|
||||
date: string
|
||||
school: string
|
||||
title: string
|
||||
tab?: string
|
||||
detail: string
|
||||
}
|
||||
|
||||
export interface LoginAnnouncementListItem {
|
||||
id: string | number
|
||||
date: string
|
||||
school: string
|
||||
title: string
|
||||
tab?: string
|
||||
}
|
||||
|
||||
export interface LoginMobileAnnouncementItem {
|
||||
id: string | number
|
||||
content: string
|
||||
title?: string
|
||||
createdAt?: string
|
||||
}
|
||||
|
||||
const storageKey = 'sk_playground_login_announcements'
|
||||
|
||||
const defaultItems: LoginAnnouncementItem[] = [
|
||||
{
|
||||
id: 'announcement-1',
|
||||
date: '2024-03-19',
|
||||
school: '市立實踐國中',
|
||||
title: '臺北市立實踐國中徵求113學年度教學支援工作人員',
|
||||
tab: 'junior',
|
||||
detail: '公告內容:本校辦理本土語教學支援工作人員甄選,請於期限內完成報名與資料繳交。',
|
||||
},
|
||||
{
|
||||
id: 'announcement-2',
|
||||
date: '2023-12-12',
|
||||
school: '市立華江高中',
|
||||
title: '臺北市立華江高級中學112學年度第二學期本土語教學支援人員甄選',
|
||||
tab: 'senior',
|
||||
detail: '公告內容:甄選包含書面審查與面試,相關時間地點請參閱簡章附件。',
|
||||
},
|
||||
{
|
||||
id: 'announcement-3',
|
||||
date: '2023-12-05',
|
||||
school: '市立麗山高中',
|
||||
title: '內湖區麗山高中誠徵閩南語教支人員數名',
|
||||
tab: 'senior',
|
||||
detail: '公告內容:需具備相關教學經驗,錄取後依課務需求排課。',
|
||||
},
|
||||
{
|
||||
id: 'announcement-4',
|
||||
date: '2023-11-28',
|
||||
school: '市立永吉國中',
|
||||
title: '公告本市學校本土語教學支援人員報名資訊',
|
||||
tab: 'junior',
|
||||
detail: '公告內容:統一受理報名,請依公告流程檢附文件並完成線上登錄。',
|
||||
},
|
||||
{
|
||||
id: 'announcement-5',
|
||||
date: '2023-11-21',
|
||||
school: '市立百齡高中',
|
||||
title: '112學年度本土語文教學支援工作人員甄選簡章',
|
||||
tab: 'senior',
|
||||
detail: '公告內容:簡章含資格條件、甄選方式、成績計算與錄取標準。',
|
||||
},
|
||||
{
|
||||
id: 'announcement-6',
|
||||
date: '2023-11-10',
|
||||
school: '市立成德國中',
|
||||
title: '本土語教學支援工作人員甄選(第二次)',
|
||||
tab: 'junior',
|
||||
detail: '公告內容:第二次甄選開放補件,報名截止日以公告為準。',
|
||||
},
|
||||
]
|
||||
|
||||
function readItems(): LoginAnnouncementItem[] {
|
||||
if (typeof window === 'undefined') return defaultItems
|
||||
try {
|
||||
const raw = window.localStorage.getItem(storageKey)
|
||||
if (!raw) return defaultItems
|
||||
const parsed = JSON.parse(raw)
|
||||
return Array.isArray(parsed) ? (parsed as LoginAnnouncementItem[]) : defaultItems
|
||||
} catch {
|
||||
return defaultItems
|
||||
}
|
||||
}
|
||||
|
||||
function writeItems(items: LoginAnnouncementItem[]) {
|
||||
if (typeof window === 'undefined') return
|
||||
try {
|
||||
window.localStorage.setItem(storageKey, JSON.stringify(items))
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
async function mockFetchMobileAnnouncementsApi(): Promise<LoginMobileAnnouncementItem[]> {
|
||||
return [
|
||||
{
|
||||
id: 'mobile-announcement-1',
|
||||
content: '系統正常運行中',
|
||||
title: '系統公告',
|
||||
createdAt: '2026-02-11',
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
export const useLoginAnnouncementsStore = defineStore('loginAnnouncements', () => {
|
||||
const items = ref<LoginAnnouncementItem[]>(readItems())
|
||||
const selectedId = ref<string | number | null>(null)
|
||||
const mobileAnnouncements = ref<LoginMobileAnnouncementItem[]>([])
|
||||
|
||||
const listItems = computed<LoginAnnouncementListItem[]>(() =>
|
||||
items.value.map((item) => ({
|
||||
id: item.id,
|
||||
date: item.date,
|
||||
school: item.school,
|
||||
title: item.title,
|
||||
tab: item.tab,
|
||||
}))
|
||||
)
|
||||
|
||||
const boardConfig = computed(() => ({
|
||||
title: '學校公告區',
|
||||
tabs: [
|
||||
{ label: '全部', value: '__all__' },
|
||||
{ label: '國中', value: 'junior' },
|
||||
{ label: '高中', value: 'senior' },
|
||||
],
|
||||
items: listItems.value,
|
||||
systemAnnouncements: mobileAnnouncements.value,
|
||||
itemsPerPage: 5,
|
||||
dateHeader: '公告時間',
|
||||
schoolHeader: '公告學校',
|
||||
titleHeader: '公告標題',
|
||||
paginationLabel: '總筆數:',
|
||||
}))
|
||||
|
||||
const selectedAnnouncement = computed(() => {
|
||||
if (selectedId.value === null) return null
|
||||
return items.value.find((item) => item.id === selectedId.value) ?? null
|
||||
})
|
||||
|
||||
const selectedAnnouncementDetail = computed(() => {
|
||||
return selectedAnnouncement.value?.detail ?? ''
|
||||
})
|
||||
|
||||
const mobileAnnouncementConfig = computed(() => ({
|
||||
items: mobileAnnouncements.value,
|
||||
show: mobileAnnouncements.value.length > 0,
|
||||
viewAllText: '查看全部',
|
||||
listTitle: '系統公告',
|
||||
closeText: '關閉',
|
||||
emptyText: '目前沒有公告',
|
||||
}))
|
||||
|
||||
const hydrate = () => {
|
||||
items.value = readItems()
|
||||
}
|
||||
|
||||
const replaceAll = (nextItems: LoginAnnouncementItem[]) => {
|
||||
items.value = Array.isArray(nextItems) ? nextItems : []
|
||||
}
|
||||
|
||||
const selectById = (id: string | number) => {
|
||||
selectedId.value = id
|
||||
}
|
||||
|
||||
const clearSelection = () => {
|
||||
selectedId.value = null
|
||||
}
|
||||
|
||||
const fetchMobileAnnouncements = async () => {
|
||||
const result = await mockFetchMobileAnnouncementsApi()
|
||||
mobileAnnouncements.value = Array.isArray(result) ? result : []
|
||||
}
|
||||
|
||||
const fetchMobileAnnouncement = async () => {
|
||||
await fetchMobileAnnouncements()
|
||||
}
|
||||
|
||||
watch(
|
||||
items,
|
||||
(val) => {
|
||||
writeItems(val)
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
return {
|
||||
items,
|
||||
listItems,
|
||||
boardConfig,
|
||||
mobileAnnouncementConfig,
|
||||
selectedAnnouncement,
|
||||
selectedAnnouncementDetail,
|
||||
hydrate,
|
||||
replaceAll,
|
||||
selectById,
|
||||
clearSelection,
|
||||
fetchMobileAnnouncements,
|
||||
fetchMobileAnnouncement,
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user