From 16b23681a7af6a268914fe7bdb4e16f1f0ba275a Mon Sep 17 00:00:00 2001 From: xingyu <xingyu4j@vip.qq.com> Date: Tue, 25 Apr 2023 10:42:31 +0800 Subject: [PATCH] feat: mp message --- src/views/mp/message/MessageModal.vue | 43 ++++++++ src/views/mp/message/index.vue | 45 +++++++- src/views/mp/message/message.data.ts | 142 ++++++++++++++++++++++++++ 3 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 src/views/mp/message/MessageModal.vue create mode 100644 src/views/mp/message/message.data.ts diff --git a/src/views/mp/message/MessageModal.vue b/src/views/mp/message/MessageModal.vue new file mode 100644 index 0000000..69845b1 --- /dev/null +++ b/src/views/mp/message/MessageModal.vue @@ -0,0 +1,43 @@ +<template> + <BasicModal v-bind="$attrs" @register="registerModal" title="发送消息" @ok="handleSubmit"> + <BasicForm @register="registerForm" /> + </BasicModal> +</template> +<script lang="ts" setup name="MpMessageModal"> +import { BasicModal, useModalInner } from '@/components/Modal' +import { BasicForm, useForm } from '@/components/Form' +import { formSchema } from './message.data' +import { sendMessage } from '@/api/mp/message' +import { ref } from 'vue' + +const emit = defineEmits(['success', 'register']) + +const userId = ref(0) + +const [registerForm, { resetFields, validate }] = useForm({ + labelWidth: 120, + baseColProps: { span: 24 }, + schemas: formSchema, + showActionButtonGroup: false, + actionColOptions: { span: 23 } +}) + +const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { + resetFields() + setModalProps({ confirmLoading: false }) + userId.value = data.record.userId +}) + +async function handleSubmit() { + try { + const values = await validate() + values.userId = userId.value + setModalProps({ confirmLoading: true }) + await sendMessage(values) + closeModal() + emit('success') + } finally { + setModalProps({ confirmLoading: false }) + } +} +</script> diff --git a/src/views/mp/message/index.vue b/src/views/mp/message/index.vue index 3b64cfc..528f8d4 100644 --- a/src/views/mp/message/index.vue +++ b/src/views/mp/message/index.vue @@ -1,3 +1,46 @@ <template> - <div>开发中</div> + <div> + <BasicTable @register="registerTable"> + <template #bodyCell="{ column, record }"> + <template v-if="column.key === 'action'"> + <TableAction + :actions="[{ icon: IconEnum.VIEW, label: '消息', auth: 'mp:message:send', onClick: handleEdit.bind(null, record) }]" + /> + </template> + </template> + </BasicTable> + <AccountModal @register="registerModal" @success="reload()" /> + </div> </template> +<script lang="ts" setup name="MpMessage"> +import { useI18n } from '@/hooks/web/useI18n' +import { useModal } from '@/components/Modal' +import AccountModal from './MessageModal.vue' +import { IconEnum } from '@/enums/appEnum' +import { BasicTable, useTable, TableAction } from '@/components/Table' +import { getMessagePage } from '@/api/mp/message' +import { columns, searchFormSchema } from './message.data' + +const { t } = useI18n() +const [registerModal, { openModal }] = useModal() + +const [registerTable, { reload }] = useTable({ + title: '公众号消息列表', + api: getMessagePage, + columns, + formConfig: { labelWidth: 120, schemas: searchFormSchema }, + useSearchForm: true, + showTableSetting: true, + actionColumn: { + width: 140, + title: t('common.action'), + dataIndex: 'action', + fixed: 'right' + } +}) + +/** 修改按钮操作 */ +function handleEdit(record: Recordable) { + openModal(true, { record }) +} +</script> diff --git a/src/views/mp/message/message.data.ts b/src/views/mp/message/message.data.ts new file mode 100644 index 0000000..a6031b9 --- /dev/null +++ b/src/views/mp/message/message.data.ts @@ -0,0 +1,142 @@ +import { getStrDictOptions } from '@/utils/dict' +import { BasicColumn, FormSchema, useRender } from '@/components/Table' +import { DICT_TYPE } from '@/utils/dict' +import { getSimpleAccounts } from '@/api/mp/account' + +export enum MsgType { + Event = 'event', + Text = 'text', + Voice = 'voice', + Image = 'image', + Video = 'video', + Link = 'link', + Location = 'location', + Music = 'music', + News = 'news' +} + +export const columns: BasicColumn[] = [ + { + title: '发送时间', + dataIndex: 'createTime', + width: 180, + customRender: ({ text }) => { + return useRender.renderDate(text) + } + }, + { + title: '消息类型', + dataIndex: 'type', + width: 80, + customRender: ({ text }) => { + return useRender.renderDict(text, DICT_TYPE.MP_MESSAGE_TYPE, 'string') + } + }, + { + title: '发送方', + dataIndex: 'sendFrom', + width: 180, + customRender: ({ text }) => { + if (text === 1) { + return useRender.renderTag('粉丝', 'success') + } else { + return useRender.renderTag('公众号', 'default') + } + } + }, + { + title: '用户标识', + dataIndex: 'openid', + width: 300 + }, + { + title: '内容', + dataIndex: 'content', + width: 300, + customRender: ({ text, record }) => { + if (record.type === MsgType.Event && record.event === 'subscribe') { + return useRender.renderTag('关注', 'success') + } else if (record.type === MsgType.Event && record.event === 'unsubscribe') { + return useRender.renderTag('取消关注', 'warn') + } else if (record.type === MsgType.Event && record.event === 'CLICK') { + return useRender.renderTag('点击菜单' + record.eventKey) + } else if (record.type === MsgType.Event && record.event === 'VIEW') { + return useRender.renderTag('点击菜单链接' + record.eventKey) + } else if (record.type === MsgType.Event && record.event === 'scancode_waitmsg') { + return useRender.renderTag('扫码结果' + record.eventKey) + } else if (record.type === MsgType.Event && record.event === 'scancode_push') { + return useRender.renderTag('扫码结果' + record.eventKey) + } else if (record.type === MsgType.Event && record.event === 'pic_sysphoto') { + return useRender.renderTag('系统拍照发图') + } else if (record.type === MsgType.Event && record.event === 'pic_photo_or_album') { + return useRender.renderTag('拍照或者相册') + } else if (record.type === MsgType.Event && record.event === 'pic_weixin') { + return useRender.renderTag('微信相册') + } else if (record.type === MsgType.Event && record.event === 'location_select') { + return useRender.renderTag('选择地理位置') + } else if (record.type === MsgType.Event) { + return useRender.renderTag('未知事件类型') + } else if (record.type === MsgType.Text) { + return text + } else if (record.type === MsgType.Voice) { + // TODO voice + return record.mediaUrl + } else if (record.type === MsgType.Image) { + return useRender.renderImg(record.mediaUrl) + } else if (record.type === MsgType.Video || record.type === 'shortvideo') { + // TODO + return record.mediaUrl + } else if (record.type === MsgType.Link) { + return useRender.renderLink(record.url, record.title) + } else if (record.type === MsgType.Location) { + // TODO + return record.label + } else if (record.type === MsgType.Music) { + // TODO + return record.title + } else if (record.type === MsgType.News) { + // TODO + return record.articles + } else { + return useRender.renderTag('未知消息类型', 'warn') + } + } + } +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '公众号', + field: 'accountId', + component: 'ApiSelect', + componentProps: { + api: () => getSimpleAccounts(), + labelField: 'name', + valueField: 'id' + }, + colProps: { span: 8 } + }, + { + label: '消息类型', + field: 'type', + component: 'Select', + componentProps: { + options: getStrDictOptions(DICT_TYPE.MP_MESSAGE_TYPE) + }, + colProps: { span: 8 } + }, + { + label: '用户标识', + field: 'openid', + component: 'Select', + colProps: { span: 8 } + }, + { + label: '创建时间', + field: 'createTime', + component: 'RangePicker', + colProps: { span: 8 } + } +] + +export const formSchema: FormSchema[] = []