系统管理

This commit is contained in:
ym1026
2025-09-05 16:40:35 +08:00
parent c778e4a300
commit c1cce63c85
24 changed files with 2220 additions and 411 deletions

View File

@@ -1,36 +1,10 @@
const btnList = [
{ label: '', type: '', disFlag: '' },
{ label: '新增', type: 'add', disFlag: 'isEdit', icon: 'icon-add' },
{ label: '更新', type: 'edit', disFlag: 'isEdit' },
{ label: '查看', type: 'detail', disFlag: 'isQuery' },
{ label: '编辑', type: 'edit', disFlag: 'isEdit' },
{ label: '删除', type: 'del', disFlag: 'isEdit', icon: 'icon-del' },
{ label: '批量删除', type: 'del', disFlag: 'isEdit', icon: 'icon-del' },
{ label: '导入', type: 'upload', disFlag: 'isEdit', icon: 'icon-import' },
{ label: '导出', type: 'download', disFlag: 'isEdit', icon: 'icon-export' },
{ label: '上传', type: 'upload', disFlag: 'isEdit', icon: 'icon-upload' },
{ label: '下载', type: 'download', disFlag: 'isEdit', icon: 'icon-download' },
{ label: '下发', type: 'xf', disFlag: 'isControl' },
{ label: '批量下载', type: 'download', disFlag: 'isEdit', icon: 'icon-download' },
{ label: '下载模版', type: 'downTemplate', disFlag: 'isControl', icon: 'icon-download' },
{ label: '重置密码', type: 'reset', disFlag: 'isEdit' },
{ label: '派发', type: 'distribute', disFlag: 'isControl' },
{ label: '处理', type: 'dealWith', disFlag: 'isControl' },
{ label: '审核', type: 'audit', disFlag: 'isControl' },
{ label: '标记为已读', type: 'setTagR', disFlag: 'isControl', icon: 'icon-chulizhuangtai' },
{ label: '标记为已处理', type: 'setTagD', disFlag: 'isControl' },
{ label: '启动', type: 'start', disFlag: 'isControl' },
{ label: '停止', type: 'stop', disFlag: 'isControl' },
{ label: '重启', type: 'restart', disFlag: 'isControl' },
{ label: '批量启动', type: 'start', disFlag: 'isControl' },
{ label: '批量停止', type: 'stop', disFlag: 'isControl' },
{ label: '批量重启', type: 'restart', disFlag: 'isControl' },
{ label: '监控日志', type: 'log', disFlag: 'isControl' },
{ label: '新建备份', type: 'backups', disFlag: 'isEdit', icon: 'icon-add' },
{ label: '导入备份', type: 'importBackups', disFlag: 'isEdit', icon: 'icon-import' },
{ label: '还原', type: 'restore', disFlag: 'isEdit' },
{ label: '批量启用', type: 'enable', disFlag: 'isControl', icon: 'icon-a-qiyong' },
{ label: '批量禁用', type: 'disable', disFlag: 'isControl', icon: 'icon-a-jinyong' }
{ label: '查看', type: 'read', disFlag: 'isQuery' },
{ label: '修改', type: 'edit', disFlag: 'isEdit' },
{ label: '删除', type: 'del', disFlag: 'isEdit', icon: 'icon-del' }
// { label: '批量删除', type: 'del', disFlag: 'isEdit', icon: 'icon-del' }
]
// arr:按钮数组
@@ -45,7 +19,7 @@ function getBtns(arr) {
const btns = []
btnList.forEach((item) => {
if (arr.includes(item.label)) {
item.disabled = !Boolean(permissions[item.disFlag])
// item.disabled = !Boolean(permissions[item.disFlag])
btns.push(item)
}
})

View File

@@ -69,7 +69,7 @@ const colWidth = [
{
label: '操作',
align: 'center',
width: 130,
width: 200,
fixed: 'right',
resizable: false
}

116
web/src/utils/decorator.js Normal file
View File

@@ -0,0 +1,116 @@
let validateRulesObj = {
phone: {
rules: [
{
validator: (rule, value, callback) => {
const reg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/
if (value === '') {
return Promise.resolve()
} else if (!reg.test(value)) {
return Promise.reject(new Error('请输入正确的手机号码'))
}
return Promise.resolve()
}
}
]
},
email: {
rules: [
{
validator: (rule, value, callback) => {
const reg =
/^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/
if (!reg.test(value)) {
return Promise.reject(new Error('请输入正确的邮箱'))
}
return Promise.resolve()
}
}
]
},
pwd: {
rules: [
{
validator: (rule, value, callback) => {
const reg = /^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,20}$/
if (!reg.test(value)) {
return Promise.reject(new Error('请输入密码,密码由6-20位字母、字符或数字组成'))
}
return Promise.resolve()
}
}
]
},
// 新密码与旧密码是否一致校验
checkOpwd: {
rules: [
{
validator: (rule, value, callback) => {
// 获取旧密码
let opwd = this.props.form.getFieldValue('oldPsd')
if (!(opwd && opwd !== value)) {
return Promise.reject(new Error('旧密码与新密码一致'))
} else {
return Promise.resolve()
}
}
}
]
},
gphone: {
rules: [
{
validator: (rule, value, callback) => {
const reg = /^([0-9]{3,4}-)?[0-9]{7,8}$/
if (!reg.test(value)) {
return Promise.reject(new Error('请输入正确的固定电话'))
} else {
return Promise.resolve()
}
}
}
]
},
lng: {
rules: [
{
validator: (rule, value, callback) => {
const reg =
/^(\-|\+)?(((\d|[1-9]\d|1[0-7]\d|0{1,3})\.\d{0,6})|(\d|[1-9]\d|1[0-7]\d|0{1,3})|180\.0{0,6}|180)$/
if (value !== '' && value !== null && value !== undefined) {
if (!reg.test(value)) {
return Promise.reject(new Error('经度整数部分为-180 至 180,小数部分为0到6位!'))
} else {
return Promise.resolve()
}
} else {
return Promise.resolve()
}
}
}
]
},
lat: {
rules: [
{
validator: (rule, value, callback) => {
const reg = /^(\-|\+)?([0-8]?\d{1}\.\d{0,6}|90\.0{0,6}|[0-8]?\d{1}|90)$/
if (value !== '' && value !== null && value !== undefined) {
if (!reg.test(value)) {
return Promise.reject(new Error('纬度整数部分为-90 至 90,小数部分为0到6位!'))
} else {
return Promise.resolve()
}
} else {
return Promise.resolve()
}
}
}
]
}
}
export default validateRulesObj

View File

@@ -0,0 +1,59 @@
import { notification } from 'ant-design-vue'
import { h } from 'vue'
import {
CheckCircleFilled,
CloseCircleFilled,
ExclamationCircleFilled
} from '@ant-design/icons-vue'
// name:页面名称,角色、人员、系统等
// typeaddeditdeldetail
// statussuccesserrorwarning
// desc: 描述
const option = {
names: {
user: '用户管理'
},
types: {
// isDealWith: '标记为已处理',
// isRead: '标记为已读'
},
status: { success: '成功', error: '失败', warning: '警告' }
}
const notiInfo = {
success: {
iconMessage: '成功通知',
icon: CheckCircleFilled,
iconColor: 'color:#065758',
iconClass: 'notification-success-class'
},
error: {
iconMessage: '失败通知',
icon: CloseCircleFilled,
iconColor: 'color:#ca4d2a',
iconClass: 'notification-error-class'
},
warning: {
iconMessage: '警告通知',
icon: ExclamationCircleFilled,
iconColor: 'color:#FF921B',
iconClass: 'notification-warning-class'
}
}
const openNotification = ({ name, type, status, desc = '' }) => {
notification[status]({
placement: 'bottomRight',
message: notiInfo[status].iconMessage,
description: desc || option.names[name] + option.types[type] + option.status[status],
icon: () =>
h(notiInfo[status].icon, {
style: notiInfo[status].iconColor
}),
style: {
minWidth: '400px'
},
class: notiInfo[status].iconClass,
duration: 2
})
}
export default openNotification