import type { MemberMessageReachTabKey } from '../types'; import type { MemberMessageReachChannel, MemberMessageReachDetailDto, MemberMessageReachStatus, MemberMessageTemplateCategory, } from '#/api/member/message-reach'; import { computed, onActivated, onMounted, reactive, ref, watch } from 'vue'; import { useAccessStore } from '@vben/stores'; import { createDefaultMessageReachEditorForm, createDefaultMessageReachFilterForm, createDefaultMessageReachPager, createDefaultMessageReachStats, createDefaultMessageTemplateEditorForm, createDefaultMessageTemplateFilterForm, createDefaultMessageTemplatePager, } from '../types'; import { MEMBER_MESSAGE_REACH_MANAGE_PERMISSION, MEMBER_MESSAGE_REACH_VIEW_PERMISSION, MESSAGE_REACH_TAB_OPTIONS, } from './message-reach-page/constants'; import { createDataActions } from './message-reach-page/data-actions'; import { resetMessageEditorForm, resetTemplateEditorForm, } from './message-reach-page/helpers'; import { createMessageActions } from './message-reach-page/message-actions'; import { createTemplateActions } from './message-reach-page/template-actions'; export function useMemberMessageReachPage() { const accessStore = useAccessStore(); const activeTab = ref('list'); const stats = ref(createDefaultMessageReachStats()); const isStatsLoading = ref(false); const messageFilterForm = reactive(createDefaultMessageReachFilterForm()); const messagePager = ref(createDefaultMessageReachPager()); const isMessageLoading = ref(false); const templateFilterForm = reactive(createDefaultMessageTemplateFilterForm()); const templatePager = ref(createDefaultMessageTemplatePager()); const isTemplateLoading = ref(false); const detail = ref(null); const isDetailLoading = ref(false); const isDetailDrawerOpen = ref(false); const detailDrawerMessageId = ref(''); const messageDrawerMode = ref<'create' | 'edit'>('create'); const form = reactive(createDefaultMessageReachEditorForm()); const isMessageDrawerOpen = ref(false); const isMessageSubmitting = ref(false); const audienceEstimateCount = ref(0); const isEstimatingAudience = ref(false); const templateEditorMode = ref<'create' | 'edit'>('create'); const templateForm = reactive(createDefaultMessageTemplateEditorForm()); const isTemplateEditorOpen = ref(false); const isTemplateEditorLoading = ref(false); const isTemplateSubmitting = ref(false); const accessCodeSet = computed( () => new Set((accessStore.accessCodes ?? []).map(String)), ); const canManage = computed(() => accessCodeSet.value.has(MEMBER_MESSAGE_REACH_MANAGE_PERMISSION), ); const canView = computed( () => canManage.value || accessCodeSet.value.has(MEMBER_MESSAGE_REACH_VIEW_PERMISSION), ); const messageDrawerTitle = computed(() => messageDrawerMode.value === 'create' ? '创建消息' : '编辑消息', ); const templateEditorTitle = computed(() => templateEditorMode.value === 'create' ? '新建模板' : '编辑模板', ); const templateEditorSubmitText = computed(() => templateEditorMode.value === 'create' ? '创建' : '保存', ); const { estimateAudience, loadMessageDetail, loadMessageList, loadStats, loadTemplateList, } = createDataActions({ audienceEstimateCount, detail, isDetailLoading, isEstimatingAudience, isMessageLoading, isStatsLoading, isTemplateLoading, messageFilterForm, messagePager, stats, templateFilterForm, templatePager, }); const { openCreateMessageDrawer, openDetailDrawer, openEditMessageDrawer, removeMessage, setAudienceType, setDetailDrawerOpen, setMessageContent, setMessageDrawerOpen, setMessageChannel, setMessageTitle, setScheduleType, setScheduledAt, submitMessage, switchToTemplateTab, toggleAudienceTag, useTemplateToCreateMessage, } = createMessageActions({ activeTab, audienceEstimateCount, canManage, detail, detailDrawerMessageId, form, isDetailDrawerOpen, isMessageDrawerOpen, isMessageSubmitting, messageDrawerMode, loadMessageDetail, loadMessageList, loadStats, }); const { openCreateTemplateModal, openEditTemplateModal, removeTemplate, setTemplateCategory, setTemplateContent, setTemplateEditorOpen, setTemplateName, submitTemplate, } = createTemplateActions({ canManage, form: templateForm, isTemplateEditorLoading, isTemplateEditorOpen, isTemplateSubmitting, loadTemplateList, mode: templateEditorMode, }); function setActiveTab(value: MemberMessageReachTabKey) { activeTab.value = value; } function setMessageStatusFilter(value: string) { messageFilterForm.status = (value || undefined) as | MemberMessageReachStatus | undefined; } function setMessageChannelFilter(value: string) { messageFilterForm.channel = (value || undefined) as | MemberMessageReachChannel | undefined; } function setMessageKeyword(value: string) { messageFilterForm.keyword = value; } async function applyMessageFilters() { messagePager.value = { ...messagePager.value, page: 1, }; await loadMessageList(); } async function resetMessageFilters() { messageFilterForm.status = undefined; messageFilterForm.channel = undefined; messageFilterForm.keyword = ''; messagePager.value = { ...messagePager.value, page: 1, }; await loadMessageList(); } async function handleMessagePageChange(page: number, pageSize: number) { messagePager.value = { ...messagePager.value, page, pageSize, }; await loadMessageList(); } function setTemplateCategoryFilter(value: string) { templateFilterForm.category = (value || undefined) as | MemberMessageTemplateCategory | undefined; } function setTemplateKeyword(value: string) { templateFilterForm.keyword = value; } async function applyTemplateFilters() { templatePager.value = { ...templatePager.value, page: 1, }; await loadTemplateList(); } async function resetTemplateFilters() { templateFilterForm.category = undefined; templateFilterForm.keyword = ''; templatePager.value = { ...templatePager.value, page: 1, }; await loadTemplateList(); } async function handleTemplatePageChange(page: number, pageSize: number) { templatePager.value = { ...templatePager.value, page, pageSize, }; await loadTemplateList(); } async function setAudienceTypeAndEstimate(value: 'all' | 'tag') { setAudienceType(value); if (value === 'all') { audienceEstimateCount.value = 0; return; } await estimateAudience('tag', form.audienceTags); } async function toggleAudienceTagAndEstimate(tag: string) { toggleAudienceTag(tag); if (form.audienceType !== 'tag') { return; } await estimateAudience('tag', form.audienceTags); } async function submitDraftMessage() { await submitMessage('draft'); } async function submitSendMessage() { await submitMessage('send'); } function clearByPermission() { stats.value = createDefaultMessageReachStats(); messagePager.value = createDefaultMessageReachPager(); templatePager.value = createDefaultMessageTemplatePager(); detail.value = null; isDetailDrawerOpen.value = false; detailDrawerMessageId.value = ''; resetMessageEditorForm(form); audienceEstimateCount.value = 0; isMessageDrawerOpen.value = false; resetTemplateEditorForm(templateForm); isTemplateEditorOpen.value = false; } async function bootstrapPageData() { await Promise.all([loadStats(), loadMessageList(), loadTemplateList()]); } watch(canView, async (value, oldValue) => { if (value === oldValue) { return; } if (!value) { clearByPermission(); return; } await bootstrapPageData(); }); onMounted(async () => { if (!canView.value) { clearByPermission(); return; } await bootstrapPageData(); }); onActivated(() => { if (!canView.value) { return; } if ( messagePager.value.totalCount === 0 && templatePager.value.totalCount === 0 ) { void bootstrapPageData(); } }); return { activeTab, applyMessageFilters, applyTemplateFilters, audienceEstimateCount, canManage, canView, detail, form, handleMessagePageChange, handleTemplatePageChange, isDetailDrawerOpen, isDetailLoading, isEstimatingAudience, isMessageDrawerOpen, isMessageLoading, isMessageSubmitting, isStatsLoading, isTemplateEditorLoading, isTemplateEditorOpen, isTemplateLoading, isTemplateSubmitting, messageDrawerTitle, messageFilterForm, messagePager, openCreateMessageDrawer, openCreateTemplateModal, openDetailDrawer, openEditMessageDrawer, openEditTemplateModal, removeMessage, removeTemplate, resetMessageFilters, resetTemplateFilters, setActiveTab, setAudienceTypeAndEstimate, setDetailDrawerOpen, setMessageChannel, setMessageChannelFilter, setMessageContent, setMessageDrawerOpen, setMessageKeyword, setMessageStatusFilter, setMessageTitle, setScheduleType, setScheduledAt, setTemplateCategory, setTemplateCategoryFilter, setTemplateContent, setTemplateEditorOpen, setTemplateKeyword, setTemplateName, stats, submitDraftMessage, submitSendMessage, submitTemplate, switchToTemplateTab, tabOptions: MESSAGE_REACH_TAB_OPTIONS, templateEditorSubmitText, templateEditorTitle, templateFilterForm, templateForm, templatePager, toggleAudienceTagAndEstimate, useTemplateToCreateMessage, }; }