feat:【antd】【mp】mp 的代码评审(autoReply)
This commit is contained in:
@@ -8,7 +8,7 @@ import { getDictOptions } from '@vben/hooks';
|
|||||||
|
|
||||||
import { WxReply } from '#/views/mp/components';
|
import { WxReply } from '#/views/mp/components';
|
||||||
|
|
||||||
// TODO @芋艿:要不要使用统一枚举?
|
// TODO @hw:要不要使用统一枚举?
|
||||||
const RequestMessageTypes = new Set([
|
const RequestMessageTypes = new Set([
|
||||||
'image',
|
'image',
|
||||||
'link',
|
'link',
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import type { MpAutoReplyApi } from '#/api/mp/autoReply';
|
|||||||
import { computed, nextTick, ref } from 'vue';
|
import { computed, nextTick, ref } from 'vue';
|
||||||
|
|
||||||
import { confirm, DocAlert, Page, useVbenModal } from '@vben/common-ui';
|
import { confirm, DocAlert, Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
// TODO @hw:直接使用 AutoReplyMsgType,不用 as
|
||||||
import { AutoReplyMsgType as MsgType } from '@vben/constants';
|
import { AutoReplyMsgType as MsgType } from '@vben/constants';
|
||||||
import { IconifyIcon } from '@vben/icons';
|
import { IconifyIcon } from '@vben/icons';
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ function handleAccountChange(accountId: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 切换回复类型 */
|
/** 切换回复类型 */
|
||||||
async function onTabChange(tabName: any) {
|
async function onTabChange(tabName: string) {
|
||||||
msgType.value = tabName;
|
msgType.value = tabName;
|
||||||
await nextTick();
|
await nextTick();
|
||||||
// 更新 columns
|
// 更新 columns
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const props = defineProps<{
|
|||||||
</div>
|
</div>
|
||||||
<div v-else-if="props.row.responseMessageType === 'image'">
|
<div v-else-if="props.row.responseMessageType === 'image'">
|
||||||
<a target="_blank" :href="props.row.responseMediaUrl">
|
<a target="_blank" :href="props.row.responseMediaUrl">
|
||||||
<img :src="props.row.responseMediaUrl" style="width: 100px" />
|
<img :src="props.row.responseMediaUrl" class="w-[100px]" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -38,7 +38,7 @@ const props = defineProps<{
|
|||||||
<WxVideoPlayer
|
<WxVideoPlayer
|
||||||
v-if="props.row.responseMediaUrl"
|
v-if="props.row.responseMediaUrl"
|
||||||
:url="props.row.responseMediaUrl"
|
:url="props.row.responseMediaUrl"
|
||||||
style="margin-top: 10px"
|
class="mt-[10px]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="props.row.responseMessageType === 'news'">
|
<div v-else-if="props.row.responseMessageType === 'news'">
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { MsgType } from './modules/types';
|
|||||||
let accountList: MpAccountApi.AccountSimple[] = [];
|
let accountList: MpAccountApi.AccountSimple[] = [];
|
||||||
getSimpleAccountList().then((data) => (accountList = data));
|
getSimpleAccountList().then((data) => (accountList = data));
|
||||||
|
|
||||||
|
// TODO @hw:要不要使用统一枚举?
|
||||||
const RequestMessageTypes = new Set([
|
const RequestMessageTypes = new Set([
|
||||||
'image',
|
'image',
|
||||||
'link',
|
'link',
|
||||||
@@ -25,6 +26,7 @@ const RequestMessageTypes = new Set([
|
|||||||
'video',
|
'video',
|
||||||
'voice',
|
'voice',
|
||||||
]); // 允许选择的请求消息类型
|
]); // 允许选择的请求消息类型
|
||||||
|
|
||||||
/** 获取表格列配置 */
|
/** 获取表格列配置 */
|
||||||
export function useGridColumns(msgType: MsgType): VxeGridPropTypes.Columns {
|
export function useGridColumns(msgType: MsgType): VxeGridPropTypes.Columns {
|
||||||
const columns: VxeGridPropTypes.Columns = [];
|
const columns: VxeGridPropTypes.Columns = [];
|
||||||
@@ -65,6 +67,7 @@ export function useGridColumns(msgType: MsgType): VxeGridPropTypes.Columns {
|
|||||||
field: 'responseMessageType',
|
field: 'responseMessageType',
|
||||||
title: '回复消息类型',
|
title: '回复消息类型',
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
|
// TODO @hw:这里和 antd 有差别。两侧尽量统一;
|
||||||
formatter: ({ cellValue }) =>
|
formatter: ({ cellValue }) =>
|
||||||
getDictObj(DICT_TYPE.MP_MESSAGE_TYPE, String(cellValue))?.label ?? '',
|
getDictObj(DICT_TYPE.MP_MESSAGE_TYPE, String(cellValue))?.label ?? '',
|
||||||
},
|
},
|
||||||
@@ -93,7 +96,9 @@ export function useGridColumns(msgType: MsgType): VxeGridPropTypes.Columns {
|
|||||||
/** 新增/修改的表单 */
|
/** 新增/修改的表单 */
|
||||||
export function useFormSchema(msgType: MsgType): VbenFormSchema[] {
|
export function useFormSchema(msgType: MsgType): VbenFormSchema[] {
|
||||||
const schema: VbenFormSchema[] = [];
|
const schema: VbenFormSchema[] = [];
|
||||||
|
|
||||||
// 消息类型(仅消息回复显示)
|
// 消息类型(仅消息回复显示)
|
||||||
|
// TODO @hw:这里和 antd 有差别。两侧尽量统一;
|
||||||
if (Number(msgType) === MsgType.Message) {
|
if (Number(msgType) === MsgType.Message) {
|
||||||
schema.push({
|
schema.push({
|
||||||
fieldName: 'requestMessageType',
|
fieldName: 'requestMessageType',
|
||||||
@@ -109,6 +114,7 @@ export function useFormSchema(msgType: MsgType): VbenFormSchema[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 匹配类型(仅关键词回复显示)
|
// 匹配类型(仅关键词回复显示)
|
||||||
|
// TODO @hw:这里和 antd 有差别。两侧尽量统一;
|
||||||
if (Number(msgType) === MsgType.Keyword) {
|
if (Number(msgType) === MsgType.Keyword) {
|
||||||
schema.push({
|
schema.push({
|
||||||
fieldName: 'requestMatch',
|
fieldName: 'requestMatch',
|
||||||
@@ -127,6 +133,7 @@ export function useFormSchema(msgType: MsgType): VbenFormSchema[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 关键词(仅关键词回复显示)
|
// 关键词(仅关键词回复显示)
|
||||||
|
// TODO @hw:这里和 antd 有差别。两侧尽量统一;
|
||||||
if (Number(msgType) === MsgType.Keyword) {
|
if (Number(msgType) === MsgType.Keyword) {
|
||||||
schema.push({
|
schema.push({
|
||||||
fieldName: 'requestKeyword',
|
fieldName: 'requestKeyword',
|
||||||
@@ -140,6 +147,7 @@ export function useFormSchema(msgType: MsgType): VbenFormSchema[] {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 回复消息
|
// 回复消息
|
||||||
|
// TODO @hw:这里和 antd 有差别。两侧尽量统一;
|
||||||
schema.push({
|
schema.push({
|
||||||
fieldName: 'reply',
|
fieldName: 'reply',
|
||||||
label: '回复消息',
|
label: '回复消息',
|
||||||
@@ -149,6 +157,7 @@ export function useFormSchema(msgType: MsgType): VbenFormSchema[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 列表的搜索表单 */
|
/** 列表的搜索表单 */
|
||||||
|
// TODO @hw:是不是用 wxselect 组件哈?
|
||||||
export function useGridFormSchema(): VbenFormSchema[] {
|
export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,7 +16,11 @@ import {
|
|||||||
} from 'element-plus';
|
} from 'element-plus';
|
||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import * as MpAutoReplyApi from '#/api/mp/autoReply';
|
import {
|
||||||
|
deleteAutoReply,
|
||||||
|
getAutoReply,
|
||||||
|
getAutoReplyPage,
|
||||||
|
} from '#/api/mp/autoReply';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
import { WxAccountSelect } from '#/views/mp/components';
|
import { WxAccountSelect } from '#/views/mp/components';
|
||||||
|
|
||||||
@@ -29,11 +33,29 @@ defineOptions({ name: 'MpAutoReply' });
|
|||||||
|
|
||||||
const msgType = ref<string>(String(MsgType.Keyword)); // 消息类型
|
const msgType = ref<string>(String(MsgType.Keyword)); // 消息类型
|
||||||
|
|
||||||
|
const showCreateButton = computed(() => {
|
||||||
|
if (Number(msgType.value) !== MsgType.Follow) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const tableData = gridApi.grid?.getTableData();
|
||||||
|
return (tableData?.tableData?.length || 0) <= 0;
|
||||||
|
} catch {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}); // 计算是否显示新增按钮:关注时回复类型只有在没有数据时才显示
|
||||||
|
|
||||||
|
/** 刷新表格 */
|
||||||
|
function handleRefresh() {
|
||||||
|
gridApi.query();
|
||||||
|
}
|
||||||
|
|
||||||
/** 公众号变化时查询数据 */
|
/** 公众号变化时查询数据 */
|
||||||
function handleAccountChange(accountId: number) {
|
function handleAccountChange(accountId: number) {
|
||||||
gridApi.formApi.setValues({ accountId });
|
gridApi.formApi.setValues({ accountId });
|
||||||
gridApi.formApi.submitForm();
|
gridApi.formApi.submitForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 切换回复类型 */
|
/** 切换回复类型 */
|
||||||
async function onTabChange(tabName: string) {
|
async function onTabChange(tabName: string) {
|
||||||
msgType.value = tabName;
|
msgType.value = tabName;
|
||||||
@@ -50,24 +72,26 @@ async function onTabChange(tabName: string) {
|
|||||||
await gridApi.query();
|
await gridApi.query();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 新增按钮操作 */
|
/** 新增自动回复 */
|
||||||
async function handleCreate() {
|
async function handleCreate() {
|
||||||
const formValues = await gridApi.formApi.getValues();
|
const formValues = await gridApi.formApi.getValues();
|
||||||
|
|
||||||
formModalApi
|
formModalApi
|
||||||
.setData({
|
.setData({
|
||||||
|
// TODO @hw:这里和 antd 不同,需要 number 下么?
|
||||||
msgType: msgType.value,
|
msgType: msgType.value,
|
||||||
accountId: formValues.accountId,
|
accountId: formValues.accountId,
|
||||||
})
|
})
|
||||||
.open();
|
.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 修改按钮操作 */
|
/** 修改自动回复 */
|
||||||
async function handleEdit(row: any) {
|
async function handleEdit(row: any) {
|
||||||
const data = (await MpAutoReplyApi.getAutoReply(row.id)) as any;
|
const data = (await getAutoReply(row.id)) as any;
|
||||||
|
// TODO @hw:这里使用 formValues,还是使用 row?
|
||||||
const formValues = await gridApi.formApi.getValues();
|
const formValues = await gridApi.formApi.getValues();
|
||||||
formModalApi
|
formModalApi
|
||||||
.setData({
|
.setData({
|
||||||
|
// TODO @hw:这里和 antd 不同,需要 number 下么?
|
||||||
msgType: msgType.value,
|
msgType: msgType.value,
|
||||||
row: data,
|
row: data,
|
||||||
accountId: formValues.accountId,
|
accountId: formValues.accountId,
|
||||||
@@ -75,14 +99,14 @@ async function handleEdit(row: any) {
|
|||||||
.open();
|
.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 删除按钮操作 */
|
/** 删除自动回复 */
|
||||||
async function handleDelete(row: any) {
|
async function handleDelete(row: any) {
|
||||||
await ElMessageBox.confirm('是否确认删除此数据?');
|
await ElMessageBox.confirm('是否确认删除此数据?');
|
||||||
const loadingInstance = ElLoading.service({
|
const loadingInstance = ElLoading.service({
|
||||||
text: $t('ui.actionMessage.deleting', ['自动回复']),
|
text: $t('ui.actionMessage.deleting', ['自动回复']),
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
await MpAutoReplyApi.deleteAutoReply(row.id);
|
await deleteAutoReply(row.id);
|
||||||
ElMessage.success('删除成功');
|
ElMessage.success('删除成功');
|
||||||
handleRefresh();
|
handleRefresh();
|
||||||
} finally {
|
} finally {
|
||||||
@@ -106,7 +130,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
query: async ({ page }, formValues) => {
|
query: async ({ page }, formValues) => {
|
||||||
return await MpAutoReplyApi.getAutoReplyPage({
|
return await getAutoReplyPage({
|
||||||
pageNo: page.currentPage,
|
pageNo: page.currentPage,
|
||||||
pageSize: page.pageSize,
|
pageSize: page.pageSize,
|
||||||
type: Number(msgType.value) as MsgType,
|
type: Number(msgType.value) as MsgType,
|
||||||
@@ -124,26 +148,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
refresh: true,
|
refresh: true,
|
||||||
search: true,
|
search: true,
|
||||||
},
|
},
|
||||||
|
// TODO @hw:这里要调整下,linter 报错;
|
||||||
} as VxeTableGridOptions<any>,
|
} as VxeTableGridOptions<any>,
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 刷新表格 */
|
|
||||||
function handleRefresh() {
|
|
||||||
gridApi.query();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算是否显示新增按钮:关注时回复类型只有在没有数据时才显示
|
|
||||||
const showCreateButton = computed(() => {
|
|
||||||
if (Number(msgType.value) !== MsgType.Follow) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const tableData = gridApi.grid?.getTableData();
|
|
||||||
return (tableData?.tableData?.length || 0) <= 0;
|
|
||||||
} catch {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -153,11 +160,10 @@ const showCreateButton = computed(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<FormModal @success="handleRefresh" />
|
<FormModal @success="handleRefresh" />
|
||||||
<Grid table-title="自动回复列表">
|
<Grid>
|
||||||
<template #form-accountId>
|
<template #form-accountId>
|
||||||
<WxAccountSelect @change="handleAccountChange" />
|
<WxAccountSelect @change="handleAccountChange" />
|
||||||
</template>
|
</template>
|
||||||
<!-- 在工具栏上方放置 Tab 切换 -->
|
|
||||||
<template #toolbar-actions>
|
<template #toolbar-actions>
|
||||||
<ElTabs
|
<ElTabs
|
||||||
v-model="msgType"
|
v-model="msgType"
|
||||||
|
|||||||
@@ -37,12 +37,11 @@ const [Form, formApi] = useVbenForm({
|
|||||||
labelWidth: 100,
|
labelWidth: 100,
|
||||||
},
|
},
|
||||||
layout: 'horizontal',
|
layout: 'horizontal',
|
||||||
|
// TODO @hw:antd 和 ele 存在差异
|
||||||
schema: useFormSchema(Number(formData.value?.msgType) as MsgType),
|
schema: useFormSchema(Number(formData.value?.msgType) as MsgType),
|
||||||
showDefaultActions: false,
|
showDefaultActions: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 注意:schema 的更新现在在 onOpenChange 中手动处理,避免时序问题
|
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
async onConfirm() {
|
async onConfirm() {
|
||||||
const { valid } = await formApi.validate();
|
const { valid } = await formApi.validate();
|
||||||
@@ -60,6 +59,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
if (formData.value?.row?.id && !submitForm.id) {
|
if (formData.value?.row?.id && !submitForm.id) {
|
||||||
submitForm.id = formData.value.row.id;
|
submitForm.id = formData.value.row.id;
|
||||||
}
|
}
|
||||||
|
// TODO @hw:antd 和 ele 存在差异
|
||||||
const reply = submitForm.reply as Reply | undefined;
|
const reply = submitForm.reply as Reply | undefined;
|
||||||
if (reply) {
|
if (reply) {
|
||||||
submitForm.responseMessageType = reply.type;
|
submitForm.responseMessageType = reply.type;
|
||||||
@@ -99,6 +99,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
// 加载数据
|
// 加载数据
|
||||||
const data = modalApi.getData<{
|
const data = modalApi.getData<{
|
||||||
accountId?: number;
|
accountId?: number;
|
||||||
|
// TODO @hw:antd 和 ele 存在差异
|
||||||
msgType: MsgType;
|
msgType: MsgType;
|
||||||
row?: any;
|
row?: any;
|
||||||
}>();
|
}>();
|
||||||
@@ -137,6 +138,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
accountId: data.accountId || -1,
|
accountId: data.accountId || -1,
|
||||||
type: data.msgType,
|
type: data.msgType,
|
||||||
requestKeyword: undefined,
|
requestKeyword: undefined,
|
||||||
|
// TODO @hw:antd 和 ele 存在差异
|
||||||
requestMatch: data.msgType === MsgType.Keyword ? 1 : undefined,
|
requestMatch: data.msgType === MsgType.Keyword ? 1 : undefined,
|
||||||
requestMessageType: undefined,
|
requestMessageType: undefined,
|
||||||
reply: {
|
reply: {
|
||||||
|
|||||||
Reference in New Issue
Block a user