feat: 新增系统站内信页面与接口联调
This commit is contained in:
parent
f52bd3fcec
commit
81af5b5bdf
@ -69,6 +69,10 @@ const SUPPORTED_ADMIN_MENU_NAMES = new Set([
|
|||||||
'SystemMenuCreate',
|
'SystemMenuCreate',
|
||||||
'SystemMenuDelete',
|
'SystemMenuDelete',
|
||||||
'SystemMenuEdit',
|
'SystemMenuEdit',
|
||||||
|
'SystemNotice',
|
||||||
|
'SystemNoticeCreate',
|
||||||
|
'SystemNoticeDelete',
|
||||||
|
'SystemNoticeEdit',
|
||||||
'SystemRole',
|
'SystemRole',
|
||||||
'SystemRoleCreate',
|
'SystemRoleCreate',
|
||||||
'SystemRoleDelete',
|
'SystemRoleDelete',
|
||||||
|
|||||||
@ -3,4 +3,5 @@ export * from './dict';
|
|||||||
export * from './log';
|
export * from './log';
|
||||||
export * from './menu';
|
export * from './menu';
|
||||||
export * from './role';
|
export * from './role';
|
||||||
|
export * from './notice';
|
||||||
export * from './user';
|
export * from './user';
|
||||||
|
|||||||
104
apps/web-antdv-next/src/api/system/notice.ts
Normal file
104
apps/web-antdv-next/src/api/system/notice.ts
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import type { Recordable } from '@vben/types';
|
||||||
|
|
||||||
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
|
export namespace SystemNoticeApi {
|
||||||
|
export interface NoticeItem {
|
||||||
|
[key: string]: any;
|
||||||
|
content: string;
|
||||||
|
createTime?: string;
|
||||||
|
createdBy?: string;
|
||||||
|
id: string;
|
||||||
|
isDeleted: boolean;
|
||||||
|
isTop: boolean;
|
||||||
|
level: number;
|
||||||
|
notifyUsers?: 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;
|
||||||
|
isTop?: boolean | number | string;
|
||||||
|
keyword?: string;
|
||||||
|
level?: number | string;
|
||||||
|
notifyUsers?: string;
|
||||||
|
page?: number;
|
||||||
|
pageNo?: number;
|
||||||
|
pageSize?: number;
|
||||||
|
status?: 0 | 1 | number | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PageResult<T> {
|
||||||
|
items: T[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getNoticeList(params: Recordable<any>) {
|
||||||
|
return requestClient.get<SystemNoticeApi.PageResult<SystemNoticeApi.NoticeItem>>(
|
||||||
|
'/system/notice/list',
|
||||||
|
{ params },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getNoticeDetail(id: string) {
|
||||||
|
return requestClient.get<SystemNoticeApi.NoticeItem>(`/system/notice/detail/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
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}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function toggleNoticeStatus(id: string, status: SystemNoticeApi.NoticeItem['status']) {
|
||||||
|
return requestClient.post('/system/notice/toggle', undefined, {
|
||||||
|
params: {
|
||||||
|
id,
|
||||||
|
status,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function toggleNoticeTop(id: string, isTop: boolean) {
|
||||||
|
return requestClient.post('/system/notice/top', undefined, {
|
||||||
|
params: {
|
||||||
|
id,
|
||||||
|
isTop: isTop ? 1 : 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
createNotice,
|
||||||
|
deleteNotice,
|
||||||
|
getNoticeDetail,
|
||||||
|
getNoticeList,
|
||||||
|
toggleNoticeStatus,
|
||||||
|
toggleNoticeTop,
|
||||||
|
updateNotice,
|
||||||
|
};
|
||||||
|
|
||||||
@ -111,6 +111,31 @@
|
|||||||
"total": "Total",
|
"total": "Total",
|
||||||
"unconfigured": "Loki Not Configured"
|
"unconfigured": "Loki Not Configured"
|
||||||
},
|
},
|
||||||
|
"notice": {
|
||||||
|
"content": "Content",
|
||||||
|
"createTime": "Create Time",
|
||||||
|
"deleteConfirm": "Confirm deleting \"{0}\"?",
|
||||||
|
"disableSuccess": "Notice disabled",
|
||||||
|
"enableSuccess": "Notice enabled",
|
||||||
|
"isTop": "Top",
|
||||||
|
"keyword": "Keyword",
|
||||||
|
"level": "Level",
|
||||||
|
"levelText": "Level {level}",
|
||||||
|
"name": "Notice",
|
||||||
|
"notifyUsers": "Notify Users",
|
||||||
|
"status": "Status",
|
||||||
|
"summary": "Summary",
|
||||||
|
"title": "Notices",
|
||||||
|
"top": "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": {
|
"role": {
|
||||||
"title": "Role Management",
|
"title": "Role Management",
|
||||||
"list": "Role List",
|
"list": "Role List",
|
||||||
|
|||||||
@ -113,6 +113,31 @@
|
|||||||
"total": "总量",
|
"total": "总量",
|
||||||
"unconfigured": "Loki 未配置"
|
"unconfigured": "Loki 未配置"
|
||||||
},
|
},
|
||||||
|
"notice": {
|
||||||
|
"content": "内容",
|
||||||
|
"createTime": "创建时间",
|
||||||
|
"deleteConfirm": "确认删除「{0}」吗?",
|
||||||
|
"disableSuccess": "已停用站内信",
|
||||||
|
"enableSuccess": "已启用站内信",
|
||||||
|
"isTop": "置顶",
|
||||||
|
"keyword": "关键字",
|
||||||
|
"level": "等级",
|
||||||
|
"levelText": "等级 {level}",
|
||||||
|
"name": "站内信",
|
||||||
|
"notifyUsers": "通知用户",
|
||||||
|
"status": "状态",
|
||||||
|
"summary": "摘要",
|
||||||
|
"title": "站内信管理",
|
||||||
|
"top": "置顶",
|
||||||
|
"topNo": "否",
|
||||||
|
"topYes": "是",
|
||||||
|
"topSuccess": "置顶成功",
|
||||||
|
"cancelTopSuccess": "取消置顶成功",
|
||||||
|
"toggle": "启停",
|
||||||
|
"toggleStatusConfirm": "确认切换「{0}」启停状态吗?",
|
||||||
|
"topToggle": "置顶切换",
|
||||||
|
"toggleTopConfirm": "确认切换「{0}」置顶状态吗?"
|
||||||
|
},
|
||||||
"role": {
|
"role": {
|
||||||
"title": "角色管理",
|
"title": "角色管理",
|
||||||
"list": "角色列表",
|
"list": "角色列表",
|
||||||
|
|||||||
@ -66,6 +66,15 @@ const routes: RouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
component: () => import('#/views/system/log/list.vue'),
|
component: () => import('#/views/system/log/list.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/system/notice',
|
||||||
|
name: 'SystemNotice',
|
||||||
|
meta: {
|
||||||
|
icon: 'mdi:bell-outline',
|
||||||
|
title: $t('system.notice.title'),
|
||||||
|
},
|
||||||
|
component: () => import('#/views/system/notice/list.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/system/ktTableDemo',
|
path: '/system/ktTableDemo',
|
||||||
name: 'SystemKtTableDemo',
|
name: 'SystemKtTableDemo',
|
||||||
|
|||||||
156
apps/web-antdv-next/src/views/system/notice/data.ts
Normal file
156
apps/web-antdv-next/src/views/system/notice/data.ts
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
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_STATUS_OPTIONS = [
|
||||||
|
{ color: 'success', label: $t('common.enabled'), value: 1 },
|
||||||
|
{ color: 'default', label: $t('common.disabled'), value: 0 },
|
||||||
|
];
|
||||||
|
|
||||||
|
export function getNoticeStatusOptions() {
|
||||||
|
return NOTICE_STATUS_OPTIONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSearchSchema(): VbenFormSchema[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
allowClear: true,
|
||||||
|
},
|
||||||
|
fieldName: 'keyword',
|
||||||
|
label: $t('system.notice.keyword'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
allowClear: true,
|
||||||
|
options: NOTICE_LEVEL_OPTIONS,
|
||||||
|
},
|
||||||
|
fieldName: 'level',
|
||||||
|
label: $t('system.notice.level'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
allowClear: true,
|
||||||
|
options: NOTICE_STATUS_OPTIONS,
|
||||||
|
},
|
||||||
|
fieldName: 'status',
|
||||||
|
label: $t('system.notice.status'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
allowClear: true,
|
||||||
|
options: [
|
||||||
|
{ label: $t('common.no'), value: 0 },
|
||||||
|
{ label: $t('common.yes'), value: 1 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
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'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
243
apps/web-antdv-next/src/views/system/notice/list.vue
Normal file
243
apps/web-antdv-next/src/views/system/notice/list.vue
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
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 { message, Tag } from 'antdv-next';
|
||||||
|
|
||||||
|
import {
|
||||||
|
deleteNotice,
|
||||||
|
getNoticeList,
|
||||||
|
toggleNoticeStatus,
|
||||||
|
toggleNoticeTop,
|
||||||
|
} from '#/api/system/notice';
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
|
||||||
|
const noticeStatusOptions = getNoticeStatusOptions();
|
||||||
|
|
||||||
|
const columns: Array<TableColumnType<SystemNoticeApi.NoticeItem>> = [
|
||||||
|
{
|
||||||
|
dataIndex: 'isTop',
|
||||||
|
fixed: 'left',
|
||||||
|
key: 'isTop',
|
||||||
|
title: $t('system.notice.top'),
|
||||||
|
width: 90,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'title',
|
||||||
|
fixed: 'left',
|
||||||
|
key: 'title',
|
||||||
|
title: $t('system.notice.title'),
|
||||||
|
width: 260,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'level',
|
||||||
|
key: 'level',
|
||||||
|
title: $t('system.notice.level'),
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'status',
|
||||||
|
key: 'status',
|
||||||
|
title: $t('system.notice.status'),
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'notifyUsers',
|
||||||
|
key: 'notifyUsers',
|
||||||
|
title: $t('system.notice.notifyUsers'),
|
||||||
|
width: 180,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
key: 'createTime',
|
||||||
|
title: $t('system.notice.createTime'),
|
||||||
|
width: 190,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
dataIndex: 'summary',
|
||||||
|
key: 'summary',
|
||||||
|
title: $t('system.notice.summary'),
|
||||||
|
width: 280,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
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'),
|
||||||
|
onClick: onToggleStatus,
|
||||||
|
permissionCodes: ['System:Notice:Edit'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
confirm: (row) =>
|
||||||
|
$t('system.notice.toggleTopConfirm', [row.title]),
|
||||||
|
key: 'top',
|
||||||
|
label: $t('system.notice.topToggle'),
|
||||||
|
onClick: onToggleTop,
|
||||||
|
permissionCodes: ['System:Notice:Edit'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
confirm: (row) =>
|
||||||
|
$t('system.notice.deleteConfirm', [row.title]),
|
||||||
|
danger: true,
|
||||||
|
key: 'delete',
|
||||||
|
label: $t('common.delete'),
|
||||||
|
onClick: onDelete,
|
||||||
|
permissionCodes: ['System:Notice:Delete'],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
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(),
|
||||||
|
},
|
||||||
|
rowActions,
|
||||||
|
rowKey: 'id',
|
||||||
|
showSelection: false,
|
||||||
|
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>,
|
||||||
|
) {
|
||||||
|
const nextStatus = row.status === 1 ? 0 : 1;
|
||||||
|
await toggleNoticeStatus(row.id, nextStatus);
|
||||||
|
message.success(
|
||||||
|
nextStatus === 1
|
||||||
|
? $t('system.notice.enableSuccess')
|
||||||
|
: $t('system.notice.disableSuccess'),
|
||||||
|
);
|
||||||
|
await context.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onToggleTop(
|
||||||
|
row: SystemNoticeApi.NoticeItem,
|
||||||
|
context: KtTableContext<SystemNoticeApi.NoticeItem>,
|
||||||
|
) {
|
||||||
|
await toggleNoticeTop(row.id, !row.isTop);
|
||||||
|
message.success(
|
||||||
|
row.isTop
|
||||||
|
? $t('system.notice.cancelTopSuccess')
|
||||||
|
: $t('system.notice.topSuccess'),
|
||||||
|
);
|
||||||
|
await context.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onDelete(
|
||||||
|
row: SystemNoticeApi.NoticeItem,
|
||||||
|
context?: KtTableContext<SystemNoticeApi.NoticeItem>,
|
||||||
|
) {
|
||||||
|
const hideLoading = message.loading({
|
||||||
|
content: $t('ui.actionMessage.deleting', [row.title]),
|
||||||
|
duration: 0,
|
||||||
|
key: 'action_process_msg',
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await deleteNotice(row.id);
|
||||||
|
message.success({
|
||||||
|
content: $t('ui.actionMessage.deleteSuccess', [row.title]),
|
||||||
|
key: 'action_process_msg',
|
||||||
|
});
|
||||||
|
await (context || tableApi).reload();
|
||||||
|
} catch {
|
||||||
|
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'">
|
||||||
|
<Tag :color="record.isTop ? 'warning' : 'default'">
|
||||||
|
{{ record.isTop ? $t('system.notice.topYes') : $t('system.notice.topNo') }}
|
||||||
|
</Tag>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'level'">
|
||||||
|
<Tag :color="getNoticeLevelColor(record.level)">
|
||||||
|
{{ $t('system.notice.levelText', { level: record.level }) }}
|
||||||
|
</Tag>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'status'">
|
||||||
|
<Tag :color="getNoticeStatusOption(record.status)?.color || 'default'">
|
||||||
|
{{ getNoticeStatusOption(record.status)?.label || record.status }}
|
||||||
|
</Tag>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</KtTable>
|
||||||
|
</Page>
|
||||||
|
</template>
|
||||||
95
apps/web-antdv-next/src/views/system/notice/modules/form.vue
Normal file
95
apps/web-antdv-next/src/views/system/notice/modules/form.vue
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<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;
|
||||||
|
if (currentId) {
|
||||||
|
await updateNotice(currentId, data);
|
||||||
|
} else {
|
||||||
|
await 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