121 lines
4.1 KiB
JavaScript
121 lines
4.1 KiB
JavaScript
import { computed, ref } from 'vue'
|
|
import { useStore } from 'vuex'
|
|
import {
|
|
getNotificationsApi, markAsReadApi, markAllAsReadApi,
|
|
deleteNotificationApi, clearNotificationsApi
|
|
} from '@/utils/api.js'
|
|
|
|
const GROUPS = [
|
|
{ type: 'activity', label: '活动通知' },
|
|
{ type: 'feedback_replied', label: '反馈回复' },
|
|
{ type: 'report_resolved', label: '举报结果' },
|
|
{ type: 'target_reported', label: '被举报' },
|
|
]
|
|
|
|
export function useMailboxCenter() {
|
|
const store = useStore()
|
|
|
|
const itemsByType = computed(() => store.state.mailbox.itemsByType)
|
|
const unreadByType = computed(() => store.state.mailbox.unreadByType)
|
|
const loading = computed(() => store.state.mailbox.loading)
|
|
const hasAny = computed(() => GROUPS.some(g => (itemsByType.value[g.type] || []).length > 0))
|
|
const hasMore = computed(() => Object.values(store.state.mailbox.noMoreByType).some(v => !v))
|
|
|
|
const collapsedMap = ref({})
|
|
collapsedMap.value = (() => {
|
|
try { return uni.getStorageSync('mailbox_collapsed') || {} } catch (e) { return {} }
|
|
})()
|
|
|
|
// 列表页 onShow 时并发 4 个 type 各拉首页
|
|
async function loadAll() {
|
|
store.commit('mailbox/SET_LOADING', true)
|
|
try {
|
|
await Promise.all(GROUPS.map(g =>
|
|
getNotificationsApi({ type: g.type, page: 1, page_size: 20 })
|
|
.then((resp) => {
|
|
const items = resp.data?.items || []
|
|
store.commit('mailbox/SET_ITEMS', { type: g.type, items, sortUnreadFirst: true })
|
|
store.commit('mailbox/SET_NO_MORE', { type: g.type, value: items.length < 20 })
|
|
if (resp.data?.unreadByType) store.commit('mailbox/REPLACE_UNREAD_BY_TYPE', resp.data.unreadByType)
|
|
})
|
|
))
|
|
} finally {
|
|
store.commit('mailbox/SET_LOADING', false)
|
|
}
|
|
}
|
|
|
|
function onScrollLower() {
|
|
const target = GROUPS.find(g => !store.state.mailbox.noMoreByType[g.type])
|
|
if (target) loadMore(target.type)
|
|
}
|
|
|
|
async function loadMore(type) {
|
|
const page = Math.floor((itemsByType.value[type].length / 20) + 1)
|
|
const resp = await getNotificationsApi({ type, page, page_size: 20 })
|
|
const items = resp.data?.items || []
|
|
store.commit('mailbox/APPEND_ITEMS', { type, items })
|
|
store.commit('mailbox/SET_NO_MORE', { type, value: items.length < 20 })
|
|
}
|
|
|
|
async function onMarkRead(nid, type) {
|
|
await markAsReadApi(nid)
|
|
store.commit('mailbox/UPDATE_ITEM', { type, id: nid, patch: { is_read: true } })
|
|
store.commit('mailbox/DECREMENT_TYPE', type)
|
|
store.commit('mailbox/RESORT_ITEMS', type) // 已读排后
|
|
}
|
|
|
|
async function onMarkAllRead() {
|
|
await Promise.all(GROUPS.map(g => markAllAsReadApi(g.type)))
|
|
store.commit('mailbox/MARK_ALL_READ')
|
|
}
|
|
|
|
async function onDeleteOne(nid, type) {
|
|
await deleteNotificationApi(nid)
|
|
store.commit('mailbox/REMOVE_ITEM', { type, id: nid })
|
|
}
|
|
|
|
async function onClearAll() {
|
|
const ok = await new Promise((resolve) => {
|
|
uni.showModal({ title: '提示', content: '清空所有通知?', success: (r) => resolve(r.confirm) })
|
|
})
|
|
if (!ok) return
|
|
await clearNotificationsApi('all')
|
|
store.commit('mailbox/CLEAR_ALL')
|
|
}
|
|
|
|
function onSelectItem(n) {
|
|
if (!n || !n.id) return
|
|
onMarkRead(n.id, n.type)
|
|
uni.navigateTo({ url: `/pages/mailbox/detail?nid=${n.id}&type=${n.type}` })
|
|
}
|
|
|
|
function onLongPress(n) {
|
|
if (!n || !n.id) return
|
|
uni.showActionSheet({
|
|
itemList: ['标已读', '删除'],
|
|
success: (res) => {
|
|
if (res.tapIndex === 0) onMarkRead(n.id, n.type)
|
|
else if (res.tapIndex === 1) onDeleteOne(n.id, n.type)
|
|
}
|
|
})
|
|
}
|
|
|
|
function isCollapsed(type) {
|
|
return !!collapsedMap.value[type]
|
|
}
|
|
|
|
function toggleCollapse(type) {
|
|
const next = { ...collapsedMap.value, [type]: !collapsedMap.value[type] }
|
|
collapsedMap.value = next
|
|
try { uni.setStorageSync('mailbox_collapsed', next) } catch (e) {}
|
|
}
|
|
|
|
return {
|
|
GROUPS,
|
|
itemsByType, unreadByType, loading, hasAny, hasMore,
|
|
loadAll, onScrollLower, loadMore,
|
|
onMarkRead, onMarkAllRead, onDeleteOne, onClearAll,
|
|
onSelectItem, onLongPress,
|
|
isCollapsed, toggleCollapse,
|
|
}
|
|
} |