mirror of
https://gitee.com/bootx/dax-pay-ui
synced 2026-08-11 23:25:33 +08:00
feat(notify): 管理端微信消息通知配置与发送记录页
单菜单 Tabs 管理模板配置与发送记录,权限合并为 wechat-config; 三方平台微信公众号文案同步支持模板通知。
This commit is contained in:
101
apps/daxpay-admin/src/api/system/notify/wechat.api.ts
Normal file
101
apps/daxpay-admin/src/api/system/notify/wechat.api.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import type { BaseEntity, PageResult, Result } from '#/types/web';
|
||||
|
||||
import { defHttp } from '#/api/request';
|
||||
|
||||
/**
|
||||
* 微信消息通知配置 API
|
||||
* 仅管理场景模板 Id(存 system_platform_config / wechat_notify);
|
||||
* 公众号 AppId/AppSecret 在三方平台管理(加密配置 wechat_mp_auth)
|
||||
*/
|
||||
export const WechatConfigApi = {
|
||||
/** 查询配置 */
|
||||
find(): Promise<Result<WechatConfigResult>> {
|
||||
return defHttp.get({ url: '/notify/wechat/config/find' });
|
||||
},
|
||||
/** 更新配置 */
|
||||
update(data: WechatConfigParam): Promise<Result<void>> {
|
||||
return defHttp.post({ url: '/notify/wechat/config/update', data });
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 微信通知记录 API
|
||||
*/
|
||||
export const WechatMessageApi = {
|
||||
/** 分页查询 */
|
||||
page(params: any): Promise<Result<PageResult<WechatMessageRecord>>> {
|
||||
return defHttp.get({ url: '/notify/wechat/message/page', params });
|
||||
},
|
||||
/** 记录详情 */
|
||||
findById(id: string): Promise<Result<WechatMessageRecord>> {
|
||||
return defHttp.get({ url: '/notify/wechat/message/get', params: { id } });
|
||||
},
|
||||
/** 重发失败消息 */
|
||||
resend(id: string): Promise<Result<void>> {
|
||||
return defHttp.post({ url: '/notify/wechat/message/resend', params: { id } });
|
||||
},
|
||||
/** 测试发送(发给当前登录用户, 验证三方平台凭据+绑定+模板链路) */
|
||||
testSend(): Promise<Result<MessageSendResult>> {
|
||||
return defHttp.post({ url: '/notify/wechat/message/test-send' });
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 微信消息通知配置参数(编辑)
|
||||
*/
|
||||
export interface WechatConfigParam {
|
||||
/** 交易通知模板Id */
|
||||
tradeTemplateId?: string;
|
||||
/** 操作通知模板Id */
|
||||
operateTemplateId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信消息通知配置结果(平台非加密配置, 无 BaseEntity 字段)
|
||||
*/
|
||||
export interface WechatConfigResult {
|
||||
tradeTemplateId?: string;
|
||||
operateTemplateId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信消息记录
|
||||
*/
|
||||
export interface WechatMessageRecord extends BaseEntity {
|
||||
/** 接收平台用户ID */
|
||||
userId?: string;
|
||||
/** 消息类型(template/uniform) */
|
||||
messageType?: string;
|
||||
/** 接收者 OpenId */
|
||||
openId?: string;
|
||||
/** 模板ID */
|
||||
templateId?: string;
|
||||
/** 模板数据(JSON) */
|
||||
templateData?: string;
|
||||
/** 跳转链接 */
|
||||
url?: string;
|
||||
/** 发送状态(success/failed/sending) */
|
||||
status?: string;
|
||||
/** 微信消息ID */
|
||||
msgId?: string;
|
||||
/** 错误码 */
|
||||
errorCode?: string;
|
||||
/** 错误信息 */
|
||||
errorMsg?: string;
|
||||
/** 发送时间 */
|
||||
sendTime?: string;
|
||||
/** 业务场景(trade/operate) */
|
||||
scene?: string;
|
||||
/** 使用的 AppId */
|
||||
wxAppId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息发送结果
|
||||
*/
|
||||
export interface MessageSendResult {
|
||||
success?: boolean;
|
||||
msgId?: string;
|
||||
errorCode?: string;
|
||||
errorMsg?: string;
|
||||
}
|
||||
@@ -254,15 +254,12 @@ export const PermCodes = {
|
||||
MANAGE: 'system:notify:notice:manage',
|
||||
PUBLISH: 'system:notify:notice:publish',
|
||||
},
|
||||
/** 公众号配置 menuCode=system:notify:wechat-config */
|
||||
WechatConfig: {
|
||||
/** 微信消息通知 menuCode=system:notify:wechat-config(配置 + 发送记录 Tabs) */
|
||||
WechatNotify: {
|
||||
MANAGE: 'system:notify:wechat-config:manage',
|
||||
},
|
||||
/** 微信通知记录 menuCode=system:notify:wechat-message */
|
||||
WechatMessage: {
|
||||
VIEW: 'system:notify:wechat-message:view',
|
||||
RESEND: 'system:notify:wechat-message:resend',
|
||||
TEST: 'system:notify:wechat-message:test',
|
||||
VIEW: 'system:notify:wechat-config:view',
|
||||
RESEND: 'system:notify:wechat-config:resend',
|
||||
TEST: 'system:notify:wechat-config:test',
|
||||
},
|
||||
/** 存储文件 menuCode=system:file:platform */
|
||||
FilePlatform: {
|
||||
|
||||
@@ -43,5 +43,34 @@
|
||||
"isTopRequired": "Please confirm whether to pin",
|
||||
"effectiveTimeHelp": "If set, the notice becomes visible after this time. Leave empty to show it immediately after publishing.",
|
||||
"expireTimeHelp": "If set, the notice is hidden after this time. Leave empty to keep it permanently.",
|
||||
"confirmCloseContent": "Content has been modified. Discard changes and close?"
|
||||
"confirmCloseContent": "Content has been modified. Discard changes and close?",
|
||||
"wechatConfigTitle": "WeChat Message Notification",
|
||||
"wechatConfigDesc": "Configure WeChat official account template data for each business scene. AppId/AppSecret are managed under Third-party Platform → WeChat Official Account.",
|
||||
"wechatTabConfig": "Notification Config",
|
||||
"wechatTabRecord": "Send Records",
|
||||
"tradeTemplateId": "Trade Notice Template ID",
|
||||
"operateTemplateId": "Operation Notice Template ID",
|
||||
"testSend": "Test Send",
|
||||
"confirmTestSend": "A test notification will be sent to the current user (requires MP credentials in Third-party Platform and the user bound to this official account). Continue?",
|
||||
"testSendSuccess": "Test message sent. Please check it in WeChat.",
|
||||
"testSendFail": "Send failed: {msg}",
|
||||
"wechatMessageType": "Message Type",
|
||||
"userId": "User ID",
|
||||
"sendStatus": "Send Status",
|
||||
"openId": "OpenId",
|
||||
"templateIdField": "Template ID",
|
||||
"sendTime": "Send Time",
|
||||
"scene": "Scene",
|
||||
"errorMsgField": "Error Message",
|
||||
"msgIdField": "WeChat Msg ID",
|
||||
"resend": "Resend",
|
||||
"confirmResend": "Resend this message?",
|
||||
"statusFilterPlaceholder": "Select send status",
|
||||
"statusSending": "Sending",
|
||||
"statusSuccess": "Success",
|
||||
"statusFailed": "Failed",
|
||||
"typeTemplate": "OA Template",
|
||||
"typeUniform": "Mini Program Uniform",
|
||||
"sceneTrade": "Trade Notice",
|
||||
"sceneOperate": "Operation Notice"
|
||||
}
|
||||
|
||||
@@ -52,10 +52,10 @@
|
||||
},
|
||||
"wechatMp": {
|
||||
"tabTitle": "WeChat Official Account Config",
|
||||
"tabDescription": "WeChat MP H5 OAuth credentials for WeChat login",
|
||||
"tabDescription": "WeChat MP credentials for login and template notifications",
|
||||
"title": "WeChat Official Account Auth Configuration",
|
||||
"description": "Manage WeChat MP H5 web authorization credentials (appId/appSecret) to get user openId.",
|
||||
"usageTip": "This configuration serves WeChat MP H5 web authorization to get user openId.",
|
||||
"description": "Manage WeChat MP credentials (appId/appSecret) for H5 OAuth openId and notification-center template messages.",
|
||||
"usageTip": "This configuration serves: 1) WeChat MP H5 OAuth login; 2) Notification-center template message sending.",
|
||||
"confirmSaveContent": "Are you sure to save the WeChat Official Account configuration?",
|
||||
"section": {
|
||||
"credential": "Credential Configuration"
|
||||
|
||||
@@ -43,5 +43,34 @@
|
||||
"isTopRequired": "请确认是否置顶",
|
||||
"effectiveTimeHelp": "设置后公告在该时间后才对用户可见,不填则发布后立即可见",
|
||||
"expireTimeHelp": "设置后公告在该时间后不再可见,不填则永久有效",
|
||||
"confirmCloseContent": "正文内容已修改,确认放弃修改并关闭吗?"
|
||||
"confirmCloseContent": "正文内容已修改,确认放弃修改并关闭吗?",
|
||||
"wechatConfigTitle": "微信消息通知",
|
||||
"wechatConfigDesc": "配置各业务场景公众号模板数据。AppId/AppSecret 请在「三方平台管理 → 微信公众号」配置。",
|
||||
"wechatTabConfig": "通知配置",
|
||||
"wechatTabRecord": "发送记录",
|
||||
"tradeTemplateId": "交易通知模板Id",
|
||||
"operateTemplateId": "操作通知模板Id",
|
||||
"testSend": "测试发送",
|
||||
"confirmTestSend": "将向当前登录用户发送一条测试通知(需已在三方平台配置公众号凭据, 且当前用户已绑定该公众号), 确认发送吗?",
|
||||
"testSendSuccess": "测试消息已发送, 请在微信公众号查看",
|
||||
"testSendFail": "发送失败: {msg}",
|
||||
"wechatMessageType": "消息类型",
|
||||
"userId": "用户ID",
|
||||
"sendStatus": "发送状态",
|
||||
"openId": "OpenId",
|
||||
"templateIdField": "模板ID",
|
||||
"sendTime": "发送时间",
|
||||
"scene": "业务场景",
|
||||
"errorMsgField": "错误信息",
|
||||
"msgIdField": "微信消息ID",
|
||||
"resend": "重发",
|
||||
"confirmResend": "确认重发该消息吗?",
|
||||
"statusFilterPlaceholder": "请选择发送状态",
|
||||
"statusSending": "发送中",
|
||||
"statusSuccess": "成功",
|
||||
"statusFailed": "失败",
|
||||
"typeTemplate": "公众号模板",
|
||||
"typeUniform": "小程序统一消息",
|
||||
"sceneTrade": "交易通知",
|
||||
"sceneOperate": "操作通知"
|
||||
}
|
||||
|
||||
@@ -52,10 +52,10 @@
|
||||
},
|
||||
"wechatMp": {
|
||||
"tabTitle": "微信公众号配置",
|
||||
"tabDescription": "公众号 H5 网页授权凭据, 服务于微信登录",
|
||||
"tabDescription": "公众号凭据, 服务于微信登录与模版通知",
|
||||
"title": "微信公众号认证配置",
|
||||
"description": "管理微信公众号网页授权凭据(appId/appSecret), 用于公众号 H5 授权获取用户 openId。",
|
||||
"usageTip": "本配置服务于公众号 H5 网页授权, 用于获取用户 openId。",
|
||||
"description": "管理微信公众号凭据(appId/appSecret), 用于公众号 H5 授权获取用户 openId, 以及通知中心模版消息发送。",
|
||||
"usageTip": "本配置同时服务于: 1) 公众号 H5 网页授权登录; 2) 通知中心模版消息发送。",
|
||||
"confirmSaveContent": "确定要保存微信公众号配置吗?",
|
||||
"section": {
|
||||
"credential": "凭据配置"
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
<script lang="ts" setup>
|
||||
import type { WechatConfigParam, WechatConfigResult } from '#/api/system/notify/wechat.api';
|
||||
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import { WechatConfigApi, WechatMessageApi } from '#/api/system/notify/wechat.api';
|
||||
import { PermCodes } from '#/constants/perm-codes';
|
||||
import { useMessage } from '#/hooks/useMessage';
|
||||
import { usePermission } from '#/hooks/usePermission';
|
||||
|
||||
defineOptions({ name: 'WechatNotifyConfig' });
|
||||
|
||||
const { confirm, message } = useMessage();
|
||||
const { hasPermission } = usePermission();
|
||||
|
||||
const loading = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
const formData = reactive<WechatConfigParam>({
|
||||
tradeTemplateId: '',
|
||||
operateTemplateId: '',
|
||||
});
|
||||
|
||||
/**
|
||||
* 加载配置
|
||||
*/
|
||||
function loadConfig() {
|
||||
loading.value = true;
|
||||
WechatConfigApi.find()
|
||||
.then((res) => {
|
||||
const data: WechatConfigResult = res.data || {};
|
||||
Object.assign(formData, {
|
||||
tradeTemplateId: data.tradeTemplateId ?? '',
|
||||
operateTemplateId: data.operateTemplateId ?? '',
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交保存
|
||||
*/
|
||||
async function handleSubmit() {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
await WechatConfigApi.update({ ...formData });
|
||||
message.success($t('common.saveSuccess'));
|
||||
loadConfig();
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试发送(给当前登录用户发一条, 验证三方平台凭据+绑定+模板链路)
|
||||
*/
|
||||
function handleTestSend() {
|
||||
confirm({
|
||||
title: $t('system.notify.testSend'),
|
||||
content: $t('system.notify.confirmTestSend'),
|
||||
onOk: () => {
|
||||
WechatMessageApi.testSend().then((res) => {
|
||||
const result = res.data;
|
||||
if (result?.success) {
|
||||
message.success($t('system.notify.testSendSuccess'));
|
||||
} else {
|
||||
message.error($t('system.notify.testSendFail', { msg: result?.errorMsg || '' }));
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadConfig();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="mb-4 flex items-start justify-between gap-3">
|
||||
<a-alert class="flex-1" :message="$t('system.notify.wechatConfigDesc')" type="info" banner />
|
||||
<a-button
|
||||
v-if="hasPermission(PermCodes.System.WechatNotify.TEST)"
|
||||
:loading="submitLoading"
|
||||
@click="handleTestSend"
|
||||
>
|
||||
{{ $t('system.notify.testSend') }}
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
<a-spin :spinning="loading">
|
||||
<a-form :model="formData" layout="vertical" class="max-w-2xl">
|
||||
<a-form-item :label="$t('system.notify.tradeTemplateId')" name="tradeTemplateId">
|
||||
<a-input
|
||||
v-model:value="formData.tradeTemplateId"
|
||||
:placeholder="$t('common.pleaseInput')"
|
||||
:disabled="submitLoading"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('system.notify.operateTemplateId')" name="operateTemplateId">
|
||||
<a-input
|
||||
v-model:value="formData.operateTemplateId"
|
||||
:placeholder="$t('common.pleaseInput')"
|
||||
:disabled="submitLoading"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
|
||||
<div class="mt-4">
|
||||
<a-space>
|
||||
<a-button :disabled="submitLoading" @click="loadConfig">{{ $t('common.reset') }}</a-button>
|
||||
<a-button
|
||||
v-if="hasPermission(PermCodes.System.WechatNotify.MANAGE)"
|
||||
type="primary"
|
||||
:loading="submitLoading"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
{{ $t('common.save') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,211 @@
|
||||
<script lang="ts" setup>
|
||||
import type { VxeTableInstance, VxeToolbarInstance } from 'vxe-table';
|
||||
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import { WechatMessageApi } from '#/api/system/notify/wechat.api';
|
||||
import { BQuery, type QueryField } from '#/components/query';
|
||||
import { PermCodes } from '#/constants/perm-codes';
|
||||
import { useMessage } from '#/hooks/useMessage';
|
||||
import { usePermission } from '#/hooks/usePermission';
|
||||
|
||||
defineOptions({ name: 'WechatNotifyRecord' });
|
||||
|
||||
const { confirm, message } = useMessage();
|
||||
const { hasPermission } = usePermission();
|
||||
|
||||
const loading = ref(false);
|
||||
const xTable = ref<VxeTableInstance>();
|
||||
const xToolbar = ref<VxeToolbarInstance>();
|
||||
|
||||
// 查询条件
|
||||
const queryForm = ref<Record<string, any>>({});
|
||||
|
||||
// 查询字段配置
|
||||
const queryFields = computed<QueryField[]>(() => [
|
||||
{
|
||||
type: 'string',
|
||||
field: 'openId',
|
||||
name: $t('system.notify.openId'),
|
||||
placeholder: $t('system.notify.openId'),
|
||||
},
|
||||
{
|
||||
type: 'list',
|
||||
field: 'status',
|
||||
name: $t('system.notify.sendStatus'),
|
||||
placeholder: $t('system.notify.statusFilterPlaceholder'),
|
||||
selectList: [
|
||||
{ label: $t('system.notify.statusSuccess'), value: 'success' },
|
||||
{ label: $t('system.notify.statusFailed'), value: 'failed' },
|
||||
{ label: $t('system.notify.statusSending'), value: 'sending' },
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
// 分页配置
|
||||
const pageConfig = ref({
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref<any[]>([]);
|
||||
|
||||
onMounted(() => {
|
||||
xTable.value?.connectToolbar(xToolbar.value as VxeToolbarInstance);
|
||||
queryPage();
|
||||
});
|
||||
|
||||
/**
|
||||
* 查询分页数据
|
||||
*/
|
||||
function queryPage() {
|
||||
loading.value = true;
|
||||
WechatMessageApi.page({
|
||||
current: pageConfig.value.currentPage,
|
||||
size: pageConfig.value.pageSize,
|
||||
...queryForm.value,
|
||||
})
|
||||
.then((res: any) => {
|
||||
tableData.value = res.data.records || [];
|
||||
pageConfig.value.total = Number(res.data.total) || 0;
|
||||
loading.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置查询
|
||||
*/
|
||||
function resetQuery() {
|
||||
queryForm.value = {};
|
||||
pageConfig.value.currentPage = 1;
|
||||
queryPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重发失败消息
|
||||
*/
|
||||
function handleResend(row: any) {
|
||||
confirm({
|
||||
title: $t('system.notify.resend'),
|
||||
content: $t('system.notify.confirmResend'),
|
||||
onOk: () => {
|
||||
WechatMessageApi.resend(row.id).then(() => {
|
||||
message.success($t('common.operateSuccess'));
|
||||
queryPage();
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息类型展示
|
||||
*/
|
||||
function formatMessageType(type?: string) {
|
||||
if (type === 'template') {
|
||||
return $t('system.notify.typeTemplate');
|
||||
}
|
||||
if (type === 'uniform') {
|
||||
return $t('system.notify.typeUniform');
|
||||
}
|
||||
return type || '-';
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务场景展示
|
||||
*/
|
||||
function formatScene(scene?: string) {
|
||||
if (scene === 'trade') {
|
||||
return $t('system.notify.sceneTrade');
|
||||
}
|
||||
if (scene === 'operate') {
|
||||
return $t('system.notify.sceneOperate');
|
||||
}
|
||||
return scene || '-';
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页变化
|
||||
*/
|
||||
function handlePageChange({ currentPage, pageSize }: any) {
|
||||
pageConfig.value.currentPage = currentPage;
|
||||
pageConfig.value.pageSize = pageSize;
|
||||
queryPage();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="list-page-compact">
|
||||
<div class="mb-3">
|
||||
<BQuery :fields="queryFields" :query-params="queryForm" @query="queryPage" @reset="resetQuery" />
|
||||
</div>
|
||||
|
||||
<vxe-toolbar ref="xToolbar" custom refresh :refresh-options="{ queryMethod: queryPage }" />
|
||||
<vxe-table ref="xTable" :row-config="{ keyField: 'id' }" :data="tableData" :loading="loading">
|
||||
<vxe-column type="seq" :title="$t('common.seq')" width="60" align="center" />
|
||||
<vxe-column field="messageType" :title="$t('system.notify.wechatMessageType')" :min-width="120" align="center">
|
||||
<template #default="{ row }">
|
||||
<a-tag>{{ formatMessageType(row.messageType) }}</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="scene" :title="$t('system.notify.scene')" :min-width="110" align="center">
|
||||
<template #default="{ row }">
|
||||
{{ formatScene(row.scene) }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="userId" :title="$t('system.notify.userId')" :min-width="100" align="center" />
|
||||
<vxe-column field="openId" :title="$t('system.notify.openId')" :min-width="200" />
|
||||
<vxe-column field="status" :title="$t('system.notify.sendStatus')" :min-width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<a-tag v-if="row.status === 'success'" color="green">{{ $t('system.notify.statusSuccess') }}</a-tag>
|
||||
<a-tag v-else-if="row.status === 'failed'" color="red">{{ $t('system.notify.statusFailed') }}</a-tag>
|
||||
<a-tag v-else>{{ $t('system.notify.statusSending') }}</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column
|
||||
field="sendTime"
|
||||
:title="$t('system.notify.sendTime')"
|
||||
:min-width="160"
|
||||
formatter="formatDateTime"
|
||||
/>
|
||||
<vxe-column field="errorMsg" :title="$t('system.notify.errorMsgField')" :min-width="220">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.errorMsg" class="text-red-500">{{ row.errorMsg }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column fixed="right" width="100" :show-overflow="false" :title="$t('common.operation')">
|
||||
<template #default="{ row }">
|
||||
<a-space :size="2">
|
||||
<template #separator>
|
||||
<a-divider type="vertical" />
|
||||
</template>
|
||||
<a-button
|
||||
v-if="row.status === 'failed' && hasPermission(PermCodes.System.WechatNotify.RESEND)"
|
||||
type="link"
|
||||
size="small"
|
||||
@click="handleResend(row)"
|
||||
>
|
||||
{{ $t('system.notify.resend') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<vxe-pager
|
||||
size="medium"
|
||||
:loading="loading"
|
||||
:current-page="pageConfig.currentPage"
|
||||
:page-size="pageConfig.pageSize"
|
||||
:total="Number(pageConfig.total)"
|
||||
@page-change="handlePageChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
33
apps/daxpay-admin/src/views/system/notify/wechat/index.vue
Normal file
33
apps/daxpay-admin/src/views/system/notify/wechat/index.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import WechatNotifyConfig from './WechatNotifyConfig.vue';
|
||||
import WechatNotifyRecord from './WechatNotifyRecord.vue';
|
||||
|
||||
defineOptions({ name: 'WechatNotify' });
|
||||
|
||||
const activeKey = ref<string>('config');
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="m-3">
|
||||
<a-card variant="borderless" class="rounded-xl shadow-sm">
|
||||
<template #title>
|
||||
<span class="text-lg font-bold text-foreground">
|
||||
{{ $t('system.notify.wechatConfigTitle') }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<a-tabs v-model:active-key="activeKey" type="card">
|
||||
<a-tab-pane key="config" :tab="$t('system.notify.wechatTabConfig')">
|
||||
<WechatNotifyConfig />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="record" :tab="$t('system.notify.wechatTabRecord')">
|
||||
<WechatNotifyRecord v-if="activeKey === 'record'" />
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user