94 changed files with 0 additions and 7220 deletions
@ -1,11 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
// 获得地区树
|
||||
export function getAreaTree() { |
||||
return defHttp.get({ url: '/system/area/tree' }) |
||||
} |
||||
|
||||
// 获得 IP 对应的地区名
|
||||
export function getAreaByIp(ip: string) { |
||||
return defHttp.get({ url: `/system/area/get-by-ip?ip=${ip}` }) |
||||
} |
@ -1,36 +0,0 @@
|
||||
import type { DictDataExportReqVO, DictDataPageReqVO, DictDataVO } from './types' |
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
// 查询字典数据(精简)列表
|
||||
export function listSimpleDictData() { |
||||
return defHttp.get({ url: '/system/dict-data/list-all-simple' }) |
||||
} |
||||
|
||||
// 查询字典数据列表
|
||||
export function getDictDataPage(params: DictDataPageReqVO) { |
||||
return defHttp.get({ url: '/system/dict-data/page', params }) |
||||
} |
||||
|
||||
// 查询字典数据详情
|
||||
export function getDictData(id: number) { |
||||
return defHttp.get({ url: `/system/dict-data/get?id=${id}` }) |
||||
} |
||||
|
||||
// 新增字典数据
|
||||
export function createDictData(data: DictDataVO) { |
||||
return defHttp.post({ url: '/system/dict-data/create', data }) |
||||
} |
||||
|
||||
// 修改字典数据
|
||||
export function updateDictData(data: DictDataVO) { |
||||
return defHttp.put({ url: '/system/dict-data/update', data }) |
||||
} |
||||
|
||||
// 删除字典数据
|
||||
export function deleteDictData(id: number) { |
||||
return defHttp.delete({ url: `/system/dict-data/delete?id=${id}` }) |
||||
} |
||||
// 导出字典类型数据
|
||||
export function exportDictData(params: DictDataExportReqVO) { |
||||
return defHttp.get({ url: '/system/dict-data/export', params }) |
||||
} |
@ -1,36 +0,0 @@
|
||||
import type { DictTypeExportReqVO, DictTypePageReqVO, DictTypeVO } from './types' |
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
// 查询字典(精简)列表
|
||||
export function listSimpleDictType() { |
||||
return defHttp.get({ url: '/system/dict-type/list-all-simple' }) |
||||
} |
||||
|
||||
// 查询字典列表
|
||||
export function getDictTypePage(params: DictTypePageReqVO) { |
||||
return defHttp.get({ url: '/system/dict-type/page', params }) |
||||
} |
||||
|
||||
// 查询字典详情
|
||||
export function getDictType(id: number) { |
||||
return defHttp.get({ url: `/system/dict-type/get?id=${id}` }) |
||||
} |
||||
|
||||
// 新增字典
|
||||
export function createDictType(data: DictTypeVO) { |
||||
return defHttp.post({ url: '/system/dict-type/create', data }) |
||||
} |
||||
|
||||
// 修改字典
|
||||
export function updateDictType(data: DictTypeVO) { |
||||
return defHttp.put({ url: '/system/dict-type/update', data }) |
||||
} |
||||
|
||||
// 删除字典
|
||||
export function deleteDictType(id: number) { |
||||
return defHttp.delete({ url: `/system/dict-type/delete?id=${id}` }) |
||||
} |
||||
// 导出字典类型
|
||||
export function exportDictType(params: DictTypeExportReqVO) { |
||||
return defHttp.get({ url: '/system/dict-type/export', params }) |
||||
} |
@ -1,46 +0,0 @@
|
||||
export interface DictTypeVO { |
||||
id: number |
||||
name: string |
||||
type: string |
||||
status: number |
||||
remark: string |
||||
createTime: Date |
||||
} |
||||
|
||||
export interface DictTypePageReqVO { |
||||
name: string |
||||
type: string |
||||
status: number |
||||
createTime: Date[] |
||||
} |
||||
|
||||
export interface DictTypeExportReqVO { |
||||
name: string |
||||
type: string |
||||
status: number |
||||
createTime: Date[] |
||||
} |
||||
|
||||
export interface DictDataVO { |
||||
id: number |
||||
sort: number |
||||
label: string |
||||
value: string |
||||
dictType: string |
||||
status: number |
||||
colorType: string |
||||
cssClass: string |
||||
remark: string |
||||
createTime: Date |
||||
} |
||||
export interface DictDataPageReqVO { |
||||
label: string |
||||
dictType: string |
||||
status: number |
||||
} |
||||
|
||||
export interface DictDataExportReqVO { |
||||
label: string |
||||
dictType: string |
||||
status: number |
||||
} |
@ -1,49 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface ErrorCodeVO { |
||||
id: number |
||||
type: number |
||||
applicationName: string |
||||
code: number |
||||
message: string |
||||
memo: string |
||||
createTime: Date |
||||
} |
||||
|
||||
export interface ErrorCodePageReqVO extends PageParam { |
||||
type?: number |
||||
applicationName?: string |
||||
code?: number |
||||
message?: string |
||||
createTime?: Date[] |
||||
} |
||||
|
||||
// 查询错误码列表
|
||||
export function getErrorCodePage(params: ErrorCodePageReqVO) { |
||||
return defHttp.get({ url: '/system/error-code/page', params }) |
||||
} |
||||
|
||||
// 查询错误码详情
|
||||
export function getErrorCode(id: number) { |
||||
return defHttp.get({ url: `/system/error-code/get?id=${id}` }) |
||||
} |
||||
|
||||
// 新增错误码
|
||||
export function createErrorCode(data: ErrorCodeVO) { |
||||
return defHttp.post({ url: '/system/error-code/create', data }) |
||||
} |
||||
|
||||
// 修改错误码
|
||||
export function updateErrorCode(data: ErrorCodeVO) { |
||||
return defHttp.put({ url: '/system/error-code/update', data }) |
||||
} |
||||
|
||||
// 删除错误码
|
||||
export function deleteErrorCode(id: number) { |
||||
return defHttp.delete({ url: `/system/error-code/delete?id=${id}` }) |
||||
} |
||||
|
||||
// 导出错误码
|
||||
export function excelErrorCode(params: ErrorCodePageReqVO) { |
||||
return defHttp.download({ url: '/system/error-code/export-excel', params }, '错误码.xls') |
||||
} |
@ -1,30 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface LoginLogVO { |
||||
id: number |
||||
logType: number |
||||
traceId: number |
||||
userId: number |
||||
userType: number |
||||
username: string |
||||
status: number |
||||
userIp: string |
||||
userAgent: string |
||||
createTime: Date |
||||
} |
||||
|
||||
export interface LoginLogReqVO extends PageParam { |
||||
userIp?: string |
||||
username?: string |
||||
status?: boolean |
||||
createTime?: Date[] |
||||
} |
||||
|
||||
// 查询登录日志列表
|
||||
export function getLoginLogPage(params: LoginLogReqVO) { |
||||
return defHttp.get({ url: '/system/login-log/page', params }) |
||||
} |
||||
// 导出登录日志
|
||||
export function exportLoginLog(params: LoginLogReqVO) { |
||||
return defHttp.download({ url: '/system/login-log/export', params }, '登录日志.xls') |
||||
} |
@ -1,31 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
// 创建邮箱账号
|
||||
export function createMailAccount(data) { |
||||
return defHttp.post({ url: '/system/mail-account/create', data }) |
||||
} |
||||
|
||||
// 更新邮箱账号
|
||||
export function updateMailAccount(data) { |
||||
return defHttp.put({ url: '/system/mail-account/update', data }) |
||||
} |
||||
|
||||
// 删除邮箱账号
|
||||
export function deleteMailAccount(id: number) { |
||||
return defHttp.delete({ url: `/system/mail-account/delete?id=${id}` }) |
||||
} |
||||
|
||||
// 获得邮箱账号
|
||||
export function getMailAccount(id: number) { |
||||
return defHttp.get({ url: `/system/mail-account/get?id=${id}` }) |
||||
} |
||||
|
||||
// 获得邮箱账号分页
|
||||
export function getMailAccountPage(params) { |
||||
return defHttp.get({ url: '/system/mail-account/page', params }) |
||||
} |
||||
|
||||
// 获取邮箱账号的精简信息列表
|
||||
export function getSimpleMailAccountList() { |
||||
return defHttp.get({ url: '/system/mail-account/list-all-simple' }) |
||||
} |
@ -1,11 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
// 获得邮件日志
|
||||
export function getMailLog(id: number) { |
||||
return defHttp.get({ url: `/system/mail-log/get?id=${id}` }) |
||||
} |
||||
|
||||
// 获得邮件日志分页
|
||||
export function getMailAccountPage(params) { |
||||
return defHttp.get({ url: '/system/mail-log/page', params }) |
||||
} |
@ -1,54 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
// 创建邮件模版
|
||||
export function createMailTemplate(data) { |
||||
return defHttp.post({ url: '/system/mail-template/create', data }) |
||||
} |
||||
|
||||
// 更新邮件模版
|
||||
export function updateMailTemplate(data) { |
||||
return defHttp.put({ url: '/system/mail-template/update', data }) |
||||
} |
||||
|
||||
// 删除邮件模版
|
||||
export function deleteMailTemplate(id: number) { |
||||
return defHttp.delete({ url: `/system/mail-template/delete?id=${id}` }) |
||||
} |
||||
|
||||
// 获得邮件模版
|
||||
export function getMailTemplate(id: number) { |
||||
return defHttp.get({ url: `/system/mail-template/get?id=${id}` }) |
||||
} |
||||
|
||||
// 获得邮件模版分页
|
||||
export function getMailTemplatePage(params) { |
||||
return defHttp.get({ url: '/system/mail-template/page', params }) |
||||
} |
||||
|
||||
// 邮件模板
|
||||
export interface MailTemplate { |
||||
name: string // 标题
|
||||
code: string // 编码
|
||||
accountId: number |
||||
nickname: string // 发送人
|
||||
title: string // 标题
|
||||
content: string // 内容
|
||||
status: number //
|
||||
remark?: any // 备注
|
||||
id: number |
||||
params: string[] // 模板里的参数
|
||||
createTime: number |
||||
} |
||||
|
||||
export interface SendMailParams { |
||||
mail: string |
||||
templateCode: string |
||||
templateParams: { |
||||
[key: string]: any |
||||
} |
||||
} |
||||
|
||||
// 发送测试邮件
|
||||
export function sendMail(data: SendMailParams) { |
||||
return defHttp.post({ url: '/system/mail-template/send-mail', data }) |
||||
} |
@ -1,42 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface NoticeVO { |
||||
id: number |
||||
title: string |
||||
type: number |
||||
content: string |
||||
status: number |
||||
remark: string |
||||
creator: string |
||||
createTime: Date |
||||
} |
||||
|
||||
export interface NoticePageReqVO extends PageParam { |
||||
title?: string |
||||
status?: number |
||||
} |
||||
|
||||
// 查询公告列表
|
||||
export function getNoticePage(params: NoticePageReqVO) { |
||||
return defHttp.get({ url: '/system/notice/page', params }) |
||||
} |
||||
|
||||
// 查询公告详情
|
||||
export function getNotice(id: number) { |
||||
return defHttp.get({ url: `/system/notice/get?id=${id}` }) |
||||
} |
||||
|
||||
// 新增公告
|
||||
export function createNotice(data: NoticeVO) { |
||||
return defHttp.post({ url: '/system/notice/create', data }) |
||||
} |
||||
|
||||
// 修改公告
|
||||
export function updateNotice(data: NoticeVO) { |
||||
return defHttp.put({ url: '/system/notice/update', data }) |
||||
} |
||||
|
||||
// 删除公告
|
||||
export function deleteNotice(id: number) { |
||||
return defHttp.delete({ url: `/system/notice/delete?id=${id}` }) |
||||
} |
@ -1,32 +0,0 @@
|
||||
import qs from 'qs' |
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
// 获得站内信分页
|
||||
export function getNotifyMessagePage(params) { |
||||
return defHttp.get({ url: '/system/notify-message/page', params }) |
||||
} |
||||
|
||||
// 获得我的站内信分页
|
||||
export function getMyNotifyMessagePage(params) { |
||||
return defHttp.get({ url: '/system/notify-message/my-page', params }) |
||||
} |
||||
|
||||
// 批量标记已读
|
||||
export function updateNotifyMessageRead(ids: number[]) { |
||||
return defHttp.put({ url: `/system/notify-message/update-read?${qs.stringify({ ids }, { indices: false })}` }) |
||||
} |
||||
|
||||
// 标记所有站内信为已读
|
||||
export function updateAllNotifyMessageRead() { |
||||
return defHttp.put({ url: '/system/notify-message/update-all-read' }) |
||||
} |
||||
|
||||
// 获取当前用户的最新站内信列表
|
||||
export function getUnreadNotifyMessageList() { |
||||
return defHttp.get({ url: '/system/notify-message/get-unread-list' }) |
||||
} |
||||
|
||||
// 获得当前用户的未读站内信数量
|
||||
export function getUnreadNotifyMessageCount() { |
||||
return defHttp.get<number>({ url: '/system/notify-message/get-unread-count' }) |
||||
} |
@ -1,63 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
// 创建站内信模板
|
||||
export function createNotifyTemplate(data) { |
||||
return defHttp.post({ url: '/system/notify-template/create', data }) |
||||
} |
||||
|
||||
// 更新站内信模板
|
||||
export function updateNotifyTemplate(data) { |
||||
return defHttp.put({ url: '/system/notify-template/update', data }) |
||||
} |
||||
|
||||
// 删除站内信模板
|
||||
export function deleteNotifyTemplate(id: number) { |
||||
return defHttp.delete({ url: `/system/notify-template/delete?id=${id}` }) |
||||
} |
||||
|
||||
// 获得站内信模板
|
||||
export function getNotifyTemplate(id: number) { |
||||
return defHttp.get({ url: `/system/notify-template/get?id=${id}` }) |
||||
} |
||||
|
||||
// 获得站内信模板分页
|
||||
export function getNotifyTemplatePage(params) { |
||||
return defHttp.get({ url: '/system/notify-template/page', params }) |
||||
} |
||||
|
||||
// 获取岗位精简信息列表
|
||||
export function listSimplePosts() { |
||||
return defHttp.get({ url: '/system/post/list-all-simple' }) |
||||
} |
||||
|
||||
// 导出站内信模板 Excel
|
||||
export function exportNotifyTemplateExcel(params) { |
||||
return defHttp.download({ url: '/system/notify-template/export-excel', params }, '导出站内信模板.xls') |
||||
} |
||||
|
||||
export interface SendNotifyParam { |
||||
userId: number |
||||
templateCode: string |
||||
templateParams: { |
||||
[key: string]: string |
||||
} |
||||
} |
||||
|
||||
export interface NotifyTemplate { |
||||
name: string |
||||
code: string |
||||
type: number |
||||
nickname: string |
||||
content: string |
||||
status: number |
||||
remark?: any |
||||
id: number |
||||
params: string[] |
||||
createTime: number |
||||
key: string |
||||
} |
||||
|
||||
// 发送
|
||||
export function sendNotify(data: SendNotifyParam) { |
||||
return defHttp.post({ url: '/system/notify-template/send-notify', data }) |
||||
} |
@ -1,51 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface OAuth2ClientVO { |
||||
id: number |
||||
clientId: string |
||||
secret: string |
||||
name: string |
||||
logo: string |
||||
description: string |
||||
status: number |
||||
accessTokenValiditySeconds: number |
||||
refreshTokenValiditySeconds: number |
||||
redirectUris: string[] |
||||
autoApprove: boolean |
||||
authorizedGrantTypes: string[] |
||||
scopes: string[] |
||||
authorities: string[] |
||||
resourceIds: string[] |
||||
additionalInformation: string |
||||
isAdditionalInformationJson: boolean |
||||
createTime: Date |
||||
} |
||||
|
||||
export interface OAuth2ClientPageReqVO extends PageParam { |
||||
name?: string |
||||
status?: number |
||||
} |
||||
// 查询 OAuth2列表
|
||||
export function getOAuth2ClientPage(params: OAuth2ClientPageReqVO) { |
||||
return defHttp.get({ url: '/system/oauth2-client/page', params }) |
||||
} |
||||
|
||||
// 查询 OAuth2详情
|
||||
export function getOAuth2Client(id: number) { |
||||
return defHttp.get({ url: `/system/oauth2-client/get?id=${id}` }) |
||||
} |
||||
|
||||
// 新增 OAuth2
|
||||
export function createOAuth2Client(data: OAuth2ClientVO) { |
||||
return defHttp.post({ url: '/system/oauth2-client/create', data }) |
||||
} |
||||
|
||||
// 修改 OAuth2
|
||||
export function updateOAuth2Client(data: OAuth2ClientVO) { |
||||
return defHttp.put({ url: '/system/oauth2-client/update', data }) |
||||
} |
||||
|
||||
// 删除 OAuth2
|
||||
export function deleteOAuth2Client(id: number) { |
||||
return defHttp.delete({ url: `/system/oauth2-client/delete?id=${id}` }) |
||||
} |
@ -1,28 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface OAuth2TokenVO { |
||||
id: number |
||||
accessToken: string |
||||
refreshToken: string |
||||
userId: number |
||||
userType: number |
||||
clientId: string |
||||
createTime: Date |
||||
expiresTime: Date |
||||
} |
||||
|
||||
export interface OAuth2TokenPageReqVO extends PageParam { |
||||
userId?: number |
||||
userType?: number |
||||
clientId?: string |
||||
} |
||||
|
||||
// 查询 token列表
|
||||
export function getAccessTokenPage(params: OAuth2TokenPageReqVO) { |
||||
return defHttp.get({ url: '/system/oauth2-token/page', params }) |
||||
} |
||||
|
||||
// 删除 token
|
||||
export function deleteAccessToken(accessToken: number) { |
||||
return defHttp.delete({ url: `/system/oauth2-token/delete?accessToken=${accessToken}` }) |
||||
} |
@ -1,41 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface OperateLogVO { |
||||
id: number |
||||
userNickname: string |
||||
traceId: string |
||||
userId: number |
||||
module: string |
||||
name: string |
||||
type: number |
||||
content: string |
||||
exts: Map<string, object> |
||||
defHttpMethod: string |
||||
defHttpUrl: string |
||||
userIp: string |
||||
userAgent: string |
||||
javaMethod: string |
||||
javaMethodArgs: string |
||||
startTime: Date |
||||
duration: number |
||||
resultCode: number |
||||
resultMsg: string |
||||
resultData: string |
||||
} |
||||
|
||||
export interface OperateLogPageReqVO extends PageParam { |
||||
module?: string |
||||
userNickname?: string |
||||
type?: number |
||||
success?: boolean |
||||
startTime?: Date[] |
||||
} |
||||
|
||||
// 查询操作日志列表
|
||||
export function getOperateLogPage(params: OperateLogPageReqVO) { |
||||
return defHttp.get({ url: '/system/operate-log/page', params }) |
||||
} |
||||
// 导出操作日志
|
||||
export function exportOperateLog(params: OperateLogPageReqVO) { |
||||
return defHttp.download({ url: '/system/operate-log/export', params }, '操作日志.xls') |
||||
} |
@ -1,42 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface PermissionAssignUserRoleReqVO { |
||||
userId: number |
||||
roleIds: number[] |
||||
} |
||||
|
||||
export interface PermissionAssignRoleMenuReqVO { |
||||
roleId: number |
||||
menuIds: number[] |
||||
} |
||||
|
||||
export interface PermissionAssignRoleDataScopeReqVO { |
||||
roleId: number |
||||
dataScope: number |
||||
dataScopeDeptIds: number[] |
||||
} |
||||
|
||||
// 查询角色拥有的菜单权限
|
||||
export function listRoleMenus(roleId: number) { |
||||
return defHttp.get({ url: `/system/permission/list-role-menus?roleId=${roleId}` }) |
||||
} |
||||
|
||||
// 赋予角色菜单权限
|
||||
export function assignRoleMenu(data: PermissionAssignRoleMenuReqVO) { |
||||
return defHttp.post({ url: '/system/permission/assign-role-menu', data }) |
||||
} |
||||
|
||||
// 赋予角色数据权限
|
||||
export function assignRoleDataScope(data: PermissionAssignRoleDataScopeReqVO) { |
||||
return defHttp.post({ url: '/system/permission/assign-role-data-scope', data }) |
||||
} |
||||
|
||||
// 查询用户拥有的角色数组
|
||||
export function listUserRoles(userId: number) { |
||||
return defHttp.get({ url: `/system/permission/list-user-roles?userId=${userId}` }) |
||||
} |
||||
|
||||
// 赋予用户角色
|
||||
export function assignUserRole(data: PermissionAssignUserRoleReqVO) { |
||||
return defHttp.post({ url: '/system/permission/assign-user-role', data }) |
||||
} |
@ -1,58 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface PostVO { |
||||
id?: number |
||||
name: string |
||||
code: string |
||||
sort: number |
||||
status: number |
||||
remark: string |
||||
createTime?: Date |
||||
} |
||||
|
||||
export interface PostPageReqVO extends PageParam { |
||||
code?: string |
||||
name?: string |
||||
status?: number |
||||
} |
||||
|
||||
export interface PostExportReqVO { |
||||
code?: string |
||||
name?: string |
||||
status?: number |
||||
} |
||||
|
||||
// 查询岗位列表
|
||||
export function getPostPage(params: PostPageReqVO) { |
||||
return defHttp.get<PageResult<PostVO>>({ url: '/system/post/page', params }) |
||||
} |
||||
|
||||
// 获取岗位精简信息列表
|
||||
export function listSimplePosts() { |
||||
return defHttp.get({ url: '/system/post/list-all-simple' }) |
||||
} |
||||
|
||||
// 查询岗位详情
|
||||
export function getPost(id: number) { |
||||
return defHttp.get({ url: `/system/post/get?id=${id}` }) |
||||
} |
||||
|
||||
// 新增岗位
|
||||
export function createPost(data) { |
||||
return defHttp.post({ url: '/system/post/create', data }) |
||||
} |
||||
|
||||
// 修改岗位
|
||||
export function updatePost(data) { |
||||
return defHttp.put({ url: '/system/post/update', data }) |
||||
} |
||||
|
||||
// 删除岗位
|
||||
export function deletePost(id: number) { |
||||
return defHttp.delete({ url: `/system/post/delete?id=${id}` }) |
||||
} |
||||
|
||||
// 导出岗位
|
||||
export function exportPost(params: PostExportReqVO) { |
||||
return defHttp.download({ url: '/system/post/export', params }, '导出岗位.xls') |
||||
} |
@ -1,64 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface SensitiveWordVO { |
||||
id: number |
||||
name: string |
||||
status: number |
||||
description: string |
||||
tags: string[] |
||||
createTime: Date |
||||
} |
||||
|
||||
export interface SensitiveWordPageReqVO extends PageParam { |
||||
name?: string |
||||
tag?: string |
||||
status?: number |
||||
createTime?: Date[] |
||||
} |
||||
|
||||
export interface SensitiveWordExportReqVO { |
||||
name?: string |
||||
tag?: string |
||||
status?: number |
||||
createTime?: Date[] |
||||
} |
||||
|
||||
// 查询敏感词列表
|
||||
export function getSensitiveWordPage(params: SensitiveWordPageReqVO) { |
||||
return defHttp.get({ url: '/system/sensitive-word/page', params }) |
||||
} |
||||
|
||||
// 查询敏感词详情
|
||||
export function getSensitiveWord(id: number) { |
||||
return defHttp.get({ url: `/system/sensitive-word/get?id=${id}` }) |
||||
} |
||||
|
||||
// 新增敏感词
|
||||
export function createSensitiveWord(data: SensitiveWordVO) { |
||||
return defHttp.post({ url: '/system/sensitive-word/create', data }) |
||||
} |
||||
|
||||
// 修改敏感词
|
||||
export function updateSensitiveWord(data: SensitiveWordVO) { |
||||
return defHttp.put({ url: '/system/sensitive-word/update', data }) |
||||
} |
||||
|
||||
// 删除敏感词
|
||||
export function deleteSensitiveWord(id: number) { |
||||
return defHttp.delete({ url: `/system/sensitive-word/delete?id=${id}` }) |
||||
} |
||||
|
||||
// 导出敏感词
|
||||
export function exportSensitiveWord(params: SensitiveWordExportReqVO) { |
||||
return defHttp.download({ url: '/system/sensitive-word/export-excel', params }, '导出敏感词.xls') |
||||
} |
||||
|
||||
// 获取所有敏感词的标签数组
|
||||
export function getSensitiveWordTags() { |
||||
return defHttp.get({ url: '/system/sensitive-word/get-tags' }) |
||||
} |
||||
|
||||
// 获得文本所包含的不合法的敏感词数组
|
||||
export function validateText(id: number) { |
||||
return defHttp.get({ url: `/system/sensitive-word/validate-text?${id}` }) |
||||
} |
@ -1,50 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface SmsChannelVO { |
||||
id: number |
||||
code: string |
||||
status: number |
||||
signature: string |
||||
remark: string |
||||
apiKey: string |
||||
apiSecret: string |
||||
callbackUrl: string |
||||
createTime: Date |
||||
} |
||||
|
||||
export interface SmsChannelPageReqVO extends PageParam { |
||||
signature?: string |
||||
code?: string |
||||
status?: number |
||||
createTime?: Date[] |
||||
} |
||||
|
||||
// 查询短信渠道列表
|
||||
export function getSmsChannelPage(params: SmsChannelPageReqVO) { |
||||
return defHttp.get({ url: '/system/sms-channel/page', params }) |
||||
} |
||||
|
||||
// 获得短信渠道精简列表
|
||||
export function getSimpleSmsChannels() { |
||||
return defHttp.get({ url: '/system/sms-channel/list-all-simple' }) |
||||
} |
||||
|
||||
// 查询短信渠道详情
|
||||
export function getSmsChannel(id: number) { |
||||
return defHttp.get({ url: `/system/sms-channel/get?id=${id}` }) |
||||
} |
||||
|
||||
// 新增短信渠道
|
||||
export function createSmsChannel(data: SmsChannelVO) { |
||||
return defHttp.post({ url: '/system/sms-channel/create', data }) |
||||
} |
||||
|
||||
// 修改短信渠道
|
||||
export function updateSmsChannel(data: SmsChannelVO) { |
||||
return defHttp.put({ url: '/system/sms-channel/update', data }) |
||||
} |
||||
|
||||
// 删除短信渠道
|
||||
export function deleteSmsChannel(id: number) { |
||||
return defHttp.delete({ url: `/system/sms-channel/delete?id=${id}` }) |
||||
} |
@ -1,55 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface SmsLogVO { |
||||
id: number |
||||
channelId: number |
||||
channelCode: string |
||||
templateId: number |
||||
templateCode: string |
||||
templateType: number |
||||
templateContent: string |
||||
templateParams: Map<string, object> |
||||
mobile: string |
||||
userId: number |
||||
userType: number |
||||
sendStatus: number |
||||
sendTime: Date |
||||
apiSendCode: string |
||||
apiSendMsg: string |
||||
apidefHttpId: string |
||||
apiSerialNo: string |
||||
receiveStatus: number |
||||
receiveTime: Date |
||||
apiReceiveCode: string |
||||
apiReceiveMsg: string |
||||
createTime: Date |
||||
} |
||||
|
||||
export interface SmsLogPageReqVO extends PageParam { |
||||
channelId?: number |
||||
templateId?: number |
||||
mobile?: string |
||||
sendStatus?: number |
||||
sendTime?: Date[] |
||||
receiveStatus?: number |
||||
receiveTime?: Date[] |
||||
} |
||||
export interface SmsLogExportReqVO { |
||||
channelId?: number |
||||
templateId?: number |
||||
mobile?: string |
||||
sendStatus?: number |
||||
sendTime?: Date[] |
||||
receiveStatus?: number |
||||
receiveTime?: Date[] |
||||
} |
||||
|
||||
// 查询短信日志列表
|
||||
export function getSmsLogPage(params: SmsLogPageReqVO) { |
||||
return defHttp.get({ url: '/system/sms-log/page', params }) |
||||
} |
||||
|
||||
// 导出短信日志
|
||||
export function exportSmsLog(params: SmsLogExportReqVO) { |
||||
return defHttp.download({ url: '/system/sms-log/export', params }, '短信日志.xls') |
||||
} |
@ -1,94 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface SmsTemplateVO { |
||||
id: number |
||||
type: number |
||||
status: number |
||||
code: string |
||||
name: string |
||||
content: string |
||||
remark: string |
||||
apiTemplateId: string |
||||
channelId: number |
||||
channelCode: string |
||||
params: string[] |
||||
createTime: Date |
||||
} |
||||
|
||||
export interface SendSmsReqVO { |
||||
mobile: string |
||||
templateCode: string |
||||
templateParams: { |
||||
[key: string]: any |
||||
} |
||||
} |
||||
|
||||
export interface SmsTemplatePageReqVO { |
||||
type?: number |
||||
status?: number |
||||
code?: string |
||||
content?: string |
||||
apiTemplateId?: string |
||||
channelId?: number |
||||
createTime?: Date[] |
||||
} |
||||
|
||||
export interface SmsTemplateExportReqVO { |
||||
type?: number |
||||
status?: number |
||||
code?: string |
||||
content?: string |
||||
apiTemplateId?: string |
||||
channelId?: number |
||||
createTime?: Date[] |
||||
} |
||||
|
||||
// 查询短信模板列表
|
||||
export function getSmsTemplatePage(params: SmsTemplatePageReqVO) { |
||||
return defHttp.get({ url: '/system/sms-template/page', params }) |
||||
} |
||||
|
||||
// 查询短信模板详情
|
||||
export function getSmsTemplate(id: number) { |
||||
return defHttp.get({ url: `/system/sms-template/get?id=${id}` }) |
||||
} |
||||
|
||||
// 新增短信模板
|
||||
export function createSmsTemplate(data: SmsTemplateVO) { |
||||
return defHttp.post({ url: '/system/sms-template/create', data }) |
||||
} |
||||
|
||||
// 修改短信模板
|
||||
export function updateSmsTemplate(data: SmsTemplateVO) { |
||||
return defHttp.put({ url: '/system/sms-template/update', data }) |
||||
} |
||||
|
||||
// 删除短信模板
|
||||
export function deleteSmsTemplate(id: number) { |
||||
return defHttp.delete({ url: `/system/sms-template/delete?id=${id}` }) |
||||
} |
||||
|
||||
// 邮件模板
|
||||
export interface SmsTemplate { |
||||
name: string // 标题
|
||||
code: string // 编码
|
||||
accountId: number |
||||
nickname: string // 发送人
|
||||
title: string // 标题
|
||||
content: string // 内容
|
||||
status: number //
|
||||
remark?: any // 备注
|
||||
id: number |
||||
params: string[] // 模板里的参数
|
||||
createTime: number |
||||
} |
||||
|
||||
// 发送短信
|
||||
export function sendSms(data: SendSmsReqVO) { |
||||
return defHttp.post({ url: '/system/sms-template/send-sms', data }) |
||||
} |
||||
|
||||
// 导出短信模板
|
||||
export function exportSmsTemplate(params: SmsTemplateExportReqVO) { |
||||
return defHttp.download({ url: '/system/sms-template/export-excel', params }, '短信模板.xls') |
||||
} |
@ -1,49 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios' |
||||
|
||||
export interface TenantPackageVO { |
||||
id: number |
||||
name: string |
||||
status: number |
||||
remark: string |
||||
creator: string |
||||
updater: string |
||||
updateTime: string |
||||
menuIds: number[] |
||||
createTime: Date |
||||
} |
||||
|
||||
export interface TenantPackagePageReqVO extends PageParam { |
||||
name?: string |
||||
status?: number |
||||
remark?: string |
||||
createTime?: Date[] |
||||
} |
||||
|
||||
// 查询租户套餐列表
|
||||
export function getTenantPackagePage(params: TenantPackagePageReqVO) { |
||||
return defHttp.get({ url: '/system/tenant-package/page', params }) |
||||
} |
||||
|
||||
// 获得租户
|
||||
export function getTenantPackage(id: number) { |
||||
return defHttp.get({ url: `/system/tenant-package/get?id=${id}` }) |
||||
} |
||||
|
||||
// 新增租户套餐
|
||||
export function createTenantPackage(data: TenantPackageVO) { |
||||
return defHttp.post({ url: '/system/tenant-package/create', data }) |
||||
} |
||||
|
||||
// 修改租户套餐
|
||||
export function updateTenantPackage(data: TenantPackageVO) { |
||||
return defHttp.put({ url: '/system/tenant-package/update', data }) |
||||
} |
||||
|
||||
// 删除租户套餐
|
||||
export function deleteTenantPackage(id: number) { |
||||
return defHttp.delete({ url: `/system/tenant-package/delete?id=${id}` }) |
||||
} |
||||
// 获取租户套餐精简信息列表
|
||||
export function getTenantPackageList() { |
||||
return defHttp.get({ url: '/system/tenant-package/get-simple-list' }) |
||||
} |
@ -1,4 +0,0 @@
|
||||
import dictTag from './src/DictTag.vue' |
||||
import { withInstall } from '@/utils' |
||||
|
||||
export const DictTag = withInstall(dictTag) |
@ -1,72 +0,0 @@
|
||||
<script lang="tsx"> |
||||
import type { PropType } from 'vue' |
||||
import { defineComponent, ref } from 'vue' |
||||
import { Tag } from 'ant-design-vue' |
||||
import { isHexColor } from '@/utils/color' |
||||
import type { DictDataType } from '@/utils/dict' |
||||
import { getDictOpts } from '@/utils/dict' |
||||
import { propTypes } from '@/utils/propTypes' |
||||
|
||||
export default defineComponent({ |
||||
name: 'DictTag', |
||||
props: { |
||||
type: { |
||||
type: String as PropType<string>, |
||||
required: true, |
||||
}, |
||||
value: propTypes.oneOfType([propTypes.string, propTypes.number, propTypes.bool]), |
||||
icon: { type: String }, |
||||
}, |
||||
setup(props) { |
||||
const dictData = ref<DictDataType>() |
||||
const getDictObj = (dictType: string, value: string) => { |
||||
let dictOptions: DictDataType[] = [] |
||||
dictOptions = getDictOpts(dictType) |
||||
if (dictOptions && dictOptions.length === 0) |
||||
return |
||||
|
||||
dictOptions.forEach((dict: DictDataType) => { |
||||
if (dict.value === value) { |
||||
if (`${dict.colorType}` === 'primary') |
||||
dict.colorType = 'processing' |
||||
else if (`${dict.colorType}` === 'danger') |
||||
dict.colorType = 'error' |
||||
else if (`${dict.colorType}` === 'info') |
||||
dict.colorType = 'default' |
||||
|
||||
dictData.value = dict |
||||
} |
||||
}) |
||||
} |
||||
const rederDictTag = () => { |
||||
if (!props.type) |
||||
return null |
||||
|
||||
// 解决自定义字典标签值为零时标签不渲染的问题 |
||||
if (props.value === undefined || props.value === null) |
||||
return null |
||||
|
||||
getDictObj(props.type, props.value.toString()) |
||||
|
||||
if (dictData.value === undefined) |
||||
return null |
||||
|
||||
// 添加标签的文字颜色为白色,解决自定义背景颜色时标签文字看不清的问题 && isHexColor(dictData.value?.cssClass) |
||||
return ( |
||||
<Tag |
||||
color={ |
||||
dictData.value?.colorType |
||||
? dictData.value?.colorType |
||||
: dictData.value?.cssClass && isHexColor(dictData.value?.cssClass) |
||||
? dictData.value?.cssClass |
||||
: '' |
||||
} |
||||
> |
||||
{dictData.value?.label || ''} |
||||
</Tag> |
||||
) |
||||
} |
||||
return () => rederDictTag() |
||||
}, |
||||
}) |
||||
</script> |
@ -1,67 +0,0 @@
|
||||
import { defineStore } from 'pinia' |
||||
import type { DictState } from '@/types/store' |
||||
|
||||
import { store } from '@/store' |
||||
|
||||
import { DICT_KEY } from '@/enums/cacheEnum' |
||||
import { createLocalStorage } from '@/utils/cache' |
||||
import { listSimpleDictData } from '@/api/system/dict/data' |
||||
import type { DictDataVO } from '@/api/system/dict/types' |
||||
|
||||
const ls = createLocalStorage() |
||||
|
||||
export const useDictStore = defineStore({ |
||||
id: 'app-dict', |
||||
state: (): DictState => ({ |
||||
dictMap: new Map<string, any>(), |
||||
isSetDict: false, |
||||
}), |
||||
getters: { |
||||
getDictMap(state): Recordable { |
||||
const dictMap = ls.get(DICT_KEY) |
||||
if (dictMap) |
||||
state.dictMap = dictMap |
||||
|
||||
return state.dictMap |
||||
}, |
||||
getIsSetDict(state): boolean { |
||||
return state.isSetDict |
||||
}, |
||||
}, |
||||
actions: { |
||||
async setDictMap() { |
||||
const dictMap = ls.get(DICT_KEY) |
||||
if (dictMap) { |
||||
this.dictMap = dictMap |
||||
this.isSetDict = true |
||||
} |
||||
else { |
||||
const res = await listSimpleDictData() |
||||
// 设置数据
|
||||
const dictDataMap = new Map<string, any>() |
||||
res.forEach((dictData: DictDataVO) => { |
||||
// 获得 dictType 层级
|
||||
const enumValueObj = dictDataMap[dictData.dictType] |
||||
if (!enumValueObj) |
||||
dictDataMap[dictData.dictType] = [] |
||||
|
||||
// 处理 dictValue 层级
|
||||
dictDataMap[dictData.dictType].push({ |
||||
value: dictData.value, |
||||
label: dictData.label, |
||||
colorType: dictData.colorType, |
||||
cssClass: dictData.cssClass, |
||||
}) |
||||
}) |
||||
this.dictMap = dictDataMap |
||||
this.isSetDict = true |
||||
ls.set(DICT_KEY, dictDataMap, 60) // 60 秒 过期
|
||||
} |
||||
}, |
||||
}, |
||||
}) |
||||
|
||||
// Need to be used outside the setup
|
||||
export function useDictStoreWithOut() { |
||||
return useDictStore(store) |
||||
} |
@ -1,24 +0,0 @@
|
||||
import { defineStore } from 'pinia' |
||||
import { getUnreadNotifyMessageCount } from '@/api/system/notify/message' |
||||
|
||||
interface MessageState { |
||||
unreadCount: number // 未读消息数量
|
||||
} |
||||
|
||||
export const useUserMessageStore = defineStore('userMessage', { |
||||
state: (): MessageState => ({ |
||||
unreadCount: 0, |
||||
}), |
||||
getters: { |
||||
getUnreadCount(state) { |
||||
return state.unreadCount |
||||
}, |
||||
}, |
||||
actions: { |
||||
// 更新未读消息的数量
|
||||
async updateUnreadCount() { |
||||
const count = await getUnreadNotifyMessageCount() |
||||
this.unreadCount = count |
||||
}, |
||||
}, |
||||
}) |
@ -1,97 +0,0 @@
|
||||
/** |
||||
* 数据字典工具类 |
||||
*/ |
||||
import { useDictStoreWithOut } from '@/store/modules/dict' |
||||
import type { StringLiteralsToType } from '@/types/utils' |
||||
|
||||
const dictStore = useDictStoreWithOut() |
||||
|
||||
/** |
||||
* 获取 dictType 对应的数据字典数组 |
||||
* |
||||
* @param dictType 数据类型 |
||||
* @returns {*|Array} 数据字典数组 |
||||
*/ |
||||
export interface DictDataType<T extends string | number | boolean = string> { |
||||
dictType: string |
||||
label: string |
||||
value: T |
||||
key?: any |
||||
colorType: string |
||||
cssClass: string |
||||
} |
||||
|
||||
export function getDictDatas(dictType: string) { |
||||
return dictStore.getDictMap[dictType] || [] |
||||
} |
||||
|
||||
export function getDictOpts(dictType: string) { |
||||
/** |
||||
* 这里原来是转换类型 转换类型后反而显示不出来正确的Tag |
||||
* 实际类型转换交给下面的getDictOptions来处理 |
||||
* |
||||
* bugfix: |
||||
* dictOption.push({ |
||||
...dict, |
||||
value: parseInt(dict.value + '') |
||||
}) |
||||
原来的这种写法是造成页面卡死的原因 |
||||
*/ |
||||
return getDictDatas(dictType) |
||||
} |
||||
|
||||
export function getDictOptions<T extends 'string' | 'number' | 'boolean' = 'string'>(dictType: string, valueType?: T) { |
||||
const dictOption: DictDataType<StringLiteralsToType<T>>[] = [] |
||||
const dictOptions: DictDataType[] = getDictDatas(dictType) |
||||
if (dictOptions && dictOptions.length > 0) { |
||||
dictOptions.forEach((dict: DictDataType) => { |
||||
dictOption.push({ |
||||
...dict, |
||||
key: dict.value, |
||||
value: |
||||
valueType === 'string' |
||||
? `${dict.value}` |
||||
: valueType === 'boolean' |
||||
? `${dict.value}` === 'true' |
||||
: Number.parseInt(`${dict.value}`), |
||||
} as DictDataType<StringLiteralsToType<T>>) |
||||
}) |
||||
} |
||||
return dictOption |
||||
} |
||||
|
||||
export function getDictObj(dictType: string, value: any) { |
||||
const dictOptions: DictDataType[] = getDictDatas(dictType) |
||||
if (dictOptions) { |
||||
dictOptions.forEach((dict: DictDataType) => { |
||||
if (dict.value === value.toString()) |
||||
return dict |
||||
}) |
||||
} |
||||
else { |
||||
return null |
||||
} |
||||
} |
||||
|
||||
export enum DICT_TYPE { |
||||
USER_TYPE = 'user_type', |
||||
COMMON_STATUS = 'common_status', |
||||
SYSTEM_TENANT_PACKAGE_ID = 'system_tenant_package_id', |
||||
SYSTEM_USER_SEX = 'system_user_sex', |
||||
SYSTEM_MENU_TYPE = 'system_menu_type', |
||||
SYSTEM_ROLE_TYPE = 'system_role_type', |
||||
SYSTEM_DATA_SCOPE = 'system_data_scope', |
||||
SYSTEM_NOTICE_TYPE = 'system_notice_type', |
||||
SYSTEM_OPERATE_TYPE = 'system_operate_type', |
||||
SYSTEM_LOGIN_TYPE = 'system_login_type', |
||||
SYSTEM_LOGIN_RESULT = 'system_login_result', |
||||
SYSTEM_SMS_CHANNEL_CODE = 'system_sms_channel_code', |
||||
SYSTEM_SMS_TEMPLATE_TYPE = 'system_sms_template_type', |
||||
SYSTEM_SMS_SEND_STATUS = 'system_sms_send_status', |
||||
SYSTEM_SMS_RECEIVE_STATUS = 'system_sms_receive_status', |
||||
SYSTEM_ERROR_CODE_TYPE = 'system_error_code_type', |
||||
SYSTEM_OAUTH2_GRANT_TYPE = 'system_oauth2_grant_type', |
||||
SYSTEM_MAIL_SEND_STATUS = 'system_mail_send_status', |
||||
SYSTEM_NOTIFY_TEMPLATE_TYPE = 'system_notify_template_type', |
||||
INFRA_BOOLEAN_STRING = 'infra_boolean_string', |
||||
} |
@ -1,42 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { formSchema } from './area.data' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { getAreaByIp } from '@/api/system/area' |
||||
|
||||
defineOptions({ name: 'SystemAreaModal' }) |
||||
|
||||
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ |
||||
labelWidth: 120, |
||||
baseColProps: { span: 24 }, |
||||
schemas: formSchema, |
||||
showActionButtonGroup: false, |
||||
actionColOptions: { span: 23 }, |
||||
}) |
||||
|
||||
const [registerModal, { setModalProps }] = useModalInner(async () => { |
||||
resetFields() |
||||
setModalProps({ confirmLoading: false }) |
||||
}) |
||||
|
||||
async function handleSubmit() { |
||||
try { |
||||
const values = await validate() |
||||
setModalProps({ confirmLoading: true }) |
||||
const res = await getAreaByIp(values.ip) |
||||
if (res) { |
||||
values.result = res |
||||
setFieldsValue({ ...values }) |
||||
} |
||||
} |
||||
finally { |
||||
setModalProps({ confirmLoading: false }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" title="IP 查询" @register="registerModal" @ok="handleSubmit"> |
||||
<BasicForm @register="registerForm" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,29 +0,0 @@
|
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '编号', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
align: 'left', |
||||
}, |
||||
{ |
||||
title: '名字', |
||||
dataIndex: 'name', |
||||
width: 180, |
||||
}, |
||||
] |
||||
|
||||
export const formSchema: FormSchema[] = [ |
||||
{ |
||||
label: 'IP', |
||||
field: 'ip', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '地址', |
||||
field: 'result', |
||||
component: 'Input', |
||||
}, |
||||
] |
@ -1,53 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import AreaModal from './AreaModal.vue' |
||||
import { columns } from './area.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useModal } from '@/components/Modal' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, useTable } from '@/components/Table' |
||||
import { getAreaTree } from '@/api/system/area' |
||||
|
||||
defineOptions({ name: 'SystemArea' }) |
||||
|
||||
const { t } = useI18n() |
||||
|
||||
const [registerModal, { openModal }] = useModal() |
||||
|
||||
const [register, { expandAll, collapseAll, reload }] = useTable({ |
||||
title: 'IP 地区列表', |
||||
api: getAreaTree, |
||||
columns, |
||||
rowKey: 'id', |
||||
isTreeTable: true, |
||||
pagination: false, |
||||
striped: false, |
||||
useSearchForm: false, |
||||
showTableSetting: true, |
||||
bordered: true, |
||||
showIndexColumn: false, |
||||
canResize: true, |
||||
}) |
||||
|
||||
function handleCreate() { |
||||
openModal(true, { isUpdate: false }) |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div class="p-4"> |
||||
<BasicTable @register="register"> |
||||
<template #toolbar> |
||||
<a-button type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
IP 查询 |
||||
</a-button> |
||||
<a-button @click="expandAll"> |
||||
{{ t('component.tree.expandAll') }} |
||||
</a-button> |
||||
<a-button @click="collapseAll"> |
||||
{{ t('component.tree.unExpandAll') }} |
||||
</a-button> |
||||
</template> |
||||
</BasicTable> |
||||
<AreaModal @register="registerModal" @success="reload()" /> |
||||
</div> |
||||
</template> |
@ -1,102 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { watch } from 'vue' |
||||
import DictDataModal from './DictDataModal.vue' |
||||
import { dataColumns, dataSearchFormSchema } from './dict.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { useModal } from '@/components/Modal' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import { deleteDictData, getDictDataPage } from '@/api/system/dict/data' |
||||
|
||||
defineOptions({ name: 'SystemDictData' }) |
||||
|
||||
const props = defineProps({ |
||||
searchInfo: { |
||||
type: Object as PropType<Recordable>, |
||||
default: () => ({}), |
||||
}, |
||||
}) |
||||
|
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const [registerModal, { openModal }] = useModal() |
||||
|
||||
const [registerTable, { reload }] = useTable({ |
||||
title: '字典数据列表', |
||||
api: getDictDataPage, |
||||
columns: dataColumns, |
||||
formConfig: { |
||||
labelWidth: 120, |
||||
schemas: dataSearchFormSchema, |
||||
autoSubmitOnEnter: true, |
||||
}, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 140, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
function handleCreate() { |
||||
openModal(true, { |
||||
record: props.searchInfo.dictType, |
||||
isUpdate: false, |
||||
}) |
||||
} |
||||
|
||||
function handleEdit(record: Recordable) { |
||||
openModal(true, { record, isUpdate: true }) |
||||
} |
||||
|
||||
async function handleDelete(record: Recordable) { |
||||
await deleteDictData(record.id) |
||||
createMessage.success(t('common.delSuccessText')) |
||||
reload() |
||||
} |
||||
|
||||
watch( |
||||
() => props.searchInfo, |
||||
(val) => { |
||||
val && reload() |
||||
}, |
||||
{ deep: true }, |
||||
) |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable :search-info="searchInfo" @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:dict:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
{{ t('action.create') }} |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:dict:update', onClick: handleEdit.bind(null, record) }, |
||||
{ |
||||
icon: IconEnum.DELETE, |
||||
danger: true, |
||||
label: t('action.delete'), |
||||
auth: 'system:dict:delete', |
||||
popConfirm: { |
||||
title: t('common.delMessage'), |
||||
placement: 'left', |
||||
confirm: handleDelete.bind(null, record), |
||||
}, |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<DictDataModal @register="registerModal" @success="reload()" /> |
||||
</div> |
||||
</template> |
@ -1,63 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref, unref } from 'vue' |
||||
import { dataFormSchema } from './dict.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { createDictData, getDictData, updateDictData } from '@/api/system/dict/data' |
||||
|
||||
defineOptions({ name: 'SystemDictDataModal' }) |
||||
|
||||
const emit = defineEmits(['success', 'register']) |
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const isUpdate = ref(true) |
||||
|
||||
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ |
||||
labelWidth: 120, |
||||
baseColProps: { span: 24 }, |
||||
schemas: dataFormSchema, |
||||
showActionButtonGroup: false, |
||||
actionColOptions: { span: 23 }, |
||||
}) |
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { |
||||
resetFields() |
||||
setModalProps({ confirmLoading: false }) |
||||
isUpdate.value = !!data?.isUpdate |
||||
if (unref(isUpdate)) { |
||||
const res = await getDictData(data.record.id) |
||||
setFieldsValue({ ...res }) |
||||
} |
||||
else { |
||||
setFieldsValue({ |
||||
dictType: data.record, |
||||
}) |
||||
} |
||||
}) |
||||
|
||||
async function handleSubmit() { |
||||
try { |
||||
const values = await validate() as any |
||||
setModalProps({ confirmLoading: true }) |
||||
if (unref(isUpdate)) |
||||
await updateDictData(values) |
||||
else |
||||
await createDictData(values) |
||||
|
||||
closeModal() |
||||
emit('success') |
||||
createMessage.success(t('common.saveSuccessText')) |
||||
} |
||||
finally { |
||||
setModalProps({ confirmLoading: false }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit"> |
||||
<BasicForm @register="registerForm" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,58 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref, unref } from 'vue' |
||||
import { typeFormSchema } from './dict.type' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { createDictType, getDictType, updateDictType } from '@/api/system/dict/type' |
||||
|
||||
defineOptions({ name: 'SystemDictTypeModal' }) |
||||
|
||||
const emit = defineEmits(['success', 'register']) |
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const isUpdate = ref(true) |
||||
|
||||
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ |
||||
labelWidth: 120, |
||||
baseColProps: { span: 24 }, |
||||
schemas: typeFormSchema, |
||||
showActionButtonGroup: false, |
||||
actionColOptions: { span: 23 }, |
||||
}) |
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { |
||||
resetFields() |
||||
setModalProps({ confirmLoading: false }) |
||||
isUpdate.value = !!data?.isUpdate |
||||
if (unref(isUpdate)) { |
||||
const res = await getDictType(data.record.id) |
||||
setFieldsValue({ ...res }) |
||||
} |
||||
}) |
||||
|
||||
async function handleSubmit() { |
||||
try { |
||||
const values = await validate() as any |
||||
setModalProps({ confirmLoading: true }) |
||||
if (unref(isUpdate)) |
||||
await updateDictType(values) |
||||
else |
||||
await createDictType(values) |
||||
|
||||
closeModal() |
||||
emit('success') |
||||
createMessage.success(t('common.saveSuccessText')) |
||||
} |
||||
finally { |
||||
setModalProps({ confirmLoading: false }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit"> |
||||
<BasicForm @register="registerForm" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,206 +0,0 @@
|
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
||||
const options = [ |
||||
{ |
||||
value: '', |
||||
label: '无', |
||||
}, |
||||
{ |
||||
value: 'processing', |
||||
label: '主要', |
||||
}, |
||||
{ |
||||
value: 'success', |
||||
label: '成功', |
||||
}, |
||||
{ |
||||
value: 'default', |
||||
label: '默认', |
||||
}, |
||||
{ |
||||
value: 'warning', |
||||
label: '警告', |
||||
}, |
||||
{ |
||||
value: 'error', |
||||
label: '危险', |
||||
}, |
||||
{ |
||||
value: 'pink', |
||||
label: 'pink', |
||||
}, |
||||
{ |
||||
value: 'red', |
||||
label: 'red', |
||||
}, |
||||
{ |
||||
value: 'orange', |
||||
label: 'orange', |
||||
}, |
||||
{ |
||||
value: 'green', |
||||
label: 'green', |
||||
}, |
||||
{ |
||||
value: 'cyan', |
||||
label: 'cyan', |
||||
}, |
||||
{ |
||||
value: 'blue', |
||||
label: 'blue', |
||||
}, |
||||
{ |
||||
value: 'purple', |
||||
label: 'purple', |
||||
}, |
||||
] |
||||
|
||||
function previewOptions() { |
||||
return options.map((option) => { |
||||
const { value, label } = option |
||||
if (value === '') |
||||
return option |
||||
|
||||
return { |
||||
label: useRender.renderTag(label, value), |
||||
value, |
||||
} |
||||
}) |
||||
} |
||||
|
||||
export const dataColumns: BasicColumn[] = [ |
||||
{ |
||||
title: '字典编码', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '字典标签', |
||||
dataIndex: 'label', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '字典键值', |
||||
dataIndex: 'value', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '字典排序', |
||||
dataIndex: 'sort', |
||||
width: 120, |
||||
}, |
||||
{ |
||||
title: '状态', |
||||
dataIndex: 'status', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.COMMON_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '颜色类型', |
||||
dataIndex: 'colorType', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: 'CSS Class', |
||||
dataIndex: 'cssClass', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '备注', |
||||
dataIndex: 'remark', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const dataSearchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '字典标签', |
||||
field: 'label', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const dataFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '编号', |
||||
field: 'id', |
||||
show: false, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '字典类型', |
||||
field: 'dictType', |
||||
required: true, |
||||
component: 'Input', |
||||
dynamicDisabled: ({ values }) => !!values.dictType, |
||||
}, |
||||
{ |
||||
label: '数据标签', |
||||
field: 'label', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '数据键值', |
||||
field: 'value', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '显示排序', |
||||
field: 'sort', |
||||
required: true, |
||||
defaultValue: 0, |
||||
component: 'InputNumber', |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '颜色类型', |
||||
field: 'colorType', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: previewOptions(), |
||||
}, |
||||
}, |
||||
{ |
||||
label: 'CSS Class', |
||||
field: 'cssClass', |
||||
component: 'Input', |
||||
helpMessage: '输入hex模式的颜色, 例如#108ee9', |
||||
rules: [{ required: false, message: '输入正确的16进制颜色', pattern: /^#([0-9a-fA-F]{3}){1,2}$/, trigger: 'blur' }], |
||||
}, |
||||
{ |
||||
label: '备注', |
||||
field: 'remark', |
||||
component: 'InputTextArea', |
||||
}, |
||||
] |
@ -1,89 +0,0 @@
|
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
||||
export const typeColumns: BasicColumn[] = [ |
||||
{ |
||||
title: '字典编号', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '字典名称', |
||||
dataIndex: 'name', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '状态', |
||||
dataIndex: 'status', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.COMMON_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '备注', |
||||
dataIndex: 'remark', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const typeSearchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '字典名称', |
||||
field: 'name', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const typeFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '编号', |
||||
field: 'id', |
||||
show: false, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '字典名称', |
||||
field: 'name', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '字典类型', |
||||
field: 'type', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '备注', |
||||
field: 'remark', |
||||
component: 'InputTextArea', |
||||
}, |
||||
] |
@ -1,90 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { reactive } from 'vue' |
||||
import DictData from './DictData.vue' |
||||
import DictTypeModal from './DictTypeModal.vue' |
||||
import { typeColumns, typeSearchFormSchema } from './dict.type' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { useModal } from '@/components/Modal' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import { deleteDictType, getDictTypePage } from '@/api/system/dict/type' |
||||
|
||||
defineOptions({ name: 'SystemDict' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const [registerModal, { openModal }] = useModal() |
||||
const searchInfo = reactive<Recordable>({}) |
||||
|
||||
const [registerTable, { reload }] = useTable({ |
||||
title: '字典分类列表', |
||||
api: getDictTypePage, |
||||
columns: typeColumns, |
||||
formConfig: { |
||||
labelWidth: 120, |
||||
schemas: typeSearchFormSchema, |
||||
}, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 140, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
function handleRowClick(record) { |
||||
searchInfo.dictType = record.type |
||||
} |
||||
|
||||
function handleCreate() { |
||||
openModal(true, { isUpdate: false }) |
||||
} |
||||
|
||||
function handleEdit(record: Recordable) { |
||||
openModal(true, { record, isUpdate: true }) |
||||
} |
||||
|
||||
async function handleDelete(record: Recordable) { |
||||
await deleteDictType(record.id) |
||||
createMessage.success(t('common.delSuccessText')) |
||||
reload() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div class="flex"> |
||||
<BasicTable class="w-1/2" @register="registerTable" @row-click="handleRowClick"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:dict:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
{{ t('action.create') }} |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:dict:update', onClick: handleEdit.bind(null, record) }, |
||||
{ |
||||
icon: IconEnum.DELETE, |
||||
danger: true, |
||||
label: t('action.delete'), |
||||
auth: 'system:dict:delete', |
||||
popConfirm: { |
||||
title: t('common.delMessage'), |
||||
placement: 'left', |
||||
confirm: handleDelete.bind(null, record), |
||||
}, |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<DictData class="w-1/2" :search-info="searchInfo" /> |
||||
<DictTypeModal @register="registerModal" @success="reload()" /> |
||||
</div> |
||||
</template> |
@ -1,58 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref, unref } from 'vue' |
||||
import { formSchema } from './errorCode.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { createErrorCode, getErrorCode, updateErrorCode } from '@/api/system/errorCode' |
||||
|
||||
defineOptions({ name: 'SystemErrorCodeModal' }) |
||||
|
||||
const emit = defineEmits(['success', 'register']) |
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const isUpdate = ref(true) |
||||
|
||||
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 }) |
||||
isUpdate.value = !!data?.isUpdate |
||||
if (unref(isUpdate)) { |
||||
const res = await getErrorCode(data.record.id) |
||||
setFieldsValue({ ...res }) |
||||
} |
||||
}) |
||||
|
||||
async function handleSubmit() { |
||||
try { |
||||
const values = await validate() as any |
||||
setModalProps({ confirmLoading: true }) |
||||
if (unref(isUpdate)) |
||||
await updateErrorCode(values) |
||||
else |
||||
await createErrorCode(values) |
||||
|
||||
closeModal() |
||||
emit('success') |
||||
createMessage.success(t('common.saveSuccessText')) |
||||
} |
||||
finally { |
||||
setModalProps({ confirmLoading: false }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit"> |
||||
<BasicForm @register="registerForm" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,115 +0,0 @@
|
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '编号', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '类型', |
||||
dataIndex: 'type', |
||||
width: 80, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_ERROR_CODE_TYPE) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '应用名', |
||||
dataIndex: 'applicationName', |
||||
width: 200, |
||||
}, |
||||
{ |
||||
title: '错误码编码', |
||||
dataIndex: 'code', |
||||
width: 120, |
||||
}, |
||||
{ |
||||
title: '错误码提示', |
||||
dataIndex: 'message', |
||||
width: 300, |
||||
}, |
||||
{ |
||||
title: '备注', |
||||
dataIndex: 'memo', |
||||
width: 200, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '错误码类型', |
||||
field: 'type', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.SYSTEM_ERROR_CODE_TYPE), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '应用名', |
||||
field: 'applicationName', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '错误码编码', |
||||
field: 'code', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '错误码提示', |
||||
field: 'message', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '创建时间', |
||||
field: 'createTime', |
||||
component: 'RangePicker', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const formSchema: FormSchema[] = [ |
||||
{ |
||||
label: '编号', |
||||
field: 'id', |
||||
show: false, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '应用名', |
||||
field: 'applicationName', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '错误码编码', |
||||
field: 'code', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '错误码提示', |
||||
field: 'message', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '备注', |
||||
field: 'memo', |
||||
component: 'InputTextArea', |
||||
}, |
||||
] |
@ -1,94 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import ErrorCodeModal from './ErrorCodeModal.vue' |
||||
import { columns, searchFormSchema } from './errorCode.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { useModal } from '@/components/Modal' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import type { ErrorCodePageReqVO } from '@/api/system/errorCode' |
||||
import { deleteErrorCode, excelErrorCode, getErrorCodePage } from '@/api/system/errorCode' |
||||
|
||||
defineOptions({ name: 'SystemErrorCode' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createConfirm, createMessage } = useMessage() |
||||
const [registerModal, { openModal }] = useModal() |
||||
const [registerTable, { getForm, reload }] = useTable({ |
||||
title: '错误码列表', |
||||
api: getErrorCodePage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 140, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
function handleCreate() { |
||||
openModal(true, { isUpdate: false }) |
||||
} |
||||
|
||||
function handleEdit(record: Recordable) { |
||||
openModal(true, { record, isUpdate: true }) |
||||
} |
||||
|
||||
async function handleExport() { |
||||
createConfirm({ |
||||
title: t('common.exportTitle'), |
||||
iconType: 'warning', |
||||
content: t('common.exportMessage'), |
||||
async onOk() { |
||||
await excelErrorCode(getForm().getFieldsValue() as ErrorCodePageReqVO) |
||||
createMessage.success(t('common.exportSuccessText')) |
||||
}, |
||||
}) |
||||
} |
||||
|
||||
async function handleDelete(record: Recordable) { |
||||
await deleteErrorCode(record.id) |
||||
createMessage.success(t('common.delSuccessText')) |
||||
reload() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:error-code:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
{{ t('action.create') }} |
||||
</a-button> |
||||
<a-button v-auth="['system:error-code:export']" :pre-icon="IconEnum.EXPORT" @click="handleExport"> |
||||
{{ t('action.export') }} |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:error-code:update', onClick: handleEdit.bind(null, record) }, |
||||
{ |
||||
icon: IconEnum.DELETE, |
||||
danger: true, |
||||
label: t('action.delete'), |
||||
auth: 'system:error-code:delete', |
||||
popConfirm: { |
||||
title: t('common.delMessage'), |
||||
placement: 'left', |
||||
confirm: handleDelete.bind(null, record), |
||||
}, |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<ErrorCodeModal @register="registerModal" @success="reload()" /> |
||||
</div> |
||||
</template> |
@ -1,46 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { columns, searchFormSchema } from './loginLog.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { BasicTable, useTable } from '@/components/Table' |
||||
import type { LoginLogReqVO } from '@/api/system/loginLog' |
||||
import { exportLoginLog, getLoginLogPage } from '@/api/system/loginLog' |
||||
|
||||
defineOptions({ name: 'SystemLoginLog' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createConfirm, createMessage } = useMessage() |
||||
const [registerTable, { getForm }] = useTable({ |
||||
title: '登录日志列表', |
||||
api: getLoginLogPage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
}) |
||||
|
||||
async function handleExport() { |
||||
createConfirm({ |
||||
title: t('common.exportTitle'), |
||||
iconType: 'warning', |
||||
content: t('common.exportMessage'), |
||||
async onOk() { |
||||
await exportLoginLog(getForm().getFieldsValue() as LoginLogReqVO) |
||||
createMessage.success(t('common.exportSuccessText')) |
||||
}, |
||||
}) |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:login-log:export']" @click="handleExport"> |
||||
{{ t('action.export') }} |
||||
</a-button> |
||||
</template> |
||||
</BasicTable> |
||||
</div> |
||||
</template> |
@ -1,83 +0,0 @@
|
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE } from '@/utils/dict' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '访问编号', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '日志类型', |
||||
dataIndex: 'logType', |
||||
width: 120, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_LOGIN_TYPE) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '用户名称', |
||||
dataIndex: 'username', |
||||
width: 120, |
||||
}, |
||||
{ |
||||
title: '登录地址', |
||||
dataIndex: 'userIp', |
||||
width: 120, |
||||
}, |
||||
{ |
||||
title: 'userAgent', |
||||
dataIndex: 'userAgent', |
||||
width: 400, |
||||
}, |
||||
{ |
||||
title: '结果', |
||||
dataIndex: 'result', |
||||
width: 100, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_LOGIN_RESULT) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '登录日期', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '登录地址', |
||||
field: 'userIp', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '用户名称', |
||||
field: 'username', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '结果', |
||||
field: 'result', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: [ |
||||
{ label: '成功', value: 'true', key: 'true' }, |
||||
{ label: '失败', value: 'false', key: 'false' }, |
||||
], |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '登录时间', |
||||
field: 'createTime', |
||||
component: 'RangePicker', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
@ -1,58 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref, unref } from 'vue' |
||||
import { formSchema } from './account.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { createMailAccount, getMailAccount, updateMailAccount } from '@/api/system/mail/account' |
||||
|
||||
defineOptions({ name: 'SystemMailAccountModal' }) |
||||
|
||||
const emit = defineEmits(['success', 'register']) |
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const isUpdate = ref(true) |
||||
|
||||
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 }) |
||||
isUpdate.value = !!data?.isUpdate |
||||
if (unref(isUpdate)) { |
||||
const res = await getMailAccount(data.record.id) |
||||
setFieldsValue({ ...res }) |
||||
} |
||||
}) |
||||
|
||||
async function handleSubmit() { |
||||
try { |
||||
const values = await validate() |
||||
setModalProps({ confirmLoading: true }) |
||||
if (unref(isUpdate)) |
||||
await updateMailAccount(values) |
||||
else |
||||
await createMailAccount(values) |
||||
|
||||
closeModal() |
||||
emit('success') |
||||
createMessage.success(t('common.saveSuccessText')) |
||||
} |
||||
finally { |
||||
setModalProps({ confirmLoading: false }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit"> |
||||
<BasicForm @register="registerForm" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,121 +0,0 @@
|
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '编号', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '邮箱', |
||||
dataIndex: 'mail', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '用户名', |
||||
dataIndex: 'username', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: 'SMTP 服务器域名', |
||||
dataIndex: 'host', |
||||
width: 120, |
||||
}, |
||||
{ |
||||
title: 'SMTP 服务器端口', |
||||
dataIndex: 'port', |
||||
width: 120, |
||||
}, |
||||
{ |
||||
title: '是否开启 SSL', |
||||
dataIndex: 'sslEnable', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.INFRA_BOOLEAN_STRING) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '邮箱', |
||||
field: 'mail', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '用户名', |
||||
field: 'username', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const formSchema: FormSchema[] = [ |
||||
{ |
||||
label: '编号', |
||||
field: 'id', |
||||
show: false, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '邮箱', |
||||
field: 'mail', |
||||
required: true, |
||||
component: 'Input', |
||||
helpMessage: '填写发件邮箱地址', |
||||
rules: [ |
||||
{ |
||||
required: true, |
||||
message: '请输入正确的邮箱地址', |
||||
pattern: /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/, |
||||
trigger: 'blur', |
||||
}, |
||||
], |
||||
}, |
||||
{ |
||||
label: '用户名', |
||||
field: 'username', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '密码/授权码', |
||||
field: 'password', |
||||
required: true, |
||||
component: 'InputPassword', |
||||
helpMessage: '填写邮件密码, 部分邮件商需要填写授权码', |
||||
}, |
||||
{ |
||||
label: 'SMTP 服务器域名', |
||||
field: 'host', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: 'SMTP 服务器端口', |
||||
field: 'port', |
||||
required: true, |
||||
component: 'InputNumber', |
||||
}, |
||||
{ |
||||
label: '是否开启 SSL', |
||||
field: 'sslEnable', |
||||
required: true, |
||||
defaultValue: false, |
||||
component: 'RadioButtonGroup', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING, 'boolean'), |
||||
}, |
||||
}, |
||||
] |
@ -1,78 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import AccountModal from './AccountModal.vue' |
||||
import { columns, searchFormSchema } from './account.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { useModal } from '@/components/Modal' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import { deleteMailAccount, getMailAccountPage } from '@/api/system/mail/account' |
||||
|
||||
defineOptions({ name: 'SystemMailAccount' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const [registerModal, { openModal }] = useModal() |
||||
const [registerTable, { reload }] = useTable({ |
||||
title: '邮件列表', |
||||
api: getMailAccountPage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 140, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
function handleCreate() { |
||||
openModal(true, { isUpdate: false }) |
||||
} |
||||
|
||||
function handleEdit(record: Recordable) { |
||||
openModal(true, { record, isUpdate: true }) |
||||
} |
||||
|
||||
async function handleDelete(record: Recordable) { |
||||
await deleteMailAccount(record.id) |
||||
createMessage.success(t('common.delSuccessText')) |
||||
reload() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:mail-account:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
{{ t('action.create') }} |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:mail-account:update', onClick: handleEdit.bind(null, record) }, |
||||
{ |
||||
icon: IconEnum.DELETE, |
||||
danger: true, |
||||
label: t('action.delete'), |
||||
auth: 'system:mail-account:delete', |
||||
popConfirm: { |
||||
title: t('common.delMessage'), |
||||
placement: 'left', |
||||
confirm: handleDelete.bind(null, record), |
||||
}, |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<AccountModal @register="registerModal" @success="reload()" /> |
||||
</div> |
||||
</template> |
@ -1,28 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref } from 'vue' |
||||
import { logSchema } from './mailLog.data' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { Description, useDescription } from '@/components/Description/index' |
||||
|
||||
defineOptions({ name: 'MailLogModal' }) |
||||
|
||||
const logData = ref() |
||||
const [registerModalInner, { closeModal }] = useModalInner((record: Recordable) => { |
||||
logData.value = record |
||||
}) |
||||
|
||||
const [registerDescription] = useDescription({ |
||||
column: 1, |
||||
schema: logSchema, |
||||
data: logData, |
||||
labelStyle: { |
||||
width: '100px', |
||||
}, |
||||
}) |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" title="发送邮件详情" width="800px" @register="registerModalInner" @ok="closeModal"> |
||||
<Description @register="registerDescription" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,55 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { columns, searchFormSchema } from './mailLog.data' |
||||
import MailLogModal from './MailLogModal.vue' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import { getMailAccountPage } from '@/api/system/mail/log' |
||||
import { useModal } from '@/components/Modal' |
||||
|
||||
defineOptions({ name: 'SystemOperateLog' }) |
||||
|
||||
const { t } = useI18n() |
||||
const [registerTable] = useTable({ |
||||
title: '邮件日志列表', |
||||
api: getMailAccountPage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 140, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
const [registerModal, { openModal }] = useModal() |
||||
|
||||
function handleShowInfo(record: Recordable) { |
||||
openModal(true, record) |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ |
||||
icon: IconEnum.VIEW, |
||||
label: t('action.detail'), |
||||
onClick: handleShowInfo.bind(null, record), |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<MailLogModal @register="registerModal" /> |
||||
</div> |
||||
</template> |
@ -1,192 +0,0 @@
|
||||
import { h } from 'vue' |
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
import { getSimpleMailAccountList } from '@/api/system/mail/account' |
||||
import type { DescItem } from '@/components/Description/index' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '编号', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '接收邮箱', |
||||
dataIndex: 'toMail', |
||||
width: 200, |
||||
}, |
||||
{ |
||||
title: '邮件标题', |
||||
dataIndex: 'templateTitle', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '发送状态', |
||||
dataIndex: 'sendStatus', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_MAIL_SEND_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '邮箱账号', |
||||
dataIndex: 'fromMail', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '模板编号', |
||||
dataIndex: 'templateId', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '发送时间', |
||||
dataIndex: 'sendTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '接收邮箱', |
||||
field: 'toMail', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '邮箱账号', |
||||
field: 'accountId', |
||||
component: 'ApiSelect', |
||||
componentProps: { |
||||
api: () => getSimpleMailAccountList(), |
||||
labelField: 'mail', |
||||
valueField: 'id', |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '模板编号', |
||||
field: 'templateId', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '发送状态', |
||||
field: 'sendStatus', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.SYSTEM_MAIL_SEND_STATUS), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '用户编号', |
||||
field: 'userId', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '用户类型', |
||||
field: 'userType', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.USER_TYPE), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '发送时间', |
||||
field: 'sendTime', |
||||
component: 'RangePicker', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const logSchema: DescItem[] = [ |
||||
{ |
||||
field: 'sendStatus', |
||||
label: '发送状态', |
||||
labelMinWidth: 80, |
||||
render(value) { |
||||
return useRender.renderDict(value, DICT_TYPE.SYSTEM_MAIL_SEND_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'sendException', |
||||
label: '异常信息', |
||||
labelMinWidth: 80, |
||||
show: data => data && data.sendException && data.sendException.length > 0, |
||||
render(value) { |
||||
return h('span', { style: { fontWeight: 'bold' } }, value) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'sendTime', |
||||
label: '发送时间', |
||||
render(value) { |
||||
return useRender.renderDate(value) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'userId', |
||||
label: '用户类型', |
||||
render(_, data) { |
||||
const { userId, userType } = data |
||||
const uidTag = useRender.renderTag(`uid: ${userId}`) |
||||
const typeTag = useRender.renderDict(userType, DICT_TYPE.USER_TYPE) |
||||
return h('span', {}, [typeTag, uidTag]) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'fromMail', |
||||
label: '发件邮箱', |
||||
}, |
||||
{ |
||||
field: 'toMail', |
||||
label: '收件邮箱', |
||||
}, |
||||
{ |
||||
field: 'templateNickname', |
||||
label: '发件昵称', |
||||
}, |
||||
{ |
||||
field: 'templateTitle', |
||||
label: '邮件标题', |
||||
}, |
||||
{ |
||||
field: 'templateContent', |
||||
label: '邮件内容', |
||||
render(value) { |
||||
return h('div', { innerHTML: value }) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'templateParams', |
||||
label: '邮件参数', |
||||
render(value) { |
||||
return useRender.renderJsonPreview(value) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'sendMessageId', |
||||
label: '返回ID', |
||||
}, |
||||
{ |
||||
field: 'templateCode', |
||||
label: '模板编码', |
||||
}, |
||||
{ |
||||
field: 'templateId', |
||||
label: '模板编号', |
||||
}, |
||||
{ |
||||
field: 'createTime', |
||||
label: '记录时间', |
||||
render(value) { |
||||
return useRender.renderDate(value) |
||||
}, |
||||
}, |
||||
] |
@ -1,107 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { baseSendSchemas, keyPrefix } from './template.data' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import type { FormSchema } from '@/components/Form' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { sendMail } from '@/api/system/mail/template' |
||||
import type { MailTemplate } from '@/api/system/mail/template' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
|
||||
defineOptions({ name: 'SendMailModal' }) |
||||
|
||||
const [register, { setFieldsValue, getFieldsValue, validateFields, resetFields, clearValidate, appendSchemaByField, removeSchemaByField }] |
||||
= useForm({ |
||||
labelWidth: 120, |
||||
schemas: baseSendSchemas, |
||||
baseColProps: { |
||||
span: 24, |
||||
}, |
||||
showActionButtonGroup: false, |
||||
}) |
||||
|
||||
// 存储动态生成的字段信息 后续需要进行移除 |
||||
let dyFields: string[] = [] |
||||
|
||||
const [innerRegister, { changeLoading, changeOkLoading, closeModal }] = useModalInner(async (data: MailTemplate) => { |
||||
// 打开时进行清空 |
||||
await resetForm() |
||||
const dyschemas: FormSchema[] = [] |
||||
data.params.forEach((item) => { |
||||
// 这里加上前缀 防止和content/mail字段重名 |
||||
const field = keyPrefix + item |
||||
const dySchema: FormSchema = { |
||||
field, |
||||
label: `参数{${item}} `, |
||||
component: 'Input', |
||||
componentProps: { |
||||
placeholder: `输入{${item}}`, |
||||
}, |
||||
required: true, |
||||
} |
||||
dyschemas.push(dySchema) |
||||
dyFields.push(field) |
||||
}) |
||||
setFieldsValue(data) |
||||
// 添加动态参数到末尾 |
||||
appendSchemaByField(dyschemas, undefined) |
||||
}) |
||||
|
||||
function modalLoading(status: boolean) { |
||||
changeOkLoading(status) |
||||
changeLoading(status) |
||||
} |
||||
|
||||
/** |
||||
* 移除动态生成的表单元素 |
||||
*/ |
||||
async function removeDySchemas() { |
||||
await removeSchemaByField(dyFields) |
||||
dyFields = [] |
||||
} |
||||
|
||||
const { createMessage } = useMessage() |
||||
async function submit() { |
||||
try { |
||||
modalLoading(true) |
||||
await validateFields() |
||||
const fields = getFieldsValue() |
||||
const data = { |
||||
mail: fields.mail, |
||||
templateCode: fields.code, |
||||
templateParams: {}, |
||||
} |
||||
Object.keys(fields).forEach((key) => { |
||||
// 这几个是固定的字段 不用处理 |
||||
const fixedKeys = ['mail', 'code', 'content'] |
||||
if (fixedKeys.includes(key)) |
||||
return |
||||
|
||||
// 去掉前缀后的key |
||||
const realKey = key.split(keyPrefix)[1] |
||||
data.templateParams[realKey] = fields[key] |
||||
}) |
||||
await sendMail(data) |
||||
createMessage.success(`发送邮件到[${fields.mail}]成功`) |
||||
closeModal() |
||||
} |
||||
catch (e) { |
||||
} |
||||
finally { |
||||
modalLoading(false) |
||||
} |
||||
} |
||||
|
||||
async function resetForm() { |
||||
// 这里需要清空动态表单 |
||||
await removeDySchemas() |
||||
// 清除上一次的表单校验和参数 |
||||
await resetFields() |
||||
await clearValidate() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" title="发送邮件" width="600px" @register="innerRegister" @ok="submit" @cancel="resetForm"> |
||||
<BasicForm @register="register" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,58 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref, unref } from 'vue' |
||||
import { formSchema } from './template.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { createMailTemplate, getMailTemplate, updateMailTemplate } from '@/api/system/mail/template' |
||||
|
||||
defineOptions({ name: 'SystemMailTemplateModal' }) |
||||
|
||||
const emit = defineEmits(['success', 'register']) |
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const isUpdate = ref(true) |
||||
|
||||
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ |
||||
labelWidth: 100, |
||||
baseColProps: { span: 24 }, |
||||
schemas: formSchema, |
||||
showActionButtonGroup: false, |
||||
actionColOptions: { span: 23 }, |
||||
}) |
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { |
||||
resetFields() |
||||
setModalProps({ confirmLoading: false }) |
||||
isUpdate.value = !!data?.isUpdate |
||||
if (unref(isUpdate)) { |
||||
const res = await getMailTemplate(data.record.id) |
||||
setFieldsValue({ ...res }) |
||||
} |
||||
}) |
||||
|
||||
async function handleSubmit() { |
||||
try { |
||||
const values = await validate() |
||||
setModalProps({ confirmLoading: true }) |
||||
if (unref(isUpdate)) |
||||
await updateMailTemplate(values) |
||||
else |
||||
await createMailTemplate(values) |
||||
|
||||
closeModal() |
||||
emit('success') |
||||
createMessage.success(t('common.saveSuccessText')) |
||||
} |
||||
finally { |
||||
setModalProps({ confirmLoading: false }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit"> |
||||
<BasicForm @register="registerForm" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,96 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import TemplateModal from './TemplateModal.vue' |
||||
import SendMailModal from './SendMailModal.vue' |
||||
import { columns, searchFormSchema } from './template.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { useModal } from '@/components/Modal' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import { deleteMailTemplate, getMailTemplatePage } from '@/api/system/mail/template' |
||||
|
||||
defineOptions({ name: 'SystemMailTemplate' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const [registerTemplateModal, { openModal }] = useModal() |
||||
const [registerSendModal, { openModal: openSendModal }] = useModal() |
||||
const [registerTable, { reload }] = useTable({ |
||||
title: '邮件模板列表', |
||||
api: getMailTemplatePage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 200, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
function handleCreate() { |
||||
openModal(true, { isUpdate: false }) |
||||
} |
||||
|
||||
function handleSend(record: Recordable) { |
||||
openSendModal(true, record) |
||||
} |
||||
|
||||
function handleEdit(record: Recordable) { |
||||
openModal(true, { record, isUpdate: true }) |
||||
} |
||||
|
||||
async function handleDelete(record: Recordable) { |
||||
await deleteMailTemplate(record.id) |
||||
createMessage.success(t('common.delSuccessText')) |
||||
reload() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:mail-template:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
{{ t('action.create') }} |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ |
||||
icon: IconEnum.SEND, |
||||
label: t('action.send'), |
||||
auth: 'system:mail-template:send-mail', |
||||
onClick: handleSend.bind(null, record), |
||||
}, |
||||
{ |
||||
icon: IconEnum.EDIT, |
||||
label: t('action.edit'), |
||||
auth: 'system:mail-template:update', |
||||
onClick: handleEdit.bind(null, record), |
||||
}, |
||||
{ |
||||
icon: IconEnum.DELETE, |
||||
danger: true, |
||||
label: t('action.delete'), |
||||
auth: 'system:mail-template:delete', |
||||
popConfirm: { |
||||
title: t('common.delMessage'), |
||||
placement: 'left', |
||||
confirm: handleDelete.bind(null, record), |
||||
}, |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<TemplateModal @register="registerTemplateModal" @success="reload()" /> |
||||
<SendMailModal @register="registerSendModal" /> |
||||
</div> |
||||
</template> |
@ -1,220 +0,0 @@
|
||||
import { h } from 'vue' |
||||
import { getSimpleMailAccountList } from '@/api/system/mail/account' |
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
import { ScrollContainer } from '@/components/Container' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '模板编码', |
||||
dataIndex: 'code', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '模板名称', |
||||
dataIndex: 'name', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '模板标题', |
||||
dataIndex: 'title', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '模板内容', |
||||
dataIndex: 'content', |
||||
width: 300, |
||||
}, |
||||
{ |
||||
title: '邮箱账号', |
||||
dataIndex: 'accountId', |
||||
width: 120, |
||||
}, |
||||
{ |
||||
title: '发送人名称', |
||||
dataIndex: 'nickname', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '开启状态', |
||||
dataIndex: 'status', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.COMMON_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '模板名称', |
||||
field: 'name', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '模板编码', |
||||
field: 'code', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '发件邮箱', |
||||
field: 'accountId', |
||||
component: 'ApiSelect', |
||||
componentProps: { |
||||
api: () => getSimpleMailAccountList(), |
||||
fieldNames: { |
||||
label: 'mail', |
||||
key: 'id', |
||||
value: 'id', |
||||
}, |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '开启状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '创建时间', |
||||
field: 'createTime', |
||||
component: 'RangePicker', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const formSchema: FormSchema[] = [ |
||||
{ |
||||
label: '编号', |
||||
field: 'id', |
||||
show: false, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '模板名称', |
||||
field: 'name', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '模板编码', |
||||
field: 'code', |
||||
required: true, |
||||
component: 'Input', |
||||
helpMessage: '建议使用下划线/数字/字母命名', |
||||
}, |
||||
{ |
||||
label: '发件邮箱', |
||||
field: 'accountId', |
||||
required: true, |
||||
component: 'ApiSelect', |
||||
componentProps: { |
||||
api: () => getSimpleMailAccountList(), |
||||
fieldNames: { |
||||
label: 'mail', |
||||
key: 'id', |
||||
value: 'id', |
||||
}, |
||||
}, |
||||
}, |
||||
{ |
||||
label: '发送人名称', |
||||
field: 'nickname', |
||||
required: true, |
||||
component: 'Input', |
||||
helpMessage: '发件人的名称, 如:系统发件人', |
||||
}, |
||||
{ |
||||
label: '模板标题', |
||||
field: 'title', |
||||
required: true, |
||||
component: 'Input', |
||||
helpMessage: '邮件的标题', |
||||
}, |
||||
{ |
||||
label: '模板内容', |
||||
field: 'content', |
||||
component: 'Editor', |
||||
required: true, |
||||
helpMessage: '{}括号中的内容作为模板参数', |
||||
}, |
||||
{ |
||||
label: '开启状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
defaultValue: 0, |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '备注', |
||||
field: 'remark', |
||||
component: 'InputTextArea', |
||||
}, |
||||
] |
||||
|
||||
// 发送邮件
|
||||
// 这里加上前缀 防止和表单其他字段重名
|
||||
export const keyPrefix = 'key$-' |
||||
export const baseSendSchemas: FormSchema[] = [ |
||||
{ |
||||
field: 'code', |
||||
label: '编码', |
||||
component: 'Input', |
||||
show: () => false, |
||||
}, |
||||
{ |
||||
field: 'content', |
||||
component: 'Editor', |
||||
label: '模板内容 ', |
||||
required: false, |
||||
defaultValue: '', |
||||
render({ model }) { |
||||
let content: string = model.content |
||||
Object.keys(model).forEach((key) => { |
||||
if (!key.startsWith(keyPrefix)) |
||||
return |
||||
|
||||
const realKey = key.split(keyPrefix)[1] |
||||
content = content.replace(`{${realKey}}`, model[key]) |
||||
}) |
||||
return h(ScrollContainer, { |
||||
innerHTML: content, |
||||
style: { border: '1px solid #e8e8e8', borderRadius: '6px', padding: '10px' }, |
||||
}) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'mail', |
||||
label: '收件邮箱 ', |
||||
component: 'Input', |
||||
componentProps: { |
||||
placeholder: '输入收件邮箱', |
||||
}, |
||||
required: true, |
||||
rules: [ |
||||
{ |
||||
required: true, |
||||
pattern: /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/, |
||||
trigger: 'blur', |
||||
message: '邮箱格式不正确', |
||||
}, |
||||
], |
||||
}, |
||||
] |
@ -1,58 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref, unref } from 'vue' |
||||
import { formSchema } from './notice.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { createNotice, getNotice, updateNotice } from '@/api/system/notice' |
||||
|
||||
defineOptions({ name: 'SystemNoticeModal' }) |
||||
|
||||
const emit = defineEmits(['success', 'register']) |
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const isUpdate = ref(true) |
||||
|
||||
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 }) |
||||
isUpdate.value = !!data?.isUpdate |
||||
if (unref(isUpdate)) { |
||||
const res = await getNotice(data.record.id) |
||||
setFieldsValue({ ...res }) |
||||
} |
||||
}) |
||||
|
||||
async function handleSubmit() { |
||||
try { |
||||
const values = await validate() as any |
||||
setModalProps({ confirmLoading: true }) |
||||
if (unref(isUpdate)) |
||||
await updateNotice(values) |
||||
else |
||||
await createNotice(values) |
||||
|
||||
closeModal() |
||||
emit('success') |
||||
createMessage.success(t('common.saveSuccessText')) |
||||
} |
||||
finally { |
||||
setModalProps({ confirmLoading: false }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit"> |
||||
<BasicForm @register="registerForm" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,78 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import NoticeModal from './NoticeModal.vue' |
||||
import { columns, searchFormSchema } from './notice.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { useModal } from '@/components/Modal' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import { deleteNotice, getNoticePage } from '@/api/system/notice' |
||||
|
||||
defineOptions({ name: 'SystemNotice' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const [registerModal, { openModal }] = useModal() |
||||
const [registerTable, { reload }] = useTable({ |
||||
title: '公告列表', |
||||
api: getNoticePage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 140, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
function handleCreate() { |
||||
openModal(true, { isUpdate: false }) |
||||
} |
||||
|
||||
function handleEdit(record: Recordable) { |
||||
openModal(true, { record, isUpdate: true }) |
||||
} |
||||
|
||||
async function handleDelete(record: Recordable) { |
||||
await deleteNotice(record.id) |
||||
createMessage.success(t('common.delSuccessText')) |
||||
reload() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:notice:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
{{ t('action.create') }} |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:notice:update', onClick: handleEdit.bind(null, record) }, |
||||
{ |
||||
icon: IconEnum.DELETE, |
||||
danger: true, |
||||
label: t('action.delete'), |
||||
auth: 'system:notice:delete', |
||||
popConfirm: { |
||||
title: t('common.delMessage'), |
||||
placement: 'left', |
||||
confirm: handleDelete.bind(null, record), |
||||
}, |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<NoticeModal @register="registerModal" @success="reload()" /> |
||||
</div> |
||||
</template> |
@ -1,93 +0,0 @@
|
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '公告编号', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '公告标题', |
||||
dataIndex: 'title', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '公告类型', |
||||
dataIndex: 'type', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_NOTICE_TYPE) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '状态', |
||||
dataIndex: 'status', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.COMMON_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '公告标题', |
||||
field: 'title', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '公告状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const formSchema: FormSchema[] = [ |
||||
{ |
||||
label: '编号', |
||||
field: 'id', |
||||
show: false, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '公告标题', |
||||
field: 'title', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '公告类型', |
||||
field: 'type', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.SYSTEM_NOTICE_TYPE), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '内容', |
||||
field: 'content', |
||||
component: 'Editor', |
||||
}, |
||||
] |
@ -1,27 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref } from 'vue' |
||||
import type { MessageInfo } from './message.data' |
||||
import { infoSchema } from './message.data' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { Description, useDescription } from '@/components/Description/index' |
||||
|
||||
defineOptions({ name: 'MessageInfoModal' }) |
||||
|
||||
const data = ref<MessageInfo>() |
||||
|
||||
const [innerRegister] = useModalInner((value: MessageInfo) => { |
||||
data.value = value |
||||
}) |
||||
|
||||
const [descriptionRegister] = useDescription({ |
||||
column: 1, |
||||
schema: infoSchema, |
||||
data, |
||||
}) |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal title="站内信详情" @register="innerRegister"> |
||||
<Description @register="descriptionRegister" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,96 +0,0 @@
|
||||
import { h } from 'vue' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE } from '@/utils/dict' |
||||
import { JsonPreview } from '@/components/CodeEditor' |
||||
import type { DescItem } from '@/components/Description/index' |
||||
|
||||
// 站内信详情modal
|
||||
export const infoSchema: DescItem[] = [ |
||||
{ |
||||
field: 'id', |
||||
label: '编号', |
||||
labelMinWidth: 50, |
||||
}, |
||||
{ |
||||
field: 'readStatus', |
||||
label: '是否已读', |
||||
render: (value) => { |
||||
return useRender.renderDict(value, DICT_TYPE.INFRA_BOOLEAN_STRING) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'userType', |
||||
label: '用户类型', |
||||
render: (value) => { |
||||
return useRender.renderDict(value, DICT_TYPE.USER_TYPE) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'userType', |
||||
label: '用户编号', |
||||
}, |
||||
{ |
||||
field: 'templateId', |
||||
label: '模板编号', |
||||
}, |
||||
{ |
||||
field: 'templateCode', |
||||
label: '模板编码', |
||||
}, |
||||
{ |
||||
field: 'templateNickname', |
||||
label: '发送人名称', |
||||
}, |
||||
{ |
||||
field: 'templateContent', |
||||
label: '模板内容', |
||||
}, |
||||
{ |
||||
field: 'templateParams', |
||||
label: '模板参数', |
||||
render: (value) => { |
||||
return h(JsonPreview, { data: value }) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'templateType', |
||||
label: '模板类型', |
||||
render: (value) => { |
||||
return useRender.renderDict(value, DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'readTime', |
||||
label: '阅读时间', |
||||
render: (value) => { |
||||
if (!value) |
||||
return useRender.renderTag('未阅读') |
||||
|
||||
return useRender.renderDate(value) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'createTime', |
||||
label: '创建时间', |
||||
render: (value) => { |
||||
return useRender.renderDate(value) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
// 站内信详情
|
||||
export interface MessageInfo { |
||||
userId: number |
||||
userType: number |
||||
templateId: number |
||||
templateCode: string |
||||
templateNickname: string |
||||
templateContent: string |
||||
templateType: number |
||||
templateParams: { [key: string]: string } |
||||
readStatus: boolean |
||||
readTime?: any |
||||
id: number |
||||
createTime: number |
||||
key: string |
||||
} |
@ -1,56 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { columns, searchFormSchema } from './message.data' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import { getNotifyMessagePage } from '@/api/system/notify/message' |
||||
import MessageInfoModal from '@/views/system/notify/components/MessageInfoModal.vue' |
||||
import { useModal } from '@/components/Modal' |
||||
|
||||
defineOptions({ name: 'SystemMessage' }) |
||||
|
||||
const { t } = useI18n() |
||||
|
||||
const [registerTable] = useTable({ |
||||
title: '站内信记录列表', |
||||
api: getNotifyMessagePage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 100, |
||||
title: t('common.action'), |
||||
fixed: 'right', |
||||
key: 'action', |
||||
}, |
||||
}) |
||||
|
||||
const [registerModal, { openModal }] = useModal() |
||||
|
||||
function handleShowInfo(record: Recordable) { |
||||
openModal(true, record) |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ |
||||
label: t('action.detail'), |
||||
icon: IconEnum.LOG, |
||||
onClick: handleShowInfo.bind(null, record), |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<MessageInfoModal @register="registerModal" /> |
||||
</div> |
||||
</template> |
@ -1,204 +0,0 @@
|
||||
import { h } from 'vue' |
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
import { JsonPreview } from '@/components/CodeEditor' |
||||
import type { DescItem } from '@/components/Description/index' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '编号', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '用户编号', |
||||
dataIndex: 'userId', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '用户类型', |
||||
dataIndex: 'userType', |
||||
width: 100, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.USER_TYPE) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '模板编码', |
||||
dataIndex: 'templateCode', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '发送人名称', |
||||
dataIndex: 'templateNickname', |
||||
width: 120, |
||||
}, |
||||
{ |
||||
title: '模版内容', |
||||
dataIndex: 'templateContent', |
||||
width: 240, |
||||
}, |
||||
{ |
||||
title: '模版类型', |
||||
dataIndex: 'templateType', |
||||
width: 140, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '是否已读', |
||||
dataIndex: 'readStatus', |
||||
width: 140, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.INFRA_BOOLEAN_STRING) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '阅读时间', |
||||
dataIndex: 'readTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
if (!text) |
||||
return useRender.renderTag('未阅读') |
||||
|
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '用户编号', |
||||
field: 'userId', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '用户类型', |
||||
field: 'userType', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '模板编码', |
||||
field: 'templateCode', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '模版类型', |
||||
field: 'templateType', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '创建时间', |
||||
field: 'createTime', |
||||
component: 'RangePicker', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
// 站内信详情modal
|
||||
export const infoSchema: DescItem[] = [ |
||||
{ |
||||
field: 'id', |
||||
label: '编号', |
||||
labelMinWidth: 50, |
||||
}, |
||||
{ |
||||
field: 'readStatus', |
||||
label: '是否已读', |
||||
render: (value) => { |
||||
return useRender.renderDict(value, DICT_TYPE.INFRA_BOOLEAN_STRING) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'userType', |
||||
label: '用户类型', |
||||
render: (value) => { |
||||
return useRender.renderDict(value, DICT_TYPE.USER_TYPE) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'userType', |
||||
label: '用户编号', |
||||
}, |
||||
{ |
||||
field: 'templateId', |
||||
label: '模板编号', |
||||
}, |
||||
{ |
||||
field: 'templateCode', |
||||
label: '模板编码', |
||||
}, |
||||
{ |
||||
field: 'templateNickname', |
||||
label: '发送人名称', |
||||
}, |
||||
{ |
||||
field: 'templateContent', |
||||
label: '模板内容', |
||||
}, |
||||
{ |
||||
field: 'templateParams', |
||||
label: '模板参数', |
||||
render: (value) => { |
||||
return h(JsonPreview, { data: value }) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'templateType', |
||||
label: '模板类型', |
||||
render: (value) => { |
||||
return useRender.renderDict(value, DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'readTime', |
||||
label: '阅读时间', |
||||
render: (value) => { |
||||
if (!value) |
||||
return useRender.renderTag('未阅读') |
||||
|
||||
return useRender.renderDate(value) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'createTime', |
||||
label: '创建时间', |
||||
render: (value) => { |
||||
return useRender.renderDate(value) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
// 站内信详情
|
||||
export interface MessageInfo { |
||||
userId: number |
||||
userType: number |
||||
templateId: number |
||||
templateCode: string |
||||
templateNickname: string |
||||
templateContent: string |
||||
templateType: number |
||||
templateParams: { [key: string]: string } |
||||
readStatus: boolean |
||||
readTime?: any |
||||
id: number |
||||
createTime: number |
||||
key: string |
||||
} |
@ -1,125 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { computed } from 'vue' |
||||
import { columns, searchFormSchema } from './my.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import { getMyNotifyMessagePage, updateAllNotifyMessageRead, updateNotifyMessageRead } from '@/api/system/notify/message' |
||||
import MessageInfoModal from '@/views/system/notify/components/MessageInfoModal.vue' |
||||
import { useModal } from '@/components/Modal' |
||||
import { useUserMessageStore } from '@/store/modules/userMessage' |
||||
|
||||
defineOptions({ name: 'SystemMyMessage' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const [registerModal, { openModal }] = useModal() |
||||
const store = useUserMessageStore() |
||||
|
||||
const [registerTable, { getSelectRowKeys, clearSelectedRowKeys, reload }] = useTable({ |
||||
title: '我的站内信列表', |
||||
api: getMyNotifyMessagePage, |
||||
columns, |
||||
formConfig: { labelWidth: 130, schemas: searchFormSchema }, |
||||
rowSelection: { |
||||
type: 'checkbox', |
||||
getCheckboxProps: (record: Recordable) => { |
||||
return { |
||||
// 已读的消息disabled 不可选 |
||||
disabled: record.readStatus, |
||||
} |
||||
}, |
||||
}, |
||||
rowKey: 'id', |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 140, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
/** |
||||
* 已读按钮的disabled 未选中则disabled |
||||
*/ |
||||
const readedDisabled = computed<boolean>(() => { |
||||
return getSelectRowKeys().length === 0 |
||||
}) |
||||
|
||||
function handleUpdateList() { |
||||
const ids = getSelectRowKeys() |
||||
handleUpdate(ids) |
||||
} |
||||
|
||||
async function handleUpdateSingle(record: Recordable) { |
||||
await handleUpdate([record.id]) |
||||
} |
||||
|
||||
function afterRead(msg: string) { |
||||
createMessage.success(msg) |
||||
// 更新未读消息 |
||||
store.updateUnreadCount() |
||||
// 重加载表格 |
||||
reload() |
||||
// 清除选中的行 |
||||
clearSelectedRowKeys() |
||||
} |
||||
|
||||
async function handleUpdate(ids) { |
||||
await updateNotifyMessageRead(ids) |
||||
afterRead('标记已读成功!') |
||||
} |
||||
|
||||
async function handleUpdateAll() { |
||||
await updateAllNotifyMessageRead() |
||||
afterRead('全部已读成功!') |
||||
} |
||||
|
||||
function handleInfo(record: any) { |
||||
openModal(true, record) |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable bordered @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button pre-icon="i-solar:check-read-line-duotone" type="primary" :disabled="readedDisabled" @click="handleUpdateList"> |
||||
标记已读 |
||||
</a-button> |
||||
<a-button pre-icon="i-solar:check-read-linear" type="primary" @click="handleUpdateAll"> |
||||
全部已读 |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<!-- 阻止事件冒泡 勾选框 --> |
||||
<TableAction |
||||
stop-button-propagation |
||||
:actions="[ |
||||
{ |
||||
icon: IconEnum.EDIT, |
||||
label: '已读', |
||||
color: 'warning', |
||||
ifShow: () => { |
||||
return !record.readStatus |
||||
}, |
||||
onClick: handleUpdateSingle.bind(null, record), |
||||
}, |
||||
{ |
||||
icon: IconEnum.LOG, |
||||
label: t('action.detail'), |
||||
onClick: handleInfo.bind(null, record), |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<MessageInfoModal @register="registerModal" /> |
||||
</div> |
||||
</template> |
@ -1,112 +0,0 @@
|
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '发送人', |
||||
dataIndex: 'templateNickname', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '发送时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '类型', |
||||
dataIndex: 'templateType', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '内容', |
||||
dataIndex: 'templateContent', |
||||
width: 300, |
||||
}, |
||||
{ |
||||
title: '是否已读', |
||||
dataIndex: 'readStatus', |
||||
width: 100, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.INFRA_BOOLEAN_STRING) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '是否已读', |
||||
field: 'readStatus', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '发送时间', |
||||
field: 'createTime', |
||||
component: 'RangePicker', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const formSchema: FormSchema[] = [ |
||||
{ |
||||
label: '编号', |
||||
field: 'id', |
||||
show: false, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '模版编码', |
||||
field: 'code', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '模板名称', |
||||
field: 'name', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '发件人名称', |
||||
field: 'nickname', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '模板内容', |
||||
field: 'content', |
||||
required: true, |
||||
component: 'InputTextArea', |
||||
}, |
||||
{ |
||||
label: '类型', |
||||
field: 'type', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '开启状态', |
||||
field: 'status', |
||||
component: 'RadioGroup', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '备注', |
||||
field: 'remark', |
||||
component: 'InputTextArea', |
||||
}, |
||||
] |
@ -1,88 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { reactive, ref } from 'vue' |
||||
import { baseSendSchemas } from './template.data' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import type { FormSchema } from '@/components/Form' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import type { NotifyTemplate, SendNotifyParam } from '@/api/system/notify/template' |
||||
import { sendNotify } from '@/api/system/notify/template' |
||||
|
||||
defineOptions({ name: 'SendNotifyModal' }) |
||||
|
||||
const { createMessage } = useMessage() |
||||
const reactiveSchemas: FormSchema[] = reactive([]) |
||||
const templateCode = ref<string>('') |
||||
|
||||
const [register, { setFieldsValue, getFieldsValue, validateFields, resetFields, clearValidate, setProps }] = useForm({ |
||||
labelWidth: 100, |
||||
baseColProps: { |
||||
span: 24, |
||||
}, |
||||
showActionButtonGroup: false, |
||||
}) |
||||
|
||||
const [innerRegister, { changeLoading, closeModal }] = useModalInner((data: NotifyTemplate) => { |
||||
resetForm() |
||||
data.params.forEach((item) => { |
||||
const dySchema: FormSchema = { |
||||
// 这里加上前缀 防止和content/userId字段重名 |
||||
field: `key-${item}`, |
||||
label: `参数{${item}} `, |
||||
component: 'Input', |
||||
componentProps: { |
||||
placeholder: `输入{${item}}`, |
||||
}, |
||||
required: true, |
||||
} |
||||
reactiveSchemas.push(dySchema) |
||||
}) |
||||
const { content, code } = data |
||||
setFieldsValue({ content }) |
||||
templateCode.value = code |
||||
}) |
||||
|
||||
async function submit() { |
||||
try { |
||||
setProps({ disabled: true }) |
||||
changeLoading(true) |
||||
await validateFields() |
||||
const fields = getFieldsValue() |
||||
const data: SendNotifyParam = { |
||||
userId: fields.userId, |
||||
templateCode: templateCode.value, |
||||
templateParams: {}, |
||||
} |
||||
Object.keys(fields).forEach((key) => { |
||||
if (key === 'content' || key === 'userId') |
||||
return |
||||
|
||||
// 去掉 - 后的key |
||||
const realKey = key.split('-')[1] |
||||
data.templateParams[realKey] = fields[key] |
||||
}) |
||||
await sendNotify(data) |
||||
createMessage.success('发送站内信成功') |
||||
closeModal() |
||||
} |
||||
finally { |
||||
setProps({ disabled: false }) |
||||
changeLoading(false) |
||||
} |
||||
} |
||||
|
||||
function resetForm() { |
||||
// 这里需要每次清空动态表单 |
||||
reactiveSchemas.splice(0, reactiveSchemas.length) |
||||
reactiveSchemas.push(...baseSendSchemas) |
||||
// 清除上一次的表单校验和参数 |
||||
resetFields() |
||||
clearValidate() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" title="发送站内信" @register="innerRegister" @ok="submit"> |
||||
<BasicForm :schemas="reactiveSchemas" @register="register" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,58 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref, unref } from 'vue' |
||||
import { formSchema } from './template.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { createNotifyTemplate, getNotifyTemplate, updateNotifyTemplate } from '@/api/system/notify/template' |
||||
|
||||
defineOptions({ name: 'NotifyTemplateModal' }) |
||||
|
||||
const emit = defineEmits(['success', 'register']) |
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const isUpdate = ref(true) |
||||
|
||||
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 }) |
||||
isUpdate.value = !!data?.isUpdate |
||||
if (unref(isUpdate)) { |
||||
const res = await getNotifyTemplate(data.record.id) |
||||
setFieldsValue({ ...res }) |
||||
} |
||||
}) |
||||
|
||||
async function handleSubmit() { |
||||
try { |
||||
const values = await validate() |
||||
setModalProps({ confirmLoading: true }) |
||||
if (unref(isUpdate)) |
||||
await updateNotifyTemplate(values) |
||||
else |
||||
await createNotifyTemplate(values) |
||||
|
||||
closeModal() |
||||
emit('success') |
||||
createMessage.success(t('common.saveSuccessText')) |
||||
} |
||||
finally { |
||||
setModalProps({ confirmLoading: false }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit"> |
||||
<BasicForm @register="registerForm" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,97 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import TemplateModal from './TemplateModal.vue' |
||||
import { columns, searchFormSchema } from './template.data' |
||||
import SendNotifyModal from './SendNotifyModal.vue' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { useModal } from '@/components/Modal' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import { deleteNotifyTemplate, getNotifyTemplatePage } from '@/api/system/notify/template' |
||||
|
||||
defineOptions({ name: 'SystemMessageTemplate' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const [registerModal, { openModal }] = useModal() |
||||
const [registerSendModal, { openModal: openSendModal }] = useModal() |
||||
|
||||
const [registerTable, { reload }] = useTable({ |
||||
title: '站内信模板列表', |
||||
api: getNotifyTemplatePage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 200, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
function handleCreate() { |
||||
openModal(true, { isUpdate: false }) |
||||
} |
||||
|
||||
function handleEdit(record: Recordable) { |
||||
openModal(true, { record, isUpdate: true }) |
||||
} |
||||
|
||||
function handleSend(record: Recordable) { |
||||
openSendModal(true, record) |
||||
} |
||||
|
||||
async function handleDelete(record: Recordable) { |
||||
await deleteNotifyTemplate(record.id) |
||||
createMessage.success(t('common.delSuccessText')) |
||||
reload() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:notify-template:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
{{ t('action.create') }} |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ |
||||
icon: IconEnum.UPLOAD, |
||||
label: t('action.send'), |
||||
auth: 'system:notify-template:update', |
||||
onClick: handleSend.bind(null, record), |
||||
}, |
||||
{ |
||||
icon: IconEnum.EDIT, |
||||
label: t('action.edit'), |
||||
auth: 'system:notify-template:update', |
||||
onClick: handleEdit.bind(null, record), |
||||
}, |
||||
{ |
||||
icon: IconEnum.DELETE, |
||||
danger: true, |
||||
label: t('action.delete'), |
||||
auth: 'system:notify-template:delete', |
||||
popConfirm: { |
||||
title: t('common.delMessage'), |
||||
placement: 'left', |
||||
confirm: handleDelete.bind(null, record), |
||||
}, |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<TemplateModal @register="registerModal" @success="reload()" /> |
||||
<SendNotifyModal @register="registerSendModal" /> |
||||
</div> |
||||
</template> |
@ -1,181 +0,0 @@
|
||||
import { h } from 'vue' |
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
import { getListSimpleUsers } from '@/api/system/user/index' |
||||
import { ScrollContainer } from '@/components/Container' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '模板编码', |
||||
dataIndex: 'code', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '模板名称', |
||||
dataIndex: 'name', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '类型', |
||||
dataIndex: 'type', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '发送人名称', |
||||
dataIndex: 'nickname', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '模板内容', |
||||
dataIndex: 'content', |
||||
width: 300, |
||||
}, |
||||
{ |
||||
title: '开启状态', |
||||
dataIndex: 'status', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.COMMON_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '备注', |
||||
dataIndex: 'remark', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '模板名称', |
||||
field: 'name', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '模版编码', |
||||
field: 'code', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '创建时间', |
||||
field: 'createTime', |
||||
component: 'RangePicker', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const formSchema: FormSchema[] = [ |
||||
{ |
||||
label: '编号', |
||||
field: 'id', |
||||
show: false, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '模版编码', |
||||
field: 'code', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '模板名称', |
||||
field: 'name', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '发件人名称', |
||||
field: 'nickname', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '模板内容', |
||||
field: 'content', |
||||
required: true, |
||||
component: 'InputTextArea', |
||||
}, |
||||
{ |
||||
label: '类型', |
||||
field: 'type', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '开启状态', |
||||
field: 'status', |
||||
required: true, |
||||
component: 'RadioGroup', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '备注', |
||||
field: 'remark', |
||||
component: 'InputTextArea', |
||||
}, |
||||
] |
||||
|
||||
// 发送站内信
|
||||
// 这里加上前缀 防止和表单其他字段重名
|
||||
export const keyPrefix = 'key$-' |
||||
export const baseSendSchemas: FormSchema[] = [ |
||||
{ |
||||
field: 'content', |
||||
component: 'Editor', |
||||
label: '模板内容 ', |
||||
required: false, |
||||
defaultValue: '', |
||||
render({ model }) { |
||||
let content: string = model.content |
||||
Object.keys(model).forEach((key) => { |
||||
if (!key.startsWith(keyPrefix)) |
||||
return |
||||
|
||||
const realKey = key.split(keyPrefix)[1] |
||||
content = content.replace(`{${realKey}}`, model[key]) |
||||
}) |
||||
return h(ScrollContainer, { |
||||
innerHTML: content, |
||||
style: { border: '1px solid #e8e8e8', borderRadius: '6px', padding: '10px' }, |
||||
}) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'userId', |
||||
component: 'ApiSelect', |
||||
label: '接收人 ', |
||||
required: true, |
||||
componentProps: { |
||||
api: getListSimpleUsers, |
||||
labelField: 'nickname', |
||||
valueField: 'id', |
||||
}, |
||||
}, |
||||
] |
@ -1,58 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref, unref } from 'vue' |
||||
import { formSchema } from './client.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { createOAuth2Client, getOAuth2Client, updateOAuth2Client } from '@/api/system/oauth2/client' |
||||
|
||||
defineOptions({ name: 'SystemClientModal' }) |
||||
|
||||
const emit = defineEmits(['success', 'register']) |
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const isUpdate = ref(true) |
||||
|
||||
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ |
||||
labelWidth: 160, |
||||
baseColProps: { span: 24 }, |
||||
schemas: formSchema, |
||||
showActionButtonGroup: false, |
||||
actionColOptions: { span: 23 }, |
||||
}) |
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { |
||||
resetFields() |
||||
setModalProps({ confirmLoading: false }) |
||||
isUpdate.value = !!data?.isUpdate |
||||
if (unref(isUpdate)) { |
||||
const res = await getOAuth2Client(data.record.id) |
||||
setFieldsValue({ ...res }) |
||||
} |
||||
}) |
||||
|
||||
async function handleSubmit() { |
||||
try { |
||||
const values = await validate() as any |
||||
setModalProps({ confirmLoading: true }) |
||||
if (unref(isUpdate)) |
||||
await updateOAuth2Client(values) |
||||
else |
||||
await createOAuth2Client(values) |
||||
|
||||
closeModal() |
||||
emit('success') |
||||
createMessage.success(t('common.saveSuccessText')) |
||||
} |
||||
finally { |
||||
setModalProps({ confirmLoading: false }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit"> |
||||
<BasicForm @register="registerForm" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,212 +0,0 @@
|
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '客户端编号', |
||||
dataIndex: 'clientId', |
||||
width: 200, |
||||
}, |
||||
{ |
||||
title: '客户端密钥', |
||||
dataIndex: 'secret', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '应用名', |
||||
dataIndex: 'name', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '应用图标', |
||||
dataIndex: 'logo', |
||||
width: 120, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderImg(text) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '状态', |
||||
dataIndex: 'status', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.COMMON_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '访问令牌的有效期', |
||||
dataIndex: 'accessTokenValiditySeconds', |
||||
width: 100, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderText(text, '秒') |
||||
}, |
||||
}, |
||||
{ |
||||
title: '刷新令牌的有效期', |
||||
dataIndex: 'refreshTokenValiditySeconds', |
||||
width: 100, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderText(text, '秒') |
||||
}, |
||||
}, |
||||
{ |
||||
title: '授权类型', |
||||
dataIndex: 'authorizedGrantTypes', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderTags(text) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '应用名', |
||||
field: 'name', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const formSchema: FormSchema[] = [ |
||||
{ |
||||
label: '编号', |
||||
field: 'id', |
||||
show: false, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '客户端编号', |
||||
field: 'clientId', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '客户端密钥', |
||||
field: 'secret', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '应用名', |
||||
field: 'name', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '应用图标', |
||||
field: 'logo', |
||||
required: true, |
||||
component: 'FileUpload', |
||||
componentProps: { |
||||
fileType: 'image', |
||||
maxCount: 1, |
||||
}, |
||||
}, |
||||
{ |
||||
label: '应用描述', |
||||
field: 'description', |
||||
component: 'InputTextArea', |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '访问令牌的有效期', |
||||
field: 'accessTokenValiditySeconds', |
||||
required: true, |
||||
defaultValue: 0, |
||||
component: 'InputNumber', |
||||
}, |
||||
{ |
||||
label: '刷新令牌的有效期', |
||||
field: 'refreshTokenValiditySeconds', |
||||
required: true, |
||||
defaultValue: 0, |
||||
component: 'InputNumber', |
||||
}, |
||||
{ |
||||
label: '授权类型', |
||||
field: 'authorizedGrantTypes', |
||||
required: true, |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.SYSTEM_OAUTH2_GRANT_TYPE, 'string'), |
||||
mode: 'multiple', |
||||
}, |
||||
}, |
||||
{ |
||||
label: '授权范围', |
||||
field: 'scopes', |
||||
component: 'Select', |
||||
componentProps: { |
||||
mode: 'tags', |
||||
options: [], |
||||
}, |
||||
}, |
||||
{ |
||||
label: '自动授权范围', |
||||
field: 'autoApproveScopes', |
||||
component: 'Select', |
||||
componentProps: { |
||||
mode: 'tags', |
||||
options: [], |
||||
}, |
||||
}, |
||||
{ |
||||
label: '可重定向的 URI 地址', |
||||
field: 'redirectUris', |
||||
required: true, |
||||
component: 'Select', |
||||
componentProps: { |
||||
mode: 'tags', |
||||
options: [], |
||||
}, |
||||
}, |
||||
{ |
||||
label: '权限', |
||||
field: 'authorities', |
||||
component: 'Select', |
||||
componentProps: { |
||||
mode: 'tags', |
||||
options: [], |
||||
}, |
||||
}, |
||||
{ |
||||
label: '资源', |
||||
field: 'resourceIds', |
||||
component: 'Select', |
||||
componentProps: { |
||||
mode: 'tags', |
||||
options: [], |
||||
}, |
||||
}, |
||||
{ |
||||
label: '附加信息', |
||||
field: 'additionalInformation', |
||||
component: 'InputTextArea', |
||||
}, |
||||
] |
@ -1,78 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import ClientModal from './ClientModal.vue' |
||||
import { columns, searchFormSchema } from './client.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { useModal } from '@/components/Modal' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import { deleteOAuth2Client, getOAuth2ClientPage } from '@/api/system/oauth2/client' |
||||
|
||||
defineOptions({ name: 'SystemClient' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const [registerModal, { openModal }] = useModal() |
||||
const [registerTable, { reload }] = useTable({ |
||||
title: '应用列表', |
||||
api: getOAuth2ClientPage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 140, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
function handleCreate() { |
||||
openModal(true, { isUpdate: false }) |
||||
} |
||||
|
||||
function handleEdit(record: Recordable) { |
||||
openModal(true, { record, isUpdate: true }) |
||||
} |
||||
|
||||
async function handleDelete(record: Recordable) { |
||||
await deleteOAuth2Client(record.id) |
||||
createMessage.success(t('common.delSuccessText')) |
||||
reload() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:oauth2-client:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
{{ t('action.create') }} |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:oauth2-client:update', onClick: handleEdit.bind(null, record) }, |
||||
{ |
||||
icon: IconEnum.DELETE, |
||||
danger: true, |
||||
label: t('action.delete'), |
||||
auth: 'system:oauth2-client:delete', |
||||
popConfirm: { |
||||
title: t('common.delMessage'), |
||||
placement: 'left', |
||||
confirm: handleDelete.bind(null, record), |
||||
}, |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<ClientModal @register="registerModal" @success="reload()" /> |
||||
</div> |
||||
</template> |
@ -1,60 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { columns, searchFormSchema } from './token.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import { deleteAccessToken, getAccessTokenPage } from '@/api/system/oauth2/token' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
|
||||
defineOptions({ name: 'SystemToken' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const [registerTable, { reload }] = useTable({ |
||||
title: 'Token列表', |
||||
api: getAccessTokenPage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 80, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
async function handleDelete(record: Recordable) { |
||||
await deleteAccessToken(record.id) |
||||
createMessage.success(t('common.delSuccessText')) |
||||
reload() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ |
||||
icon: IconEnum.DELETE, |
||||
danger: true, |
||||
label: '强退', |
||||
auth: 'system:oauth2-token:delete', |
||||
popConfirm: { |
||||
title: '是否确认强退', |
||||
placement: 'left', |
||||
confirm: handleDelete.bind(null, record), |
||||
}, |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
</div> |
||||
</template> |
@ -1,69 +0,0 @@
|
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '访问令牌', |
||||
dataIndex: 'accessToken', |
||||
width: 300, |
||||
}, |
||||
{ |
||||
title: '刷新令牌', |
||||
dataIndex: 'refreshToken', |
||||
width: 300, |
||||
}, |
||||
{ |
||||
title: '用户编号', |
||||
dataIndex: 'userId', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '用户类型', |
||||
dataIndex: 'userType', |
||||
width: 120, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.USER_TYPE) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '过期时间', |
||||
dataIndex: 'expiresTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '用户编号', |
||||
field: 'userId', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '客户端编号', |
||||
field: 'clientId', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '用户类型', |
||||
field: 'userType', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.USER_TYPE), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
@ -1,25 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref } from 'vue' |
||||
import { infoSchema } from './operateLog.data' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { Description, useDescription } from '@/components/Description/index' |
||||
|
||||
defineOptions({ name: 'OperLogInfoModal' }) |
||||
|
||||
const logData = ref() |
||||
const [registerModalInner, { closeModal }] = useModalInner((record: Recordable) => { |
||||
logData.value = record |
||||
}) |
||||
|
||||
const [registerDescription] = useDescription({ |
||||
column: 1, |
||||
schema: infoSchema, |
||||
data: logData, |
||||
}) |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" title="操作日志详情" width="800px" @register="registerModalInner" @ok="closeModal"> |
||||
<Description @register="registerDescription" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,74 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { columns, searchFormSchema } from './operateLog.data' |
||||
import OperLogInfoModal from './LogInfoModal.vue' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import type { OperateLogPageReqVO } from '@/api/system/operatelog' |
||||
import { exportOperateLog, getOperateLogPage } from '@/api/system/operatelog' |
||||
import { useModal } from '@/components/Modal' |
||||
|
||||
defineOptions({ name: 'SystemOperateLog' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createConfirm, createMessage } = useMessage() |
||||
const [registerTable, { getForm }] = useTable({ |
||||
title: '操作日志列表', |
||||
api: getOperateLogPage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 140, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
async function handleExport() { |
||||
createConfirm({ |
||||
title: t('common.exportTitle'), |
||||
iconType: 'warning', |
||||
content: t('common.exportMessage'), |
||||
async onOk() { |
||||
await exportOperateLog(getForm().getFieldsValue() as OperateLogPageReqVO) |
||||
createMessage.success(t('common.exportSuccessText')) |
||||
}, |
||||
}) |
||||
} |
||||
|
||||
const [registerModal, { openModal }] = useModal() |
||||
function handleShowInfo(record: Recordable) { |
||||
openModal(true, record) |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button :pre-icon="IconEnum.EXPORT" @click="handleExport"> |
||||
{{ t('action.export') }} |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ |
||||
icon: IconEnum.VIEW, |
||||
label: t('action.detail'), |
||||
onClick: handleShowInfo.bind(null, record), |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<OperLogInfoModal @register="registerModal" /> |
||||
</div> |
||||
</template> |
@ -1,202 +0,0 @@
|
||||
import { h } from 'vue' |
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
import type { DescItem } from '@/components/Description/index' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '日志编号', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '操作模块', |
||||
dataIndex: 'module', |
||||
width: 200, |
||||
}, |
||||
{ |
||||
title: '操作名', |
||||
dataIndex: 'name', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '操作类型', |
||||
dataIndex: 'type', |
||||
width: 120, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_OPERATE_TYPE) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '操作人', |
||||
dataIndex: 'userNickname', |
||||
width: 120, |
||||
}, |
||||
// {
|
||||
// title: 'userAgent',
|
||||
// dataIndex: 'userAgent',
|
||||
// width: 400
|
||||
// },
|
||||
{ |
||||
title: '请求路径', |
||||
dataIndex: 'requestUrl', |
||||
}, |
||||
{ |
||||
title: '操作结果', |
||||
dataIndex: 'resultCode', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderTag(text === 0 ? '成功' : '失败', text === 0 ? '#87d068' : '#f50') |
||||
}, |
||||
}, |
||||
{ |
||||
title: '执行时长', |
||||
dataIndex: 'duration', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderText(text, 'ms') |
||||
}, |
||||
}, |
||||
{ |
||||
title: '操作日期', |
||||
dataIndex: 'startTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '系统模块', |
||||
field: 'title', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '操作人员', |
||||
field: 'operName', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '类型', |
||||
field: 'type', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.SYSTEM_OPERATE_TYPE), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'success', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: [ |
||||
{ value: 1, key: true, label: '成功' }, |
||||
{ value: 0, key: false, label: '失败' }, |
||||
], |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '操作时间', |
||||
field: 'startTime', |
||||
component: 'RangePicker', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
const httpMethods = [ |
||||
{ value: 'GET', color: '#108ee9' }, |
||||
{ value: 'POST', color: '#2db7f5' }, |
||||
{ value: 'PUT', color: 'warning' }, |
||||
{ value: 'DELETE', color: '#f50' }, |
||||
] |
||||
|
||||
export const infoSchema: DescItem[] = [ |
||||
{ |
||||
field: 'module', |
||||
label: '操作模块', |
||||
}, |
||||
{ |
||||
field: 'name', |
||||
label: '操作名', |
||||
}, |
||||
{ |
||||
field: 'userNickname', |
||||
label: '操作人', |
||||
render(_, data) { |
||||
const { userNickname, userId } = data |
||||
// return useRender.renderText(userNickname, 'uid: ' + userId)
|
||||
return useRender.renderTags([userNickname, `uid: ${userId}`]) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'resultCode', |
||||
label: '请求结果', |
||||
render(value) { |
||||
return useRender.renderTag(value === 0 ? '成功' : '失败', value === 0 ? '#87d068' : '#f50') |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'resultMsg', |
||||
label: '响应信息', |
||||
show(data) { |
||||
return data && data.resultMsg && data.resultMsg !== '' |
||||
}, |
||||
render(value) { |
||||
return h('span', { style: { color: 'red', fontWeight: 'bold' } }, value) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'userIp', |
||||
label: '请求ip', |
||||
}, |
||||
{ |
||||
field: 'startTime', |
||||
label: '请求时间', |
||||
render(value) { |
||||
return useRender.renderDate(value) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'requestUrl', |
||||
label: '请求路径', |
||||
render(_, data) { |
||||
if (!data) |
||||
return '' |
||||
|
||||
const { requestMethod, requestUrl } = data |
||||
const current = httpMethods.find(item => item.value === requestMethod.toUpperCase()) |
||||
const methodTag = current ? useRender.renderTag(requestMethod, current.color) : requestMethod |
||||
return h('span', {}, [methodTag, requestUrl]) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'javaMethod', |
||||
label: '操作方法', |
||||
labelMinWidth: 80, |
||||
}, |
||||
{ |
||||
field: 'javaMethodArgs', |
||||
label: '请求参数', |
||||
render(value) { |
||||
return useRender.renderJsonPreview(value) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'userAgent', |
||||
label: 'userAgent', |
||||
}, |
||||
{ |
||||
field: 'duration', |
||||
label: '请求耗时', |
||||
render(value) { |
||||
return useRender.renderText(value, 'ms') |
||||
}, |
||||
}, |
||||
] |
@ -1,58 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref, unref } from 'vue' |
||||
import { formSchema } from './post.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { createPost, getPost, updatePost } from '@/api/system/post' |
||||
|
||||
defineOptions({ name: 'SystemPostModal' }) |
||||
|
||||
const emit = defineEmits(['success', 'register']) |
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const isUpdate = ref(true) |
||||
|
||||
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 }) |
||||
isUpdate.value = !!data?.isUpdate |
||||
if (unref(isUpdate)) { |
||||
const res = await getPost(data.record.id) |
||||
setFieldsValue({ ...res }) |
||||
} |
||||
}) |
||||
|
||||
async function handleSubmit() { |
||||
try { |
||||
const values = await validate() |
||||
setModalProps({ confirmLoading: true }) |
||||
if (unref(isUpdate)) |
||||
await updatePost(values) |
||||
else |
||||
await createPost(values) |
||||
|
||||
closeModal() |
||||
emit('success') |
||||
createMessage.success(t('common.saveSuccessText')) |
||||
} |
||||
finally { |
||||
setModalProps({ confirmLoading: false }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit"> |
||||
<BasicForm @register="registerForm" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,94 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import PostModal from './PostModal.vue' |
||||
import { columns, searchFormSchema } from './post.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { useModal } from '@/components/Modal' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import type { PostExportReqVO } from '@/api/system/post' |
||||
import { deletePost, exportPost, getPostPage } from '@/api/system/post' |
||||
|
||||
defineOptions({ name: 'SystemPost' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createConfirm, createMessage } = useMessage() |
||||
const [registerModal, { openModal }] = useModal() |
||||
|
||||
const [registerTable, { getForm, reload }] = useTable({ |
||||
title: '岗位列表', |
||||
api: getPostPage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
actionColumn: { |
||||
width: 140, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
function handleCreate() { |
||||
openModal(true, { isUpdate: false }) |
||||
} |
||||
|
||||
function handleEdit(record: Recordable) { |
||||
openModal(true, { record, isUpdate: true }) |
||||
} |
||||
|
||||
async function handleExport() { |
||||
createConfirm({ |
||||
title: t('common.exportTitle'), |
||||
iconType: 'warning', |
||||
content: t('common.exportMessage'), |
||||
async onOk() { |
||||
await exportPost(getForm().getFieldsValue() as PostExportReqVO) |
||||
createMessage.success(t('common.exportSuccessText')) |
||||
}, |
||||
}) |
||||
} |
||||
|
||||
async function handleDelete(record: Recordable) { |
||||
await deletePost(record.id) |
||||
createMessage.success(t('common.delSuccessText')) |
||||
reload() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:post:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
{{ t('action.create') }} |
||||
</a-button> |
||||
<a-button v-auth="['system:post:export']" :pre-icon="IconEnum.EXPORT" @click="handleExport"> |
||||
{{ t('action.export') }} |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:post:update', onClick: handleEdit.bind(null, record) }, |
||||
{ |
||||
icon: IconEnum.DELETE, |
||||
danger: true, |
||||
label: t('action.delete'), |
||||
auth: 'system:post:delete', |
||||
popConfirm: { |
||||
title: t('common.delMessage'), |
||||
placement: 'left', |
||||
confirm: handleDelete.bind(null, record), |
||||
}, |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<PostModal @register="registerModal" @success="reload()" /> |
||||
</div> |
||||
</template> |
@ -1,112 +0,0 @@
|
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '岗位编号', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '岗位名称', |
||||
dataIndex: 'name', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '岗位编码', |
||||
dataIndex: 'code', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '岗位顺序', |
||||
dataIndex: 'sort', |
||||
width: 120, |
||||
}, |
||||
{ |
||||
title: '状态', |
||||
dataIndex: 'status', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.COMMON_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '备注', |
||||
dataIndex: 'remark', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '岗位名称', |
||||
field: 'name', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '岗位编码', |
||||
field: 'code', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const formSchema: FormSchema[] = [ |
||||
{ |
||||
label: '编号', |
||||
field: 'id', |
||||
show: false, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '岗位名称', |
||||
field: 'name', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '岗位编码', |
||||
field: 'code', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '岗位顺序', |
||||
field: 'sort', |
||||
required: true, |
||||
defaultValue: 0, |
||||
component: 'InputNumber', |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '备注', |
||||
field: 'remark', |
||||
component: 'InputTextArea', |
||||
}, |
||||
] |
@ -1,58 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref, unref } from 'vue' |
||||
import { formSchema } from './sensitiveWord.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { createSensitiveWord, getSensitiveWord, updateSensitiveWord } from '@/api/system/sensitiveWord' |
||||
|
||||
defineOptions({ name: 'SystemSensitiveWordModal' }) |
||||
|
||||
const emit = defineEmits(['success', 'register']) |
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const isUpdate = ref(true) |
||||
|
||||
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 }) |
||||
isUpdate.value = !!data?.isUpdate |
||||
if (unref(isUpdate)) { |
||||
const res = await getSensitiveWord(data.record.id) |
||||
setFieldsValue({ ...res }) |
||||
} |
||||
}) |
||||
|
||||
async function handleSubmit() { |
||||
try { |
||||
const values = await validate() as any |
||||
setModalProps({ confirmLoading: true }) |
||||
if (unref(isUpdate)) |
||||
await updateSensitiveWord(values) |
||||
else |
||||
await createSensitiveWord(values) |
||||
|
||||
closeModal() |
||||
emit('success') |
||||
createMessage.success(t('common.saveSuccessText')) |
||||
} |
||||
finally { |
||||
setModalProps({ confirmLoading: false }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit"> |
||||
<BasicForm @register="registerForm" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,99 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import SensitiveWordModal from './SensitiveWordModal.vue' |
||||
import { columns, searchFormSchema } from './sensitiveWord.data' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import type { SensitiveWordExportReqVO } from '@/api/system/sensitiveWord' |
||||
import { deleteSensitiveWord, exportSensitiveWord, getSensitiveWordPage } from '@/api/system/sensitiveWord' |
||||
import { useModal } from '@/components/Modal' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
|
||||
defineOptions({ name: 'SystemSensitiveWord' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createConfirm, createMessage } = useMessage() |
||||
const [registerModal, { openModal }] = useModal() |
||||
const [registerTable, { getForm, reload }] = useTable({ |
||||
title: '敏感词列表', |
||||
api: getSensitiveWordPage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 140, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
function handleCreate() { |
||||
openModal(true, { isUpdate: false }) |
||||
} |
||||
|
||||
function handleEdit(record: Recordable) { |
||||
openModal(true, { record, isUpdate: true }) |
||||
} |
||||
|
||||
async function handleExport() { |
||||
createConfirm({ |
||||
title: t('common.exportTitle'), |
||||
iconType: 'warning', |
||||
content: t('common.exportMessage'), |
||||
async onOk() { |
||||
await exportSensitiveWord(getForm().getFieldsValue() as SensitiveWordExportReqVO) |
||||
createMessage.success(t('common.exportSuccessText')) |
||||
}, |
||||
}) |
||||
} |
||||
|
||||
async function handleDelete(record: Recordable) { |
||||
await deleteSensitiveWord(record.id) |
||||
createMessage.success(t('common.delSuccessText')) |
||||
reload() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:sensitive-word:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
{{ t('action.create') }} |
||||
</a-button> |
||||
<a-button v-auth="['system:sensitive-word:export']" :pre-icon="IconEnum.EXPORT" @click="handleExport"> |
||||
{{ t('action.export') }} |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ |
||||
icon: IconEnum.EDIT, |
||||
label: t('action.edit'), |
||||
auth: 'system:sensitive-word:delete', |
||||
onClick: handleEdit.bind(null, record), |
||||
}, |
||||
{ |
||||
icon: IconEnum.DELETE, |
||||
danger: true, |
||||
label: t('action.delete'), |
||||
auth: 'system:sensitive-word:delete', |
||||
popConfirm: { |
||||
title: t('common.delMessage'), |
||||
placement: 'left', |
||||
confirm: handleDelete.bind(null, record), |
||||
}, |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<SensitiveWordModal @register="registerModal" @success="reload()" /> |
||||
</div> |
||||
</template> |
@ -1,113 +0,0 @@
|
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '编号', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '敏感词', |
||||
dataIndex: 'name', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '状态', |
||||
dataIndex: 'status', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.COMMON_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '描述', |
||||
dataIndex: 'description', |
||||
width: 200, |
||||
}, |
||||
{ |
||||
title: '标签', |
||||
dataIndex: 'tags', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderTags(text) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '敏感词', |
||||
field: 'name', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '标签', |
||||
field: 'tag', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '创建时间', |
||||
field: 'createTime', |
||||
component: 'RangePicker', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const formSchema: FormSchema[] = [ |
||||
{ |
||||
label: '编号', |
||||
field: 'id', |
||||
show: false, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '敏感词', |
||||
field: 'name', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '备注', |
||||
field: 'remark', |
||||
component: 'InputTextArea', |
||||
}, |
||||
{ |
||||
label: '标签', |
||||
field: 'tags', |
||||
required: true, |
||||
component: 'Select', |
||||
componentProps: { |
||||
mode: 'tags', |
||||
options: [], |
||||
}, |
||||
}, |
||||
] |
@ -1,58 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref, unref } from 'vue' |
||||
import { formSchema } from './smsChannel.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { createSmsChannel, getSmsChannel, updateSmsChannel } from '@/api/system/sms/smsChannel' |
||||
|
||||
defineOptions({ name: 'SystemSmsChannelModal' }) |
||||
|
||||
const emit = defineEmits(['success', 'register']) |
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const isUpdate = ref(true) |
||||
|
||||
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 }) |
||||
isUpdate.value = !!data?.isUpdate |
||||
if (unref(isUpdate)) { |
||||
const res = await getSmsChannel(data.record.id) |
||||
setFieldsValue({ ...res }) |
||||
} |
||||
}) |
||||
|
||||
async function handleSubmit() { |
||||
try { |
||||
const values = await validate() as any |
||||
setModalProps({ confirmLoading: true }) |
||||
if (unref(isUpdate)) |
||||
await updateSmsChannel(values) |
||||
else |
||||
await createSmsChannel(values) |
||||
|
||||
closeModal() |
||||
emit('success') |
||||
createMessage.success(t('common.saveSuccessText')) |
||||
} |
||||
finally { |
||||
setModalProps({ confirmLoading: false }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit"> |
||||
<BasicForm @register="registerForm" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,79 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import SmsChannelModal from './SmsChannelModal.vue' |
||||
import { columns, searchFormSchema } from './smsChannel.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { useModal } from '@/components/Modal' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import { deleteSmsChannel, getSmsChannelPage } from '@/api/system/sms/smsChannel' |
||||
|
||||
defineOptions({ name: 'SystemSmsChannel' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const [registerModal, { openModal }] = useModal() |
||||
|
||||
const [registerTable, { reload }] = useTable({ |
||||
title: '短信渠道列表', |
||||
api: getSmsChannelPage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 140, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
function handleCreate() { |
||||
openModal(true, { isUpdate: false }) |
||||
} |
||||
|
||||
function handleEdit(record: Recordable) { |
||||
openModal(true, { record, isUpdate: true }) |
||||
} |
||||
|
||||
async function handleDelete(record: Recordable) { |
||||
await deleteSmsChannel(record.id) |
||||
createMessage.success(t('common.delSuccessText')) |
||||
reload() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:sms-channel:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
{{ t('action.create') }} |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:sms-channel:update', onClick: handleEdit.bind(null, record) }, |
||||
{ |
||||
icon: IconEnum.DELETE, |
||||
danger: true, |
||||
label: t('action.delete'), |
||||
auth: 'system:sms-channel:delete', |
||||
popConfirm: { |
||||
title: t('common.delMessage'), |
||||
placement: 'left', |
||||
confirm: handleDelete.bind(null, record), |
||||
}, |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<SmsChannelModal @register="registerModal" @success="reload()" /> |
||||
</div> |
||||
</template> |
@ -1,138 +0,0 @@
|
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '编号', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '短信签名', |
||||
dataIndex: 'signature', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '渠道编码', |
||||
dataIndex: 'code', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '启用状态', |
||||
dataIndex: 'status', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.COMMON_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '备注', |
||||
dataIndex: 'remark', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '短信 API 的账号', |
||||
dataIndex: 'apiKey', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '短信 API 的密钥', |
||||
dataIndex: 'apiSecret', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '短信发送回调 URL', |
||||
dataIndex: 'callbackUrl', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '短信签名', |
||||
field: 'signature', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '启用状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '创建时间', |
||||
field: 'createTime', |
||||
component: 'RangePicker', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const formSchema: FormSchema[] = [ |
||||
{ |
||||
label: '编号', |
||||
field: 'id', |
||||
show: false, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '短信签名', |
||||
field: 'signature', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '渠道编码', |
||||
field: 'code', |
||||
component: 'Select', |
||||
required: true, |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE, 'string'), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '启用状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
defaultValue: 0, |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '备注', |
||||
field: 'remark', |
||||
component: 'InputTextArea', |
||||
}, |
||||
{ |
||||
label: '短信 API 的账号', |
||||
field: 'apiKey', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '短信 API 的密钥', |
||||
field: 'apiSecret', |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '短信发送回调 URL', |
||||
field: 'callbackUrl', |
||||
component: 'Input', |
||||
}, |
||||
] |
@ -1,47 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { columns, searchFormSchema } from './smsLog.data' |
||||
import { BasicTable, useTable } from '@/components/Table' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import type { SmsLogExportReqVO } from '@/api/system/sms/smsLog' |
||||
import { exportSmsLog, getSmsLogPage } from '@/api/system/sms/smsLog' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
|
||||
defineOptions({ name: 'SystemSmsLog' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createConfirm, createMessage } = useMessage() |
||||
const [registerTable, { getForm }] = useTable({ |
||||
title: '短信日志列表', |
||||
api: getSmsLogPage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
}) |
||||
|
||||
async function handleExport() { |
||||
createConfirm({ |
||||
title: t('common.exportTitle'), |
||||
iconType: 'warning', |
||||
content: t('common.exportMessage'), |
||||
async onOk() { |
||||
await exportSmsLog(getForm().getFieldsValue() as SmsLogExportReqVO) |
||||
createMessage.success(t('common.exportSuccessText')) |
||||
}, |
||||
}) |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:sms-log:export']" :pre-icon="IconEnum.EXPORT" @click="handleExport"> |
||||
{{ t('action.export') }} |
||||
</a-button> |
||||
</template> |
||||
</BasicTable> |
||||
</div> |
||||
</template> |
@ -1,148 +0,0 @@
|
||||
import { getSimpleSmsChannels } from '@/api/system/sms/smsChannel' |
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
||||
let channelOptions: any[] = [] |
||||
|
||||
async function getchannelList() { |
||||
const res = await getSimpleSmsChannels() |
||||
channelOptions = res |
||||
} |
||||
|
||||
await getchannelList() |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '日志编号', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '手机号', |
||||
dataIndex: 'mobile', |
||||
width: 180, |
||||
customRender: ({ text, record }) => { |
||||
if (record.userType && record.userId) |
||||
return useRender.renderDict(record.userType, DICT_TYPE.USER_TYPE) |
||||
else return text |
||||
}, |
||||
}, |
||||
{ |
||||
title: '短信内容', |
||||
dataIndex: 'templateContent', |
||||
width: 300, |
||||
}, |
||||
{ |
||||
title: '发送状态', |
||||
dataIndex: 'sendStatus', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_SMS_SEND_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '接收状态', |
||||
dataIndex: 'receiveStatus', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_SMS_RECEIVE_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '短信渠道', |
||||
dataIndex: 'channelCode', |
||||
width: 180, |
||||
customRender: ({ text, record }) => { |
||||
if (!text) |
||||
return '未设置' |
||||
|
||||
for (const channel of channelOptions) { |
||||
if (record.channelId === channel.id) |
||||
return channel.signature |
||||
} |
||||
|
||||
return `找不到签名:${record.channelId}` |
||||
}, |
||||
}, |
||||
{ |
||||
title: '模板编号', |
||||
dataIndex: 'templateId', |
||||
width: 120, |
||||
}, |
||||
{ |
||||
title: '短信类型', |
||||
dataIndex: 'templateType', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '手机号', |
||||
field: 'mobile', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '短信渠道', |
||||
field: 'channelId', |
||||
component: 'ApiSelect', |
||||
componentProps: { |
||||
api: getSimpleSmsChannels, |
||||
fieldNames: { |
||||
label: 'signature', |
||||
key: 'id', |
||||
value: 'id', |
||||
}, |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '模板编号', |
||||
field: 'templateId', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '发送状态', |
||||
field: 'sendStatus', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.SYSTEM_SMS_SEND_STATUS), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '发送时间', |
||||
field: 'sendTime', |
||||
component: 'RangePicker', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '接收状态', |
||||
field: 'receiveStatus', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.SYSTEM_SMS_RECEIVE_STATUS), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '接收时间', |
||||
field: 'receiveTime', |
||||
component: 'RangePicker', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
@ -1,88 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { reactive, ref } from 'vue' |
||||
import { baseSendSchemas } from './smsTemplate.data' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import type { FormSchema } from '@/components/Form' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import type { SmsTemplateVO } from '@/api/system/sms/smsTemplate' |
||||
import { sendSms } from '@/api/system/sms/smsTemplate' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
|
||||
defineOptions({ name: 'SendSmsModal' }) |
||||
|
||||
const { createMessage } = useMessage() |
||||
const reactiveSchemas: FormSchema[] = reactive([]) |
||||
const templateCode = ref<string>('') |
||||
|
||||
const [register, { setFieldsValue, getFieldsValue, validateFields, resetFields, clearValidate, setProps }] = useForm({ |
||||
labelWidth: 100, |
||||
baseColProps: { |
||||
span: 24, |
||||
}, |
||||
showActionButtonGroup: false, |
||||
}) |
||||
|
||||
const [innerRegister, { changeLoading, closeModal }] = useModalInner((data: SmsTemplateVO) => { |
||||
resetForm() |
||||
data.params.forEach((item) => { |
||||
const dySchema: FormSchema = { |
||||
// 这里加上前缀 防止content/mobile和字段重名 |
||||
field: `key-${item}`, |
||||
label: `参数{${item}} `, |
||||
component: 'Input', |
||||
componentProps: { |
||||
placeholder: `输入{${item}}`, |
||||
}, |
||||
required: true, |
||||
} |
||||
reactiveSchemas.push(dySchema) |
||||
}) |
||||
const { content, code } = data |
||||
setFieldsValue({ content }) |
||||
templateCode.value = code |
||||
}) |
||||
|
||||
async function submit() { |
||||
try { |
||||
setProps({ disabled: true }) |
||||
changeLoading(true) |
||||
await validateFields() |
||||
const fields = getFieldsValue() |
||||
const data = { |
||||
mobile: fields.mobile, |
||||
templateCode: templateCode.value, |
||||
templateParams: {}, |
||||
} |
||||
Object.keys(fields).forEach((key) => { |
||||
if (key === 'content' || key === 'mobile') |
||||
return |
||||
|
||||
// 去掉 - 后的key |
||||
const realKey = key.split('-')[1] |
||||
data.templateParams[realKey] = fields[key] |
||||
}) |
||||
await sendSms(data) |
||||
createMessage.success(`发送短信到[${fields.mobile}]成功`) |
||||
closeModal() |
||||
} |
||||
finally { |
||||
setProps({ disabled: false }) |
||||
changeLoading(false) |
||||
} |
||||
} |
||||
|
||||
function resetForm() { |
||||
// 这里需要每次清空动态表单 |
||||
reactiveSchemas.splice(0, reactiveSchemas.length) |
||||
reactiveSchemas.push(...baseSendSchemas) |
||||
// 清除上一次的表单校验和参数 |
||||
resetFields() |
||||
clearValidate() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" title="测试发送短信" @register="innerRegister" @ok="submit"> |
||||
<BasicForm :schemas="reactiveSchemas" @register="register" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,58 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref, unref } from 'vue' |
||||
import { formSchema } from './smsTemplate.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { createSmsTemplate, getSmsTemplate, updateSmsTemplate } from '@/api/system/sms/smsTemplate' |
||||
|
||||
defineOptions({ name: 'SystemSmsTemplateModal' }) |
||||
|
||||
const emit = defineEmits(['success', 'register']) |
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const isUpdate = ref(true) |
||||
|
||||
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 }) |
||||
isUpdate.value = !!data?.isUpdate |
||||
if (unref(isUpdate)) { |
||||
const res = await getSmsTemplate(data.record.id) |
||||
setFieldsValue({ ...res }) |
||||
} |
||||
}) |
||||
|
||||
async function handleSubmit() { |
||||
try { |
||||
const values = await validate() as any |
||||
setModalProps({ confirmLoading: true }) |
||||
if (unref(isUpdate)) |
||||
await updateSmsTemplate(values) |
||||
else |
||||
await createSmsTemplate(values) |
||||
|
||||
closeModal() |
||||
emit('success') |
||||
createMessage.success(t('common.saveSuccessText')) |
||||
} |
||||
finally { |
||||
setModalProps({ confirmLoading: false }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit"> |
||||
<BasicForm @register="registerForm" /> |
||||
</BasicModal> |
||||
</template> |
@ -1,107 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import SmsTemplateModal from './SmsTemplateModal.vue' |
||||
import SendSmsModal from './SendSmsModal.vue' |
||||
import { columns, searchFormSchema } from './smsTemplate.data' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import type { SmsTemplateExportReqVO } from '@/api/system/sms/smsTemplate' |
||||
import { deleteSmsTemplate, exportSmsTemplate, getSmsTemplatePage } from '@/api/system/sms/smsTemplate' |
||||
import { useModal } from '@/components/Modal' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
|
||||
defineOptions({ name: 'SystemSmsTemplate' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createConfirm, createMessage } = useMessage() |
||||
const [registerModal, { openModal }] = useModal() |
||||
const [registerSendModal, { openModal: openSendModal }] = useModal() |
||||
const [registerTable, { getForm, reload }] = useTable({ |
||||
title: '短信模版列表', |
||||
api: getSmsTemplatePage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 220, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
function handleCreate() { |
||||
openModal(true, { isUpdate: false }) |
||||
} |
||||
|
||||
function handleSendSms(record: Recordable) { |
||||
openSendModal(true, record) |
||||
} |
||||
|
||||
function handleEdit(record: Recordable) { |
||||
openModal(true, { record, isUpdate: true }) |
||||
} |
||||
|
||||
async function handleExport() { |
||||
createConfirm({ |
||||
title: t('common.exportTitle'), |
||||
iconType: 'warning', |
||||
content: t('common.exportMessage'), |
||||
async onOk() { |
||||
await exportSmsTemplate(getForm().getFieldsValue() as SmsTemplateExportReqVO) |
||||
createMessage.success(t('common.exportSuccessText')) |
||||
}, |
||||
}) |
||||
} |
||||
|
||||
async function handleDelete(record: Recordable) { |
||||
await deleteSmsTemplate(record.id) |
||||
createMessage.success(t('common.delSuccessText')) |
||||
reload() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:sms-template:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
{{ t('action.create') }} |
||||
</a-button> |
||||
<a-button v-auth="['system:sms-template:export']" :pre-icon="IconEnum.EXPORT" @click="handleExport"> |
||||
{{ t('action.export') }} |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ |
||||
icon: IconEnum.TEST, |
||||
label: t('action.test'), |
||||
auth: 'system:sms-template:send-sms', |
||||
onClick: handleSendSms.bind(null, record), |
||||
}, |
||||
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:sms-template:update', onClick: handleEdit.bind(null, record) }, |
||||
{ |
||||
icon: IconEnum.DELETE, |
||||
danger: true, |
||||
label: t('action.delete'), |
||||
auth: 'system:sms-template:delete', |
||||
popConfirm: { |
||||
title: t('common.delMessage'), |
||||
placement: 'left', |
||||
confirm: handleDelete.bind(null, record), |
||||
}, |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<SmsTemplateModal @register="registerModal" @success="reload()" /> |
||||
<SendSmsModal @register="registerSendModal" /> |
||||
</div> |
||||
</template> |
@ -1,209 +0,0 @@
|
||||
import { h } from 'vue' |
||||
import { ScrollContainer } from '@/components/Container' |
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '模板编码', |
||||
dataIndex: 'code', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '模板名称', |
||||
dataIndex: 'name', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '模板内容', |
||||
dataIndex: 'content', |
||||
width: 300, |
||||
}, |
||||
{ |
||||
title: '短信类型', |
||||
dataIndex: 'type', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '开启状态', |
||||
dataIndex: 'status', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.COMMON_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '备注', |
||||
dataIndex: 'remark', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '短信 API 的模板编号', |
||||
dataIndex: 'apiTemplateId', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '短信渠道', |
||||
dataIndex: 'channelCode', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '短信类型', |
||||
field: 'type', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '开启状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '模板编码', |
||||
field: 'code', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '短信 API 的模板编号', |
||||
field: 'apiTemplateId', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '短信渠道', |
||||
field: 'channelId', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.SYSTEM_SMS_CHANNEL_CODE), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '创建时间', |
||||
field: 'createTime', |
||||
component: 'RangePicker', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const formSchema: FormSchema[] = [ |
||||
{ |
||||
label: '编号', |
||||
field: 'id', |
||||
show: false, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '短信渠道编号', |
||||
field: 'channelId', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '短信类型', |
||||
field: 'type', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '模板编号', |
||||
field: 'code', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '模板名称', |
||||
field: 'name', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '模板内容', |
||||
field: 'content', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '开启状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
}, |
||||
{ |
||||
label: '短信 API 模板编号', |
||||
field: 'apiTemplateId', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '备注', |
||||
field: 'remark', |
||||
component: 'InputTextArea', |
||||
}, |
||||
] |
||||
|
||||
// 发送短信
|
||||
// 这里加上前缀 防止和表单其他字段重名
|
||||
export const keyPrefix = 'key$-' |
||||
export const baseSendSchemas: FormSchema[] = [ |
||||
{ |
||||
field: 'content', |
||||
component: 'Editor', |
||||
label: '模板内容 ', |
||||
required: false, |
||||
defaultValue: '', |
||||
render({ model }) { |
||||
let content: string = model.content |
||||
Object.keys(model).forEach((key) => { |
||||
if (!key.startsWith(keyPrefix)) |
||||
return |
||||
|
||||
const realKey = key.split(keyPrefix)[1] |
||||
content = content.replace(`{${realKey}}`, model[key]) |
||||
}) |
||||
return h(ScrollContainer, { |
||||
innerHTML: content, |
||||
style: { border: '1px solid #e8e8e8', borderRadius: '6px', padding: '10px' }, |
||||
}) |
||||
}, |
||||
}, |
||||
{ |
||||
field: 'mobile', |
||||
label: '手机号 ', |
||||
component: 'Input', |
||||
componentProps: { |
||||
placeholder: '请输入手机号', |
||||
}, |
||||
required: true, |
||||
}, |
||||
] |
@ -1,128 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import { ref, unref } from 'vue' |
||||
import { without } from 'lodash-es' |
||||
import { formSchema } from './tenantPackage.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { BasicForm, useForm } from '@/components/Form' |
||||
import type { CheckedEvent, CheckedKeys, TreeItem } from '@/components/Tree' |
||||
import { BasicTree } from '@/components/Tree' |
||||
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
import { createTenantPackage, getTenantPackage, updateTenantPackage } from '@/api/system/tenantPackage' |
||||
|
||||
import { getMenuListWithoutButtons } from '@/api/system/menu' |
||||
import { handleTree } from '@/utils/tree' |
||||
|
||||
defineOptions({ name: 'SystemTenantPackageModal' }) |
||||
|
||||
const emit = defineEmits(['success', 'register']) |
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const isUpdate = ref(true) |
||||
const treeData = ref<TreeItem[]>([]) |
||||
const menuKeys = ref<number[]>([]) |
||||
const menuHalfKeys = ref<number[]>([]) |
||||
// 默认展开的层级 |
||||
const defaultExpandLevel = ref<number>(1) |
||||
// 祖先节点list |
||||
const parentIdSets = ref<Set<string>>(new Set()) |
||||
const treeRef = ref() |
||||
|
||||
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() |
||||
menuReset() |
||||
setModalProps({ confirmLoading: false }) |
||||
if (unref(treeData).length === 0) { |
||||
const res = await getMenuListWithoutButtons() |
||||
treeData.value = handleTree(res, 'id') |
||||
// 去重 拿到所有的祖先节点 |
||||
parentIdSets.value = new Set<string>(res.map(item => item.parentId)) |
||||
} |
||||
isUpdate.value = !!data?.isUpdate |
||||
|
||||
if (unref(isUpdate)) { |
||||
const res = await getTenantPackage(data.record.id) |
||||
// 默认关联节点 需要排除所有的祖先节点 否则会全部勾选 |
||||
// 只保留子节点 关联情况下会自己选中父节点 |
||||
// 排除祖先节点后的子节点 达到"独立"的效果 但可以进行关联选择 |
||||
const excludeParentIds: string[] = without(res.menuIds, ...Array.from(parentIdSets.value)) |
||||
// 这里的checkedKeys为包含所有节点的数组 用作判断数组是否修改过 |
||||
menuKeys.value = res.menuIds |
||||
// 这里只控制页面显示 不包含祖先节点 |
||||
res.menuIds = excludeParentIds |
||||
await setFieldsValue({ ...res }) |
||||
} |
||||
|
||||
// 默认展开的层级 |
||||
if (unref(treeRef)) |
||||
unref(treeRef).filterByLevel(defaultExpandLevel.value) |
||||
}) |
||||
|
||||
async function handleSubmit() { |
||||
try { |
||||
const values = await validate() as any |
||||
values.menuIds = [...menuKeys.value, ...menuHalfKeys.value] |
||||
setModalProps({ confirmLoading: true }) |
||||
if (unref(isUpdate)) |
||||
await updateTenantPackage(values) |
||||
else |
||||
await createTenantPackage(values) |
||||
|
||||
closeModal() |
||||
emit('success') |
||||
createMessage.success(t('common.saveSuccessText')) |
||||
} |
||||
finally { |
||||
setModalProps({ confirmLoading: false }) |
||||
} |
||||
} |
||||
|
||||
function menuReset() { |
||||
menuKeys.value = [] |
||||
menuHalfKeys.value = [] |
||||
} |
||||
|
||||
/** |
||||
* 父子节点关联情况下 checkedKeys为选中的菜单 e.halfCheckedKeys为父节点数组 |
||||
* 父子节点独立情况下 checkedKeys为{checked: number[], halfChecked: number[]} e.halfCheckedKeys为null |
||||
* @param checkedKeys 选中的菜单 |
||||
* @param event event |
||||
*/ |
||||
function menuCheck(checkedKeys: CheckedKeys, event: CheckedEvent) { |
||||
if (Array.isArray(checkedKeys)) { |
||||
menuKeys.value = checkedKeys |
||||
menuHalfKeys.value = event.halfCheckedKeys! |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit"> |
||||
<BasicForm @register="registerForm"> |
||||
<template #menuIds="{ model, field }"> |
||||
<BasicTree |
||||
v-if="treeData.length" |
||||
ref="treeRef" |
||||
v-model:checkedKeys="model[field]" |
||||
:tree-data="treeData" |
||||
:field-names="{ title: 'name', key: 'id' }" |
||||
checkable |
||||
toolbar |
||||
search |
||||
:show-strictly-button="false" |
||||
:selectable="false" |
||||
title="菜单分配" |
||||
@check="menuCheck" |
||||
/> |
||||
</template> |
||||
</BasicForm> |
||||
</BasicModal> |
||||
</template> |
@ -1,83 +0,0 @@
|
||||
<script lang="ts" setup> |
||||
import TenantPackageModal from './TenantPackageModal.vue' |
||||
import { columns, searchFormSchema } from './tenantPackage.data' |
||||
import { useI18n } from '@/hooks/web/useI18n' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
import { useModal } from '@/components/Modal' |
||||
import { IconEnum } from '@/enums/appEnum' |
||||
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
import { deleteTenantPackage, getTenantPackagePage } from '@/api/system/tenantPackage' |
||||
|
||||
defineOptions({ name: 'SystemTenantPackage' }) |
||||
|
||||
const { t } = useI18n() |
||||
const { createMessage } = useMessage() |
||||
const [registerModal, { openModal }] = useModal() |
||||
const [registerTable, { reload }] = useTable({ |
||||
title: '租户套餐列表', |
||||
api: getTenantPackagePage, |
||||
columns, |
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
||||
useSearchForm: true, |
||||
showTableSetting: true, |
||||
showIndexColumn: false, |
||||
actionColumn: { |
||||
width: 140, |
||||
title: t('common.action'), |
||||
dataIndex: 'action', |
||||
fixed: 'right', |
||||
}, |
||||
}) |
||||
|
||||
function handleCreate() { |
||||
openModal(true, { isUpdate: false }) |
||||
} |
||||
|
||||
function handleEdit(record: Recordable) { |
||||
openModal(true, { record, isUpdate: true }) |
||||
} |
||||
|
||||
async function handleDelete(record: Recordable) { |
||||
await deleteTenantPackage(record.id) |
||||
createMessage.success(t('common.delSuccessText')) |
||||
reload() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<BasicTable @register="registerTable"> |
||||
<template #toolbar> |
||||
<a-button v-auth="['system:tenant-package:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
{{ t('action.create') }} |
||||
</a-button> |
||||
</template> |
||||
<template #bodyCell="{ column, record }"> |
||||
<template v-if="column.key === 'action'"> |
||||
<TableAction |
||||
:actions="[ |
||||
{ |
||||
icon: IconEnum.EDIT, |
||||
label: t('action.edit'), |
||||
auth: 'system:tenant-package:update', |
||||
onClick: handleEdit.bind(null, record), |
||||
}, |
||||
{ |
||||
icon: IconEnum.DELETE, |
||||
danger: true, |
||||
label: t('action.delete'), |
||||
auth: 'system:tenant-package:delete', |
||||
popConfirm: { |
||||
title: t('common.delMessage'), |
||||
placement: 'left', |
||||
confirm: handleDelete.bind(null, record), |
||||
}, |
||||
}, |
||||
]" |
||||
/> |
||||
</template> |
||||
</template> |
||||
</BasicTable> |
||||
<TenantPackageModal @register="registerModal" @success="reload()" /> |
||||
</div> |
||||
</template> |
@ -1,89 +0,0 @@
|
||||
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
||||
export const columns: BasicColumn[] = [ |
||||
{ |
||||
title: '套餐编号', |
||||
dataIndex: 'id', |
||||
width: 100, |
||||
}, |
||||
{ |
||||
title: '套餐名', |
||||
dataIndex: 'name', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '状态', |
||||
dataIndex: 'status', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDict(text, DICT_TYPE.COMMON_STATUS) |
||||
}, |
||||
}, |
||||
{ |
||||
title: '备注', |
||||
dataIndex: 'remark', |
||||
width: 180, |
||||
}, |
||||
{ |
||||
title: '创建时间', |
||||
dataIndex: 'createTime', |
||||
width: 180, |
||||
customRender: ({ text }) => { |
||||
return useRender.renderDate(text) |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
export const searchFormSchema: FormSchema[] = [ |
||||
{ |
||||
label: '套餐名', |
||||
field: 'name', |
||||
component: 'Input', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
colProps: { span: 8 }, |
||||
}, |
||||
{ |
||||
label: '创建时间', |
||||
field: 'createTime', |
||||
component: 'RangePicker', |
||||
colProps: { span: 8 }, |
||||
}, |
||||
] |
||||
|
||||
export const formSchema: FormSchema[] = [ |
||||
{ |
||||
label: '编号', |
||||
field: 'id', |
||||
show: false, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '套餐名', |
||||
field: 'name', |
||||
required: true, |
||||
component: 'Input', |
||||
}, |
||||
{ |
||||
label: '菜单权限', |
||||
field: 'menuIds', |
||||
slot: 'menuIds', |
||||
}, |
||||
{ |
||||
label: '状态', |
||||
field: 'status', |
||||
component: 'Select', |
||||
componentProps: { |
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
}, |
||||
}, |
||||
] |
Reference in new issue