feat: 优化站内信通知面板
This commit is contained in:
parent
15e588f80e
commit
60ac59c628
@ -44,6 +44,10 @@ pnpm run build:antdv-next
|
||||
|
||||
真实环境变量不提交,示例配置以 `.env.example` 为准。
|
||||
|
||||
## 业务页面
|
||||
|
||||
- 系统管理 / 站内信是日志级通知列表,只展示 API 错误、QQBot 下线、NapCat 离线等后端自动捕获事件;页面提供筛选、处理/重新打开、置顶和删除,不提供人工新增或编辑。
|
||||
|
||||
## 部署说明
|
||||
|
||||
Jenkins 使用 `Jenkinsfile` 执行:
|
||||
|
||||
@ -70,7 +70,6 @@ const SUPPORTED_ADMIN_MENU_NAMES = new Set([
|
||||
'SystemMenuDelete',
|
||||
'SystemMenuEdit',
|
||||
'SystemNotice',
|
||||
'SystemNoticeCreate',
|
||||
'SystemNoticeDelete',
|
||||
'SystemNoticeEdit',
|
||||
'SystemRole',
|
||||
|
||||
@ -8,37 +8,39 @@ export namespace SystemNoticeApi {
|
||||
content: string;
|
||||
createTime?: string;
|
||||
createdBy?: string;
|
||||
dedupeKey?: string;
|
||||
eventType?: string;
|
||||
firstSeenAt?: string;
|
||||
id: string;
|
||||
isDeleted: boolean;
|
||||
isTop: boolean;
|
||||
lastSeenAt?: string;
|
||||
level: number;
|
||||
metadata?: Recordable<any> | string;
|
||||
notifyUsers?: string;
|
||||
notifyRoleCode?: string;
|
||||
occurrenceCount?: number;
|
||||
severity?: 'error' | 'fatal' | 'info' | 'warn';
|
||||
source?: string;
|
||||
status: 0 | 1;
|
||||
summary?: string;
|
||||
title: string;
|
||||
updateTime?: string;
|
||||
}
|
||||
|
||||
export interface NoticeInput {
|
||||
content: string;
|
||||
id?: string;
|
||||
isTop?: boolean;
|
||||
level?: number;
|
||||
notifyUsers?: string;
|
||||
status?: 0 | 1;
|
||||
summary?: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface NoticeQuery {
|
||||
[key: string]: any;
|
||||
eventType?: string;
|
||||
isTop?: boolean | number | string;
|
||||
keyword?: string;
|
||||
level?: number | string;
|
||||
notifyUsers?: string;
|
||||
notifyRoleCode?: string;
|
||||
page?: number;
|
||||
pageNo?: number;
|
||||
pageSize?: number;
|
||||
severity?: string;
|
||||
source?: string;
|
||||
status?: 0 | 1 | number | string;
|
||||
}
|
||||
|
||||
@ -60,17 +62,6 @@ async function getNoticeDetail(id: string) {
|
||||
);
|
||||
}
|
||||
|
||||
async function createNotice(data: SystemNoticeApi.NoticeInput) {
|
||||
return requestClient.post<string>('/system/notice/save', data);
|
||||
}
|
||||
|
||||
async function updateNotice(id: string, data: SystemNoticeApi.NoticeInput) {
|
||||
return requestClient.post('/system/notice/update', {
|
||||
...data,
|
||||
id,
|
||||
});
|
||||
}
|
||||
|
||||
async function deleteNotice(id: string) {
|
||||
return requestClient.delete(`/system/notice/${id}`);
|
||||
}
|
||||
@ -97,11 +88,9 @@ async function toggleNoticeTop(id: string, isTop: boolean) {
|
||||
}
|
||||
|
||||
export {
|
||||
createNotice,
|
||||
deleteNotice,
|
||||
getNoticeDetail,
|
||||
getNoticeList,
|
||||
toggleNoticeStatus,
|
||||
toggleNoticeTop,
|
||||
updateNotice,
|
||||
};
|
||||
|
||||
@ -112,28 +112,45 @@
|
||||
"unconfigured": "Loki Not Configured"
|
||||
},
|
||||
"notice": {
|
||||
"cancelTop": "Unpin",
|
||||
"cancelTopSuccess": "Unpinned",
|
||||
"content": "Content",
|
||||
"createTime": "Create Time",
|
||||
"deleteConfirm": "Confirm deleting \"{0}\"?",
|
||||
"disableSuccess": "Notice disabled",
|
||||
"enableSuccess": "Notice enabled",
|
||||
"eventTitle": "Event Title",
|
||||
"eventType": "Event Type",
|
||||
"firstSeenAt": "First Seen",
|
||||
"handleConfirm": "Mark \"{0}\" as handled?",
|
||||
"handleSuccess": "Marked as handled",
|
||||
"isTop": "Top",
|
||||
"keyword": "Keyword",
|
||||
"lastSeenAt": "Last Seen",
|
||||
"level": "Level",
|
||||
"levelText": "Level {level}",
|
||||
"markHandled": "Handle",
|
||||
"markTop": "Pin",
|
||||
"name": "Notice",
|
||||
"notifyUsers": "Notify Users",
|
||||
"occurrenceCount": "Count",
|
||||
"reopen": "Reopen",
|
||||
"reopenConfirm": "Reopen \"{0}\"?",
|
||||
"reopenSuccess": "Reopened",
|
||||
"severity": "Severity",
|
||||
"severityError": "Error",
|
||||
"severityFatal": "Fatal",
|
||||
"severityInfo": "Info",
|
||||
"severityWarn": "Warning",
|
||||
"source": "Source",
|
||||
"sourceApi": "API",
|
||||
"sourceQqbot": "QQBot",
|
||||
"status": "Status",
|
||||
"statusHandled": "Handled",
|
||||
"statusUnhandled": "Unhandled",
|
||||
"summary": "Summary",
|
||||
"title": "Notices",
|
||||
"top": "Pinned",
|
||||
"topSuccess": "Pinned",
|
||||
"topNo": "No",
|
||||
"topYes": "Yes",
|
||||
"topSuccess": "Pinned",
|
||||
"cancelTopSuccess": "Unpinned",
|
||||
"toggle": "Toggle",
|
||||
"toggleStatusConfirm": "Confirm toggling \"{0}\" status?",
|
||||
"topToggle": "Pin Toggle",
|
||||
"toggleTopConfirm": "Confirm toggling \"{0}\" pin state?"
|
||||
},
|
||||
"role": {
|
||||
|
||||
@ -114,28 +114,45 @@
|
||||
"unconfigured": "Loki 未配置"
|
||||
},
|
||||
"notice": {
|
||||
"cancelTop": "取消置顶",
|
||||
"cancelTopSuccess": "取消置顶成功",
|
||||
"content": "内容",
|
||||
"createTime": "创建时间",
|
||||
"deleteConfirm": "确认删除「{0}」吗?",
|
||||
"disableSuccess": "已停用站内信",
|
||||
"enableSuccess": "已启用站内信",
|
||||
"eventTitle": "事件标题",
|
||||
"eventType": "事件类型",
|
||||
"firstSeenAt": "首次发生",
|
||||
"handleConfirm": "确认将「{0}」标记为已处理吗?",
|
||||
"handleSuccess": "已标记为已处理",
|
||||
"isTop": "置顶",
|
||||
"keyword": "关键字",
|
||||
"lastSeenAt": "最后发生",
|
||||
"level": "等级",
|
||||
"levelText": "等级 {level}",
|
||||
"markHandled": "标记处理",
|
||||
"markTop": "置顶",
|
||||
"name": "站内信",
|
||||
"notifyUsers": "通知用户",
|
||||
"occurrenceCount": "次数",
|
||||
"reopen": "重新打开",
|
||||
"reopenConfirm": "确认重新打开「{0}」吗?",
|
||||
"reopenSuccess": "已重新打开",
|
||||
"severity": "级别",
|
||||
"severityError": "错误",
|
||||
"severityFatal": "致命",
|
||||
"severityInfo": "信息",
|
||||
"severityWarn": "警告",
|
||||
"source": "来源",
|
||||
"sourceApi": "接口",
|
||||
"sourceQqbot": "QQBot",
|
||||
"status": "状态",
|
||||
"statusHandled": "已处理",
|
||||
"statusUnhandled": "未处理",
|
||||
"summary": "摘要",
|
||||
"title": "站内信管理",
|
||||
"top": "置顶",
|
||||
"topSuccess": "置顶成功",
|
||||
"topNo": "否",
|
||||
"topYes": "是",
|
||||
"topSuccess": "置顶成功",
|
||||
"cancelTopSuccess": "取消置顶成功",
|
||||
"toggle": "启停",
|
||||
"toggleStatusConfirm": "确认切换「{0}」启停状态吗?",
|
||||
"topToggle": "置顶切换",
|
||||
"toggleTopConfirm": "确认切换「{0}」置顶状态吗?"
|
||||
},
|
||||
"role": {
|
||||
|
||||
@ -1,19 +1,32 @@
|
||||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
|
||||
import { z } from '#/adapter/form';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
export const NOTICE_LEVEL_OPTIONS = [
|
||||
{ label: '普通', value: 1 },
|
||||
{ label: '重要', value: 2 },
|
||||
{ label: '紧急', value: 3 },
|
||||
export const NOTICE_SEVERITY_OPTIONS = [
|
||||
{ color: 'blue', label: $t('system.notice.severityInfo'), value: 'info' },
|
||||
{ color: 'orange', label: $t('system.notice.severityWarn'), value: 'warn' },
|
||||
{ color: 'red', label: $t('system.notice.severityError'), value: 'error' },
|
||||
{ color: 'purple', label: $t('system.notice.severityFatal'), value: 'fatal' },
|
||||
];
|
||||
|
||||
export const NOTICE_SOURCE_OPTIONS = [
|
||||
{ color: 'geekblue', label: $t('system.notice.sourceApi'), value: 'api' },
|
||||
{ color: 'cyan', label: $t('system.notice.sourceQqbot'), value: 'qqbot' },
|
||||
];
|
||||
|
||||
export const NOTICE_STATUS_OPTIONS = [
|
||||
{ color: 'success', label: $t('common.enabled'), value: 1 },
|
||||
{ color: 'default', label: $t('common.disabled'), value: 0 },
|
||||
{ color: 'error', label: $t('system.notice.statusUnhandled'), value: 1 },
|
||||
{ color: 'default', label: $t('system.notice.statusHandled'), value: 0 },
|
||||
];
|
||||
|
||||
export function getNoticeSeverityOptions() {
|
||||
return NOTICE_SEVERITY_OPTIONS;
|
||||
}
|
||||
|
||||
export function getNoticeSourceOptions() {
|
||||
return NOTICE_SOURCE_OPTIONS;
|
||||
}
|
||||
|
||||
export function getNoticeStatusOptions() {
|
||||
return NOTICE_STATUS_OPTIONS;
|
||||
}
|
||||
@ -32,10 +45,10 @@ export function useSearchSchema(): VbenFormSchema[] {
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
options: NOTICE_LEVEL_OPTIONS,
|
||||
options: NOTICE_SEVERITY_OPTIONS,
|
||||
},
|
||||
fieldName: 'level',
|
||||
label: $t('system.notice.level'),
|
||||
fieldName: 'severity',
|
||||
label: $t('system.notice.severity'),
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
@ -50,113 +63,18 @@ export function useSearchSchema(): VbenFormSchema[] {
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
options: [
|
||||
{ label: $t('common.no'), value: 0 },
|
||||
{ label: $t('common.yes'), value: 1 },
|
||||
],
|
||||
options: NOTICE_SOURCE_OPTIONS,
|
||||
},
|
||||
fieldName: 'isTop',
|
||||
label: $t('system.notice.top'),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export function useFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
placeholder: '如 系统公告',
|
||||
},
|
||||
fieldName: 'title',
|
||||
label: $t('system.notice.title'),
|
||||
rules: z
|
||||
.string()
|
||||
.min(1, $t('ui.formRules.required', [$t('system.notice.title')]))
|
||||
.max(
|
||||
120,
|
||||
$t('ui.formRules.maxLength', [$t('system.notice.title'), 120]),
|
||||
),
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
placeholder: '如 站内信内容概要',
|
||||
},
|
||||
fieldName: 'summary',
|
||||
label: $t('system.notice.summary'),
|
||||
rules: z
|
||||
.string()
|
||||
.max(
|
||||
200,
|
||||
$t('ui.formRules.maxLength', [$t('system.notice.summary'), 200]),
|
||||
),
|
||||
},
|
||||
{
|
||||
component: 'TextArea',
|
||||
componentProps: {
|
||||
autoSize: {
|
||||
maxRows: 10,
|
||||
minRows: 4,
|
||||
},
|
||||
allowClear: true,
|
||||
placeholder: '请输入完整内容',
|
||||
},
|
||||
fieldName: 'content',
|
||||
label: $t('system.notice.content'),
|
||||
rules: z
|
||||
.string()
|
||||
.min(1, $t('ui.formRules.required', [$t('system.notice.content')])),
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
options: NOTICE_LEVEL_OPTIONS,
|
||||
},
|
||||
fieldName: 'level',
|
||||
label: $t('system.notice.level'),
|
||||
defaultValue: 1,
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
placeholder: '逗号分隔,如:10001,10002,留空表示全部用户可见',
|
||||
},
|
||||
fieldName: 'notifyUsers',
|
||||
label: $t('system.notice.notifyUsers'),
|
||||
},
|
||||
{
|
||||
component: 'RadioGroup',
|
||||
componentProps: {
|
||||
buttonStyle: 'solid',
|
||||
options: [
|
||||
{
|
||||
label: $t('system.notice.topNo'),
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
label: $t('system.notice.topYes'),
|
||||
value: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultValue: false,
|
||||
fieldName: 'isTop',
|
||||
label: $t('system.notice.top'),
|
||||
},
|
||||
{
|
||||
component: 'RadioGroup',
|
||||
componentProps: {
|
||||
buttonStyle: 'solid',
|
||||
options: NOTICE_STATUS_OPTIONS,
|
||||
},
|
||||
defaultValue: 1,
|
||||
fieldName: 'status',
|
||||
label: $t('system.notice.status'),
|
||||
fieldName: 'source',
|
||||
label: $t('system.notice.source'),
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
},
|
||||
fieldName: 'eventType',
|
||||
label: $t('system.notice.eventType'),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@ -4,15 +4,11 @@ import type { TableColumnType } from 'antdv-next';
|
||||
import type { SystemNoticeApi } from '#/api/system/notice';
|
||||
import type {
|
||||
KtTableApi,
|
||||
KtTableButton,
|
||||
KtTableContext,
|
||||
KtTableRowAction,
|
||||
} from '#/components/ktTable';
|
||||
|
||||
import { h } from 'vue';
|
||||
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
import { Plus } from '@vben/icons';
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
||||
import { message, Tag } from 'antdv-next';
|
||||
|
||||
@ -25,14 +21,15 @@ import {
|
||||
import { KtTable, useKtTable } from '#/components/ktTable';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
import { getNoticeStatusOptions, useSearchSchema } from './data';
|
||||
import Form from './modules/form.vue';
|
||||
|
||||
const [FormModal, formModalApi] = useVbenModal({
|
||||
connectedComponent: Form,
|
||||
destroyOnClose: true,
|
||||
});
|
||||
import {
|
||||
getNoticeSeverityOptions,
|
||||
getNoticeSourceOptions,
|
||||
getNoticeStatusOptions,
|
||||
useSearchSchema,
|
||||
} from './data';
|
||||
|
||||
const noticeSeverityOptions = getNoticeSeverityOptions();
|
||||
const noticeSourceOptions = getNoticeSourceOptions();
|
||||
const noticeStatusOptions = getNoticeStatusOptions();
|
||||
|
||||
const columns: Array<TableColumnType<SystemNoticeApi.NoticeItem>> = [
|
||||
@ -41,37 +38,49 @@ const columns: Array<TableColumnType<SystemNoticeApi.NoticeItem>> = [
|
||||
fixed: 'left',
|
||||
key: 'isTop',
|
||||
title: $t('system.notice.top'),
|
||||
width: 90,
|
||||
width: 82,
|
||||
},
|
||||
{
|
||||
dataIndex: 'title',
|
||||
dataIndex: 'severity',
|
||||
fixed: 'left',
|
||||
key: 'title',
|
||||
title: $t('system.notice.title'),
|
||||
width: 260,
|
||||
},
|
||||
{
|
||||
dataIndex: 'level',
|
||||
key: 'level',
|
||||
title: $t('system.notice.level'),
|
||||
width: 100,
|
||||
key: 'severity',
|
||||
title: $t('system.notice.severity'),
|
||||
width: 96,
|
||||
},
|
||||
{
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
title: $t('system.notice.status'),
|
||||
width: 100,
|
||||
width: 96,
|
||||
},
|
||||
{
|
||||
dataIndex: 'notifyUsers',
|
||||
key: 'notifyUsers',
|
||||
title: $t('system.notice.notifyUsers'),
|
||||
dataIndex: 'title',
|
||||
key: 'title',
|
||||
title: $t('system.notice.eventTitle'),
|
||||
width: 260,
|
||||
},
|
||||
{
|
||||
dataIndex: 'source',
|
||||
key: 'source',
|
||||
title: $t('system.notice.source'),
|
||||
width: 110,
|
||||
},
|
||||
{
|
||||
dataIndex: 'eventType',
|
||||
key: 'eventType',
|
||||
title: $t('system.notice.eventType'),
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
dataIndex: 'createTime',
|
||||
key: 'createTime',
|
||||
title: $t('system.notice.createTime'),
|
||||
dataIndex: 'occurrenceCount',
|
||||
key: 'occurrenceCount',
|
||||
title: $t('system.notice.occurrenceCount'),
|
||||
width: 110,
|
||||
},
|
||||
{
|
||||
dataIndex: 'lastSeenAt',
|
||||
key: 'lastSeenAt',
|
||||
title: $t('system.notice.lastSeenAt'),
|
||||
width: 190,
|
||||
},
|
||||
{
|
||||
@ -79,7 +88,7 @@ const columns: Array<TableColumnType<SystemNoticeApi.NoticeItem>> = [
|
||||
dataIndex: 'summary',
|
||||
key: 'summary',
|
||||
title: $t('system.notice.summary'),
|
||||
width: 280,
|
||||
width: 320,
|
||||
},
|
||||
];
|
||||
|
||||
@ -87,37 +96,38 @@ const api: KtTableApi<SystemNoticeApi.NoticeItem> = {
|
||||
list: async (params) => await getNoticeList(params),
|
||||
};
|
||||
|
||||
const buttons: Array<KtTableButton<SystemNoticeApi.NoticeItem>> = [
|
||||
{
|
||||
icon: () => h(Plus, { class: 'kt-table__button-icon' }),
|
||||
key: 'create',
|
||||
label: $t('ui.actionTitle.create', [$t('system.notice.name')]),
|
||||
onClick: onCreate,
|
||||
permissionCodes: ['System:Notice:Create'],
|
||||
type: 'primary',
|
||||
},
|
||||
];
|
||||
|
||||
const rowActions: Array<KtTableRowAction<SystemNoticeApi.NoticeItem>> = [
|
||||
{
|
||||
key: 'edit',
|
||||
label: $t('common.edit'),
|
||||
onClick: onEdit,
|
||||
permissionCodes: ['System:Notice:Edit'],
|
||||
},
|
||||
{
|
||||
confirm: (row) => $t('system.notice.toggleStatusConfirm', [row.title]),
|
||||
key: 'toggle',
|
||||
label: $t('system.notice.toggle'),
|
||||
confirm: (row) => $t('system.notice.handleConfirm', [row.title]),
|
||||
key: 'handle',
|
||||
label: $t('system.notice.markHandled'),
|
||||
onClick: onToggleStatus,
|
||||
permissionCodes: ['System:Notice:Edit'],
|
||||
rowVisible: (row) => row.status === 1,
|
||||
},
|
||||
{
|
||||
confirm: (row) => $t('system.notice.reopenConfirm', [row.title]),
|
||||
key: 'reopen',
|
||||
label: $t('system.notice.reopen'),
|
||||
onClick: onToggleStatus,
|
||||
permissionCodes: ['System:Notice:Edit'],
|
||||
rowVisible: (row) => row.status !== 1,
|
||||
},
|
||||
{
|
||||
confirm: (row) => $t('system.notice.toggleTopConfirm', [row.title]),
|
||||
key: 'top',
|
||||
label: $t('system.notice.topToggle'),
|
||||
key: 'markTop',
|
||||
label: $t('system.notice.markTop'),
|
||||
onClick: onToggleTop,
|
||||
permissionCodes: ['System:Notice:Edit'],
|
||||
rowVisible: (row) => !row.isTop,
|
||||
},
|
||||
{
|
||||
confirm: (row) => $t('system.notice.toggleTopConfirm', [row.title]),
|
||||
key: 'cancelTop',
|
||||
label: $t('system.notice.cancelTop'),
|
||||
onClick: onToggleTop,
|
||||
permissionCodes: ['System:Notice:Edit'],
|
||||
rowVisible: (row) => row.isTop,
|
||||
},
|
||||
{
|
||||
confirm: (row) => $t('system.notice.deleteConfirm', [row.title]),
|
||||
@ -129,19 +139,22 @@ const rowActions: Array<KtTableRowAction<SystemNoticeApi.NoticeItem>> = [
|
||||
},
|
||||
];
|
||||
|
||||
function getNoticeSeverityOption(
|
||||
severity: SystemNoticeApi.NoticeItem['severity'],
|
||||
) {
|
||||
return noticeSeverityOptions.find((item) => item.value === severity);
|
||||
}
|
||||
|
||||
function getNoticeSourceOption(source?: string) {
|
||||
return noticeSourceOptions.find((item) => item.value === source);
|
||||
}
|
||||
|
||||
function getNoticeStatusOption(status: SystemNoticeApi.NoticeItem['status']) {
|
||||
return noticeStatusOptions.find((item) => item.value === status);
|
||||
}
|
||||
|
||||
function getNoticeLevelColor(level: SystemNoticeApi.NoticeItem['level']) {
|
||||
if (level === 3) return 'red';
|
||||
if (level === 2) return 'orange';
|
||||
return 'blue';
|
||||
}
|
||||
|
||||
const [registerTable, tableApi] = useKtTable<SystemNoticeApi.NoticeItem>({
|
||||
api,
|
||||
buttons,
|
||||
columns,
|
||||
formOptions: {
|
||||
schema: useSearchSchema(),
|
||||
@ -152,14 +165,6 @@ const [registerTable, tableApi] = useKtTable<SystemNoticeApi.NoticeItem>({
|
||||
tableTitle: $t('system.notice.title'),
|
||||
});
|
||||
|
||||
function onCreate() {
|
||||
formModalApi.setData(undefined).open();
|
||||
}
|
||||
|
||||
function onEdit(row: SystemNoticeApi.NoticeItem) {
|
||||
formModalApi.setData(row).open();
|
||||
}
|
||||
|
||||
async function onToggleStatus(
|
||||
row: SystemNoticeApi.NoticeItem,
|
||||
context: KtTableContext<SystemNoticeApi.NoticeItem>,
|
||||
@ -167,9 +172,9 @@ async function onToggleStatus(
|
||||
const nextStatus = row.status === 1 ? 0 : 1;
|
||||
await toggleNoticeStatus(row.id, nextStatus);
|
||||
message.success(
|
||||
nextStatus === 1
|
||||
? $t('system.notice.enableSuccess')
|
||||
: $t('system.notice.disableSuccess'),
|
||||
nextStatus === 0
|
||||
? $t('system.notice.handleSuccess')
|
||||
: $t('system.notice.reopenSuccess'),
|
||||
);
|
||||
await context.reload();
|
||||
}
|
||||
@ -208,15 +213,10 @@ async function onDelete(
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
function onRefresh() {
|
||||
tableApi.reload();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page auto-content-height>
|
||||
<FormModal @success="onRefresh" />
|
||||
<KtTable @register="registerTable">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'isTop'">
|
||||
@ -228,9 +228,26 @@ function onRefresh() {
|
||||
}}
|
||||
</Tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'level'">
|
||||
<Tag :color="getNoticeLevelColor(record.level)">
|
||||
{{ $t('system.notice.levelText', { level: record.level }) }}
|
||||
<template v-else-if="column.key === 'severity'">
|
||||
<Tag
|
||||
:color="
|
||||
getNoticeSeverityOption(record.severity)?.color || 'default'
|
||||
"
|
||||
>
|
||||
{{
|
||||
getNoticeSeverityOption(record.severity)?.label ||
|
||||
record.severity ||
|
||||
'-'
|
||||
}}
|
||||
</Tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'source'">
|
||||
<Tag :color="getNoticeSourceOption(record.source)?.color || 'blue'">
|
||||
{{
|
||||
getNoticeSourceOption(record.source)?.label ||
|
||||
record.source ||
|
||||
'-'
|
||||
}}
|
||||
</Tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'status'">
|
||||
@ -240,6 +257,12 @@ function onRefresh() {
|
||||
{{ getNoticeStatusOption(record.status)?.label || record.status }}
|
||||
</Tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'occurrenceCount'">
|
||||
{{ record.occurrenceCount || 1 }}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'summary'">
|
||||
{{ record.summary || record.content || '-' }}
|
||||
</template>
|
||||
</template>
|
||||
</KtTable>
|
||||
</Page>
|
||||
|
||||
@ -1,87 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { SystemNoticeApi } from '#/api/system/notice';
|
||||
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { Button } from 'antdv-next';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { createNotice, updateNotice } from '#/api/system/notice';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
import { useFormSchema } from '../data';
|
||||
|
||||
const emit = defineEmits<{
|
||||
success: [];
|
||||
}>();
|
||||
|
||||
const formData = ref<Partial<SystemNoticeApi.NoticeItem>>();
|
||||
const getTitle = computed(() => {
|
||||
return formData.value?.id
|
||||
? $t('ui.actionTitle.edit', [$t('system.notice.name')])
|
||||
: $t('ui.actionTitle.create', [$t('system.notice.name')]);
|
||||
});
|
||||
|
||||
const [Form, formApi] = useVbenForm({
|
||||
layout: 'vertical',
|
||||
schema: useFormSchema(),
|
||||
showDefaultActions: false,
|
||||
});
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
async onConfirm() {
|
||||
const { valid } = await formApi.validate();
|
||||
if (!valid) return;
|
||||
|
||||
modalApi.lock();
|
||||
const data = (await formApi.getValues()) as SystemNoticeApi.NoticeInput;
|
||||
|
||||
try {
|
||||
const currentId = formData.value?.id;
|
||||
await (currentId ? updateNotice(currentId, data) : createNotice(data));
|
||||
modalApi.close();
|
||||
emit('success');
|
||||
} finally {
|
||||
modalApi.lock(false);
|
||||
}
|
||||
},
|
||||
onOpenChange(isOpen) {
|
||||
if (!isOpen) return;
|
||||
const data = modalApi.getData<Partial<SystemNoticeApi.NoticeItem>>();
|
||||
formData.value = data || undefined;
|
||||
resetForm();
|
||||
},
|
||||
});
|
||||
|
||||
function getFormValues() {
|
||||
return {
|
||||
content: formData.value?.content || '',
|
||||
isTop: formData.value?.isTop ?? false,
|
||||
level: formData.value?.level ?? 1,
|
||||
notifyUsers: formData.value?.notifyUsers || '',
|
||||
status: formData.value?.status ?? 1,
|
||||
summary: formData.value?.summary || '',
|
||||
title: formData.value?.title || '',
|
||||
};
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
formApi.resetForm();
|
||||
formApi.setValues(getFormValues());
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal :title="getTitle">
|
||||
<Form class="mx-4" />
|
||||
<template #prepend-footer>
|
||||
<div class="flex-auto">
|
||||
<Button type="primary" danger @click="resetForm">
|
||||
{{ $t('common.reset') }}
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
||||
Loading…
Reference in New Issue
Block a user