diff --git a/src/views/mp/account/index.vue b/src/views/mp/account/index.vue index a5275d3..7903dbe 100644 --- a/src/views/mp/account/index.vue +++ b/src/views/mp/account/index.vue @@ -12,13 +12,13 @@ :actions="[ { icon: IconEnum.EDIT, label: t('action.edit'), auth: 'mp:account:update', onClick: handleEdit.bind(null, record) }, { - icon: IconEnum.EDIT, + icon: IconEnum.RESET, label: '生成二维码', auth: 'mp:account:qr-code', onClick: handleGenerateQrCode.bind(null, record) }, { - icon: IconEnum.EDIT, + icon: IconEnum.TEST, label: '清空 API 配额', auth: 'mp:account:clear-quota', onClick: handleCleanQuota.bind(null, record) diff --git a/src/views/mp/mpuser/MpUserModal.vue b/src/views/mp/mpuser/MpUserModal.vue new file mode 100644 index 0000000..c3bc52b --- /dev/null +++ b/src/views/mp/mpuser/MpUserModal.vue @@ -0,0 +1,40 @@ +<template> + <BasicModal v-bind="$attrs" @register="registerModal" title="编辑" @ok="handleSubmit"> + <BasicForm @register="registerForm" /> + </BasicModal> +</template> +<script lang="ts" setup name="MpUserModal"> +import { BasicModal, useModalInner } from '@/components/Modal' +import { BasicForm, useForm } from '@/components/Form' +import { formSchema } from './mpuser.data' +import { getUser, updateUser } from '@/api/mp/mpuser' + +const emit = defineEmits(['success', 'register']) + +const [registerForm, { setFieldsValue, 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 }) + const res = await getUser(data.record.id) + setFieldsValue({ ...res }) +}) + +async function handleSubmit() { + try { + const values = await validate() + setModalProps({ confirmLoading: true }) + await updateUser(values) + closeModal() + emit('success') + } finally { + setModalProps({ confirmLoading: false }) + } +} +</script> diff --git a/src/views/mp/mpuser/index.vue b/src/views/mp/mpuser/index.vue index 3b64cfc..b663411 100644 --- a/src/views/mp/mpuser/index.vue +++ b/src/views/mp/mpuser/index.vue @@ -1,3 +1,66 @@ <template> - <div>开发中</div> + <div> + <BasicTable @register="registerTable"> + <template #toolbar> + <a-button type="primary" v-auth="['mp:user:sync']" :preIcon="IconEnum.RESET" @click="handleSync"> + {{ t('action.create') }} + </a-button> + </template> + <template #bodyCell="{ column }"> + <template v-if="column.key === 'action'"> + <TableAction + :actions="[{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'mp:user:update', onClick: handleEdit.bind(null) }]" + /> + </template> + </template> + </BasicTable> + <MpUserModal @register="registerModal" @success="reload()" /> + </div> </template> +<script lang="ts" setup name="MpUser"> +import { useI18n } from '@/hooks/web/useI18n' +import { useMessage } from '@/hooks/web/useMessage' +import { useModal } from '@/components/Modal' +import MpUserModal from './MpUserModal.vue' +import { IconEnum } from '@/enums/appEnum' +import { BasicTable, useTable, TableAction } from '@/components/Table' +import { getUserPage, syncUser } from '@/api/mp/mpuser' +import { columns, searchFormSchema } from './mpuser.data' + +const { t } = useI18n() +const { createConfirm, createMessage } = useMessage() +const [registerModal, { openModal }] = useModal() + +const [registerTable, { getForm, reload }] = useTable({ + title: '公众号账号列表', + api: getUserPage, + columns, + formConfig: { labelWidth: 120, schemas: searchFormSchema }, + useSearchForm: true, + showTableSetting: true, + actionColumn: { + width: 140, + title: t('common.action'), + dataIndex: 'action', + fixed: 'right' + } +}) + +/** 同步按钮操作 */ +async function handleSync() { + createConfirm({ + title: '同步粉丝', + iconType: 'warning', + content: '是否确认同步粉丝?', + async onOk() { + await syncUser(getForm().getFieldsValue().accountId) + createMessage.success('开始从微信公众号同步粉丝信息,同步需要一段时间,建议稍后再查询') + } + }) +} + +/** 修改按钮操作 */ +function handleEdit(record: Recordable) { + openModal(true, { record }) +} +</script> diff --git a/src/views/mp/mpuser/mpuser.data.ts b/src/views/mp/mpuser/mpuser.data.ts new file mode 100644 index 0000000..48a8959 --- /dev/null +++ b/src/views/mp/mpuser/mpuser.data.ts @@ -0,0 +1,110 @@ +import { getSimpleAccounts } from '@/api/mp/account' +import { getSimpleTags } from '@/api/mp/tag' +import { BasicColumn, FormSchema, useRender } from '@/components/Table' + +export const columns: BasicColumn[] = [ + { + title: '岗位编号', + dataIndex: 'id', + width: 100 + }, + { + title: '用户标识', + dataIndex: 'openid', + width: 180 + }, + { + title: '昵称', + dataIndex: 'nickname', + width: 100 + }, + { + title: '备注', + dataIndex: 'remark', + width: 120 + }, + { + title: '标签', + dataIndex: 'tagIds', + width: 180, + customRender: ({ text }) => { + return useRender.renderTags(text) + } + }, + { + title: '订阅状态', + dataIndex: 'subscribeStatus', + width: 180, + customRender: ({ text }) => { + return useRender.renderTag(text === 0 ? '已订阅' : '未订阅', text === 0 ? 'purple' : 'orange') + } + }, + { + title: '订阅时间', + dataIndex: 'subscribeTime', + width: 180, + customRender: ({ text }) => { + return useRender.renderDate(text) + } + } +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '公众号', + field: 'accountId', + component: 'ApiSelect', + componentProps: { + api: () => getSimpleAccounts(), + labelField: 'name', + valueField: 'id' + }, + colProps: { span: 8 } + }, + { + label: '用户标识', + field: 'openid', + component: 'Input', + colProps: { span: 8 } + }, + { + label: '昵称', + field: 'nickname', + component: 'Input', + colProps: { span: 8 } + } +] + +export const formSchema: FormSchema[] = [ + { + label: '编号', + field: 'id', + show: false, + component: 'Input' + }, + { + label: '昵称', + field: 'nickname', + required: true, + component: 'Input' + }, + { + label: '备注', + field: 'remark', + required: true, + component: 'Input' + }, + { + label: '标签', + field: 'tagIds', + helpMessage: '在微信公众平台(mp.weixin.qq.com)的菜单 [设置与开发 - 公众号设置 - 基本设置] 中能找到「开发者ID(AppID)」', + required: true, + component: 'ApiSelect', + componentProps: { + api: () => getSimpleTags(), + labelField: 'name', + valueField: 'tagId', + mode: 'tags' + } + } +]