mirror of https://gitee.com/xiaonuobase/snowy
【更新】前端依赖大升级,业务代码等多处优化调整,完全去掉以往this.xxx等语法。
parent
a216d0ccff
commit
4f9de9fc9a
|
@ -19,70 +19,70 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@amap/amap-jsapi-loader": "1.0.1",
|
"@amap/amap-jsapi-loader": "1.0.1",
|
||||||
"@ant-design/colors": "7.0.0",
|
"@ant-design/colors": "7.0.0",
|
||||||
"@ant-design/icons-vue": "6.1.0",
|
"@ant-design/icons-vue": "7.0.1",
|
||||||
"@antv/g2plot": "2.4.28",
|
"@antv/g2plot": "2.4.31",
|
||||||
"@chenfengyuan/vue-qrcode": "2.0.0",
|
"@chenfengyuan/vue-qrcode": "2.0.0",
|
||||||
"@highlightjs/vue-plugin": "2.1.0",
|
"@highlightjs/vue-plugin": "2.1.0",
|
||||||
"@tinymce/tinymce-vue": "5.0.0",
|
"@tinymce/tinymce-vue": "5.1.1",
|
||||||
"@vue-office/docx": "1.2.0",
|
"@vue-office/docx": "1.3.2",
|
||||||
"@vue-office/excel": "1.2.0",
|
"@vue-office/excel": "1.4.7",
|
||||||
"@vue-office/pdf": "1.2.0",
|
"@vue-office/pdf": "1.5.5",
|
||||||
"ant-design-vue": "3.2.14",
|
"ant-design-vue": "3.2.14",
|
||||||
"axios": "1.1.3",
|
"axios": "1.6.2",
|
||||||
"cropperjs": "1.5.12",
|
"cropperjs": "1.6.1",
|
||||||
"dayjs": "1.11.7",
|
"dayjs": "1.11.10",
|
||||||
"echarts": "5.4.0",
|
"echarts": "5.4.3",
|
||||||
"echarts-stat": "1.2.0",
|
"echarts-stat": "1.2.0",
|
||||||
"enquire.js": "2.1.6",
|
"enquire.js": "2.1.6",
|
||||||
"event-source-polyfill": "1.0.31",
|
"event-source-polyfill": "1.0.31",
|
||||||
"fuse.js": "6.6.2",
|
"fuse.js": "7.0.0",
|
||||||
"highlight.js": "11.6.0",
|
"highlight.js": "11.9.0",
|
||||||
"hotkeys-js": "3.10.1",
|
"hotkeys-js": "3.12.2",
|
||||||
"js-pinyin": "0.1.9",
|
"js-pinyin": "0.2.5",
|
||||||
"lodash-es": "4.17.21",
|
"lodash-es": "4.17.21",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"pinia": "2.0.33",
|
"pinia": "2.1.7",
|
||||||
"qs": "6.11.1",
|
"qs": "6.11.2",
|
||||||
"screenfull": "6.0.2",
|
"screenfull": "6.0.2",
|
||||||
"sm-crypto": "0.3.11",
|
"sm-crypto": "0.3.13",
|
||||||
"snowflake-id": "1.1.0",
|
"snowflake-id": "1.1.0",
|
||||||
"sortablejs": "1.15.0",
|
"sortablejs": "1.15.1",
|
||||||
"tinymce": "6.2.0",
|
"tinymce": "6.8.1",
|
||||||
"vue": "3.2.44",
|
"vue": "3.3.10",
|
||||||
"vue-cropper": "1.0.5",
|
"vue-cropper": "1.1.1",
|
||||||
"vue-demi": "0.13.11",
|
"vue-demi": "0.13.11",
|
||||||
"vue-i18n": "9.2.2",
|
"vue-i18n": "9.8.0",
|
||||||
"vue-router": "4.1.6",
|
"vue-router": "4.2.5",
|
||||||
"vue3-colorpicker": "2.0.4",
|
"vue3-colorpicker": "2.2.3",
|
||||||
"vue3-tree-org": "4.2.2",
|
"vue3-tree-org": "4.2.2",
|
||||||
"vuedraggable-es": "4.1.1"
|
"vuedraggable-es": "4.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@antfu/eslint-config": "0.29.4",
|
"@antfu/eslint-config": "0.29.4",
|
||||||
"@babel/eslint-parser": "7.19.1",
|
"@babel/eslint-parser": "7.19.1",
|
||||||
"@vitejs/plugin-legacy": "3.0.2",
|
"@vitejs/plugin-legacy": "5.2.0",
|
||||||
"@vitejs/plugin-vue": "4.1.0",
|
"@vitejs/plugin-vue": "4.5.2",
|
||||||
"@vitejs/plugin-vue-jsx": "3.0.1",
|
"@vitejs/plugin-vue-jsx": "3.1.0",
|
||||||
"@vue/compiler-sfc": "3.2.47",
|
"@vue/compiler-sfc": "3.3.10",
|
||||||
"@vue/eslint-config-standard": "8.0.1",
|
"@vue/eslint-config-standard": "8.0.1",
|
||||||
"antd-less-to-css-variable": "1.0.5",
|
"antd-less-to-css-variable": "1.0.5",
|
||||||
"autoprefixer": "10.4.13",
|
"autoprefixer": "10.4.16",
|
||||||
"eslint": "8.26.0",
|
"eslint": "8.55.0",
|
||||||
"eslint-config-prettier": "8.5.0",
|
"eslint-config-prettier": "9.1.0",
|
||||||
"eslint-plugin-prettier": "4.2.1",
|
"eslint-plugin-prettier": "5.0.1",
|
||||||
"eslint-plugin-vue": "9.7.0",
|
"eslint-plugin-vue": "9.7.0",
|
||||||
"less": "4.1.3",
|
"less": "4.1.3",
|
||||||
"postcss": "8.4.21",
|
"postcss": "8.4.32",
|
||||||
"prettier": "2.8.7",
|
"prettier": "3.1.0",
|
||||||
"rollup-plugin-visualizer": "5.8.3",
|
"rollup-plugin-visualizer": "5.10.0",
|
||||||
"tailwindcss": "3.2.7",
|
"tailwindcss": "3.3.6",
|
||||||
"typescript": "4.9.5",
|
"typescript": "5.3.3",
|
||||||
"unplugin-auto-import": "0.15.2",
|
"unplugin-auto-import": "0.17.2",
|
||||||
"unplugin-vue-components": "0.24.1",
|
"unplugin-vue-components": "0.26.0",
|
||||||
"vite": "4.2.1",
|
"vite": "5.0.6",
|
||||||
"vite-plugin-compression": "0.5.1",
|
"vite-plugin-compression": "0.5.1",
|
||||||
"vite-plugin-vue-setup-extend": "0.4.0",
|
"vite-plugin-vue-setup-extend": "0.4.0",
|
||||||
"vue-eslint-parser": "9.1.0"
|
"vue-eslint-parser": "9.3.2"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"> 1%",
|
"> 1%",
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/auth/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/auth/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 绘画
|
* 绘画
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/auth/third/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/auth/third/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 三方登录
|
* 三方登录
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/auth/third/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/auth/third/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 三方用户
|
* 三方用户
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/biz/dict/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/biz/dict/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 字典
|
* 字典
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/biz/org/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/biz/org/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 机构
|
* 机构
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/biz/position/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/biz/position/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 岗位
|
* 岗位
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/biz/user/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/biz/user/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 人员接口api
|
* 人员接口api
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/dev/config/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/dev/config/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 配置
|
* 配置
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/dev/dict/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/dev/dict/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 字典
|
* 字典
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/dev/email/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/dev/email/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 邮件
|
* 邮件
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/dev/file/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/dev/file/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 文件
|
* 文件
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/dev/job/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/dev/job/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 定时任务
|
* 定时任务
|
||||||
*
|
*
|
||||||
|
@ -22,10 +22,6 @@ export default {
|
||||||
jobPage(data) {
|
jobPage(data) {
|
||||||
return request('page', data, 'get')
|
return request('page', data, 'get')
|
||||||
},
|
},
|
||||||
// 获取定时任务列表
|
|
||||||
jobList(data) {
|
|
||||||
return request('list', data, 'get')
|
|
||||||
},
|
|
||||||
// 提交表单 edit为true时为编辑,默认为新增
|
// 提交表单 edit为true时为编辑,默认为新增
|
||||||
submitForm(data, edit = false) {
|
submitForm(data, edit = false) {
|
||||||
return request(edit ? 'edit' : 'add', data)
|
return request(edit ? 'edit' : 'add', data)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/dev/log/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/dev/log/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 日志
|
* 日志
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/dev/message/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/dev/message/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 站内信
|
* 站内信
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/dev/monitor/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/dev/monitor/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 监控
|
* 监控
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/dev/sms/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/dev/sms/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 短信
|
* 短信
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/gen/basic/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/gen/basic/` + url, ...arg)
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// 获取代码生成基础分页
|
// 获取代码生成基础分页
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/gen/config/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/gen/config/` + url, ...arg)
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// 获取代码生成详情配置列表
|
// 获取代码生成详情配置列表
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/mobile/button/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/mobile/button/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 按钮
|
* 按钮
|
||||||
*
|
*
|
||||||
|
|
|
@ -13,10 +13,6 @@ export default {
|
||||||
mobileMenuTree(data) {
|
mobileMenuTree(data) {
|
||||||
return request('tree', data, 'get')
|
return request('tree', data, 'get')
|
||||||
},
|
},
|
||||||
// 获取移动端菜单列表
|
|
||||||
mobileMenuList(data) {
|
|
||||||
return request('list', data, 'get')
|
|
||||||
},
|
|
||||||
// 提交移动端菜单表单 edit为true时为编辑,默认为新增
|
// 提交移动端菜单表单 edit为true时为编辑,默认为新增
|
||||||
mobileMenuSubmitForm(data, edit = false) {
|
mobileMenuSubmitForm(data, edit = false) {
|
||||||
return request(edit ? 'edit' : 'add', data)
|
return request(edit ? 'edit' : 'add', data)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/mobile/module/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/mobile/module/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 类别
|
* 类别
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/sys/index/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/sys/index/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 系统首页控制器
|
* 系统首页控制器
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/sys/org/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/sys/org/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 机构
|
* 机构
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/sys/position/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/sys/position/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 职位
|
* 职位
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/sys/button/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/sys/button/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 按钮
|
* 按钮
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/sys/field/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/sys/field/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 字段
|
* 字段
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/sys/menu/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/sys/menu/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 菜单
|
* 菜单
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/sys/module/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/sys/module/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 模块
|
* 模块
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/sys/role/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/sys/role/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 角色
|
* 角色
|
||||||
*
|
*
|
||||||
|
@ -22,10 +22,6 @@ export default {
|
||||||
rolePage(data) {
|
rolePage(data) {
|
||||||
return request('page', data, 'get')
|
return request('page', data, 'get')
|
||||||
},
|
},
|
||||||
// 获取角色列表
|
|
||||||
roleList(data) {
|
|
||||||
return request('list', data, 'get')
|
|
||||||
},
|
|
||||||
// 提交表单 edit为true时为编辑,默认为新增
|
// 提交表单 edit为true时为编辑,默认为新增
|
||||||
submitForm(data, edit = false) {
|
submitForm(data, edit = false) {
|
||||||
return request(edit ? 'edit' : 'add', data)
|
return request(edit ? 'edit' : 'add', data)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/sys/user/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/sys/user/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 用户接口api
|
* 用户接口api
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
import { baseRequest } from '@/utils/request'
|
import { baseRequest } from '@/utils/request'
|
||||||
|
|
||||||
const request = (url, ...arg) => baseRequest(`/sys/userCenter/${url}`, ...arg)
|
const request = (url, ...arg) => baseRequest(`/sys/userCenter/` + url, ...arg)
|
||||||
/**
|
/**
|
||||||
* 用户个人控制器
|
* 用户个人控制器
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
export const getYear = () => {
|
||||||
|
let v = []
|
||||||
|
let y = new Date().getFullYear()
|
||||||
|
for (let i = 0; i < 11; i++) {
|
||||||
|
v.push(y + i)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
export const data = {
|
||||||
|
second: ['0', '5', '15', '20', '25', '30', '35', '40', '45', '50', '55', '59'],
|
||||||
|
minute: ['0', '5', '15', '20', '25', '30', '35', '40', '45', '50', '55', '59'],
|
||||||
|
hour: [
|
||||||
|
'0',
|
||||||
|
'1',
|
||||||
|
'2',
|
||||||
|
'3',
|
||||||
|
'4',
|
||||||
|
'5',
|
||||||
|
'6',
|
||||||
|
'7',
|
||||||
|
'8',
|
||||||
|
'9',
|
||||||
|
'10',
|
||||||
|
'11',
|
||||||
|
'12',
|
||||||
|
'13',
|
||||||
|
'14',
|
||||||
|
'15',
|
||||||
|
'16',
|
||||||
|
'17',
|
||||||
|
'18',
|
||||||
|
'19',
|
||||||
|
'20',
|
||||||
|
'21',
|
||||||
|
'22',
|
||||||
|
'23'
|
||||||
|
],
|
||||||
|
day: [
|
||||||
|
'1',
|
||||||
|
'2',
|
||||||
|
'3',
|
||||||
|
'4',
|
||||||
|
'5',
|
||||||
|
'6',
|
||||||
|
'7',
|
||||||
|
'8',
|
||||||
|
'9',
|
||||||
|
'10',
|
||||||
|
'11',
|
||||||
|
'12',
|
||||||
|
'13',
|
||||||
|
'14',
|
||||||
|
'15',
|
||||||
|
'16',
|
||||||
|
'17',
|
||||||
|
'18',
|
||||||
|
'19',
|
||||||
|
'20',
|
||||||
|
'21',
|
||||||
|
'22',
|
||||||
|
'23',
|
||||||
|
'24',
|
||||||
|
'25',
|
||||||
|
'26',
|
||||||
|
'27',
|
||||||
|
'28',
|
||||||
|
'29',
|
||||||
|
'30',
|
||||||
|
'31'
|
||||||
|
],
|
||||||
|
month: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
|
||||||
|
week: [
|
||||||
|
{
|
||||||
|
value: '1',
|
||||||
|
label: '周日'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '2',
|
||||||
|
label: '周一'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '3',
|
||||||
|
label: '周二'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '4',
|
||||||
|
label: '周三'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '5',
|
||||||
|
label: '周四'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '6',
|
||||||
|
label: '周五'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '7',
|
||||||
|
label: '周六'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
year: getYear()
|
||||||
|
}
|
|
@ -405,18 +405,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="XnCron">
|
<script setup name="XnCron">
|
||||||
|
import { data, getYear } from './data.js'
|
||||||
const activeKey = ref('1')
|
const activeKey = ref('1')
|
||||||
const type = ref('0')
|
|
||||||
const defaultValue = ref('')
|
const defaultValue = ref('')
|
||||||
const modalVisible = ref(false)
|
const modalVisible = ref(false)
|
||||||
const getYear = () => {
|
|
||||||
let v = []
|
|
||||||
let y = new Date().getFullYear()
|
|
||||||
for (let i = 0; i < 11; i++) {
|
|
||||||
v.push(y + i)
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
const dateValue = ref({
|
const dateValue = ref({
|
||||||
second: {
|
second: {
|
||||||
type: '0',
|
type: '0',
|
||||||
|
@ -504,101 +496,6 @@
|
||||||
appoint: []
|
appoint: []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const data = {
|
|
||||||
second: ['0', '5', '15', '20', '25', '30', '35', '40', '45', '50', '55', '59'],
|
|
||||||
minute: ['0', '5', '15', '20', '25', '30', '35', '40', '45', '50', '55', '59'],
|
|
||||||
hour: [
|
|
||||||
'0',
|
|
||||||
'1',
|
|
||||||
'2',
|
|
||||||
'3',
|
|
||||||
'4',
|
|
||||||
'5',
|
|
||||||
'6',
|
|
||||||
'7',
|
|
||||||
'8',
|
|
||||||
'9',
|
|
||||||
'10',
|
|
||||||
'11',
|
|
||||||
'12',
|
|
||||||
'13',
|
|
||||||
'14',
|
|
||||||
'15',
|
|
||||||
'16',
|
|
||||||
'17',
|
|
||||||
'18',
|
|
||||||
'19',
|
|
||||||
'20',
|
|
||||||
'21',
|
|
||||||
'22',
|
|
||||||
'23'
|
|
||||||
],
|
|
||||||
day: [
|
|
||||||
'1',
|
|
||||||
'2',
|
|
||||||
'3',
|
|
||||||
'4',
|
|
||||||
'5',
|
|
||||||
'6',
|
|
||||||
'7',
|
|
||||||
'8',
|
|
||||||
'9',
|
|
||||||
'10',
|
|
||||||
'11',
|
|
||||||
'12',
|
|
||||||
'13',
|
|
||||||
'14',
|
|
||||||
'15',
|
|
||||||
'16',
|
|
||||||
'17',
|
|
||||||
'18',
|
|
||||||
'19',
|
|
||||||
'20',
|
|
||||||
'21',
|
|
||||||
'22',
|
|
||||||
'23',
|
|
||||||
'24',
|
|
||||||
'25',
|
|
||||||
'26',
|
|
||||||
'27',
|
|
||||||
'28',
|
|
||||||
'29',
|
|
||||||
'30',
|
|
||||||
'31'
|
|
||||||
],
|
|
||||||
month: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
|
|
||||||
week: [
|
|
||||||
{
|
|
||||||
value: '1',
|
|
||||||
label: '周日'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '2',
|
|
||||||
label: '周一'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '3',
|
|
||||||
label: '周二'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '4',
|
|
||||||
label: '周三'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '5',
|
|
||||||
label: '周四'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '6',
|
|
||||||
label: '周五'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '7',
|
|
||||||
label: '周六'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
year: getYear()
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
|
@ -610,111 +507,62 @@
|
||||||
default: () => []
|
default: () => []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const value_second = computed(() => {
|
const setRules = (v) => {
|
||||||
let v = dateValue.value.second
|
switch (v.type) {
|
||||||
if (v.type === '0') {
|
case '0':
|
||||||
return '*'
|
return '*'
|
||||||
} else if (v.type === '1') {
|
case '1':
|
||||||
return v.range.start + '-' + v.range.end
|
return v.range.start + '-' + v.range.end
|
||||||
} else if (v.type === '2') {
|
case '2':
|
||||||
return v.loop.start + '/' + v.loop.end
|
return v.loop.start + '/' + v.loop.end
|
||||||
} else if (v.type === '3') {
|
case '3':
|
||||||
return v.appoint.length > 0 ? v.appoint.join(',') : '*'
|
return v.appoint.length > 0 ? v.appoint.join(',') : '*'
|
||||||
} else {
|
case '4':
|
||||||
|
return 'L'
|
||||||
|
case '5':
|
||||||
|
return '?'
|
||||||
|
default:
|
||||||
return '*'
|
return '*'
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
const value_second = computed(() => {
|
||||||
|
let v = dateValue.value.second
|
||||||
|
return setRules(v)
|
||||||
})
|
})
|
||||||
const value_minute = computed(() => {
|
const value_minute = computed(() => {
|
||||||
let v = dateValue.value.minute
|
let v = dateValue.value.minute
|
||||||
if (v.type === '0') {
|
return setRules(v)
|
||||||
return '*'
|
|
||||||
} else if (v.type === '1') {
|
|
||||||
return v.range.start + '-' + v.range.end
|
|
||||||
} else if (v.type === '2') {
|
|
||||||
return v.loop.start + '/' + v.loop.end
|
|
||||||
} else if (v.type === '3') {
|
|
||||||
return v.appoint.length > 0 ? v.appoint.join(',') : '*'
|
|
||||||
} else {
|
|
||||||
return '*'
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
const value_hour = computed(() => {
|
const value_hour = computed(() => {
|
||||||
let v = dateValue.value.hour
|
let v = dateValue.value.hour
|
||||||
if (v.type === '0') {
|
return setRules(v)
|
||||||
return '*'
|
|
||||||
} else if (v.type === '1') {
|
|
||||||
return v.range.start + '-' + v.range.end
|
|
||||||
} else if (v.type === '2') {
|
|
||||||
return v.loop.start + '/' + v.loop.end
|
|
||||||
} else if (v.type === '3') {
|
|
||||||
return v.appoint.length > 0 ? v.appoint.join(',') : '*'
|
|
||||||
} else {
|
|
||||||
return '*'
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
const value_day = computed(() => {
|
const value_day = computed(() => {
|
||||||
let v = dateValue.value.day
|
let v = dateValue.value.day
|
||||||
if (v.type === '0') {
|
return setRules(v)
|
||||||
return '*'
|
|
||||||
} else if (v.type === '1') {
|
|
||||||
return v.range.start + '-' + v.range.end
|
|
||||||
} else if (v.type === '2') {
|
|
||||||
return v.loop.start + '/' + v.loop.end
|
|
||||||
} else if (v.type === '3') {
|
|
||||||
return v.appoint.length > 0 ? v.appoint.join(',') : '*'
|
|
||||||
} else if (v.type === '4') {
|
|
||||||
return 'L'
|
|
||||||
} else if (v.type === '5') {
|
|
||||||
return '?'
|
|
||||||
} else {
|
|
||||||
return '*'
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
const value_month = computed(() => {
|
const value_month = computed(() => {
|
||||||
let v = dateValue.value.month
|
let v = dateValue.value.month
|
||||||
if (v.type === '0') {
|
return setRules(v)
|
||||||
return '*'
|
|
||||||
} else if (v.type === '1') {
|
|
||||||
return v.range.start + '-' + v.range.end
|
|
||||||
} else if (v.type === '2') {
|
|
||||||
return v.loop.start + '/' + v.loop.end
|
|
||||||
} else if (v.type === '3') {
|
|
||||||
return v.appoint.length > 0 ? v.appoint.join(',') : '*'
|
|
||||||
} else {
|
|
||||||
return '*'
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
const value_week = computed(() => {
|
const value_week = computed(() => {
|
||||||
let v = dateValue.value.week
|
let v = dateValue.value.week
|
||||||
if (v.type === '0') {
|
return setRules(v)
|
||||||
return '*'
|
|
||||||
} else if (v.type === '1') {
|
|
||||||
return v.range.start + '-' + v.range.end
|
|
||||||
} else if (v.type === '2') {
|
|
||||||
return v.loop.end + '#' + v.loop.start
|
|
||||||
} else if (v.type === '3') {
|
|
||||||
return v.appoint.length > 0 ? v.appoint.join(',') : '*'
|
|
||||||
} else if (v.type === '4') {
|
|
||||||
return v.last + 'L'
|
|
||||||
} else if (v.type === '5') {
|
|
||||||
return '?'
|
|
||||||
} else {
|
|
||||||
return '*'
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
const value_year = computed(() => {
|
const value_year = computed(() => {
|
||||||
let v = dateValue.value.year
|
let v = dateValue.value.year
|
||||||
if (v.type === '-1') {
|
switch (v.type) {
|
||||||
|
case '-1':
|
||||||
return ''
|
return ''
|
||||||
} else if (v.type === '0') {
|
case '0':
|
||||||
return '*'
|
return '*'
|
||||||
} else if (v.type === '1') {
|
case '1':
|
||||||
return v.range.start + '-' + v.range.end
|
return v.range.start + '-' + v.range.end
|
||||||
} else if (v.type === '2') {
|
case '2':
|
||||||
return v.loop.start + '/' + v.loop.end
|
return v.loop.start + '/' + v.loop.end
|
||||||
} else if (v.type === '3') {
|
case '3':
|
||||||
return v.appoint.length > 0 ? v.appoint.join(',') : ''
|
return v.appoint.length > 0 ? v.appoint.join(',') : ''
|
||||||
} else {
|
default:
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<a-modal
|
<a-modal
|
||||||
:class="['my-modal', modalClass, simpleClass]"
|
:class="['my-modal', modalClass, simpleClass]"
|
||||||
:visible="visible"
|
:visible="visible"
|
||||||
v-bind="$props"
|
v-bind="props"
|
||||||
:width="modalWidth"
|
:width="modalWidth"
|
||||||
:wrap-class-name="wrapClassName + fullscreenClass"
|
:wrap-class-name="wrapClassName + fullscreenClass"
|
||||||
@cancel="handleCancel"
|
@cancel="handleCancel"
|
||||||
|
@ -27,24 +27,23 @@
|
||||||
<slot name="insertFooter"></slot>
|
<slot name="insertFooter"></slot>
|
||||||
<slot name="footer">
|
<slot name="footer">
|
||||||
<a-button @click="handleCancel">
|
<a-button @click="handleCancel">
|
||||||
{{ $props.cancelText || '取消' }}
|
{{ props.cancelText || '取消' }}
|
||||||
</a-button>
|
</a-button>
|
||||||
<slot name="centerFooter"></slot>
|
<slot name="centerFooter"></slot>
|
||||||
<a-button type="primary" @click="handleOk" :loading="loading">
|
<a-button type="primary" @click="handleOk" :loading="loading">
|
||||||
{{ $props.okText || '确定' }}
|
{{ props.okText || '确定' }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</slot>
|
</slot>
|
||||||
<slot name="appendFooter"></slot>
|
<slot name="appendFooter"></slot>
|
||||||
</template>
|
</template>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup>
|
||||||
import props from './props.js'
|
import mixinProps from './props.js'
|
||||||
|
import { useSlots } from 'vue'
|
||||||
export default {
|
const slots = useSlots()
|
||||||
name: 'DragModal',
|
const props = defineProps({
|
||||||
mixins: [props],
|
...mixinProps,
|
||||||
props: {
|
|
||||||
// 容器的类名
|
// 容器的类名
|
||||||
modalClass: {
|
modalClass: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -92,218 +91,194 @@
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: undefined
|
default: undefined
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
emits: ['ok', 'close', 'fullscreen'],
|
const emit = defineEmits(['ok', 'close', 'fullscreen'])
|
||||||
data() {
|
const modalWidth = ref('')
|
||||||
return {
|
const contain = ref(null)
|
||||||
modalWidth: '',
|
|
||||||
contain: null,
|
|
||||||
// 拖拽
|
// 拖拽
|
||||||
header: null,
|
const header = ref(null)
|
||||||
modalContent: null,
|
const modalContent = ref(null)
|
||||||
mouseDownX: 0,
|
const mouseDownX = ref(0)
|
||||||
mouseDownY: 0,
|
const mouseDownY = ref(0)
|
||||||
deltaX: 0,
|
const deltaX = ref(0)
|
||||||
deltaY: 0,
|
const deltaY = ref(0)
|
||||||
sumX: 0,
|
const sumX = ref(0)
|
||||||
sumY: 0,
|
const sumY = ref(0)
|
||||||
onmousedown: false,
|
const onmousedown = ref(false)
|
||||||
// 缩放
|
// 缩放
|
||||||
modalBody: null,
|
const modalBody = ref(null)
|
||||||
myBody: null,
|
const myBody = ref(null)
|
||||||
prevModalWidth: 0,
|
const prevModalWidth = ref(0)
|
||||||
prevModalHeight: 0,
|
const prevModalHeight = ref(0)
|
||||||
prevBodyWidth: 0,
|
const prevBodyWidth = ref(0)
|
||||||
prevBodyHeight: 0,
|
const prevBodyHeight = ref(0)
|
||||||
startX: 0,
|
const startX = ref(0)
|
||||||
startY: 0,
|
const startY = ref(0)
|
||||||
// 全屏
|
// 全屏
|
||||||
fullscreenClass: '',
|
const fullscreenClass = ref('')
|
||||||
fullscreenStatus: false
|
const fullscreenStatus = ref(false)
|
||||||
}
|
const slotKeys = computed(() => {
|
||||||
},
|
return Object.keys(slots)
|
||||||
computed: {
|
})
|
||||||
slotKeys() {
|
const simpleClass = computed(() => {
|
||||||
return Object.keys(this.$slots)
|
|
||||||
},
|
|
||||||
simpleClass() {
|
|
||||||
return Math.random().toString(36).substring(2)
|
return Math.random().toString(36).substring(2)
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
visible() {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.initialEvent(this.visible)
|
|
||||||
})
|
})
|
||||||
},
|
onMounted(() => {
|
||||||
fullscreenStatus() {
|
nextTick(() => {
|
||||||
this.fullscreenClass = this.fullscreenStatus ? ' full-modal' : ''
|
initialEvent(props.visible)
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.initialEvent(this.visible)
|
|
||||||
})
|
})
|
||||||
},
|
})
|
||||||
created() {},
|
watch(
|
||||||
beforeUnmount() {
|
() => props.visible,
|
||||||
this.removeMove()
|
(newValue) => {
|
||||||
document.removeEventListener('mouseup', this.removeUp, false)
|
nextTick(() => {
|
||||||
this.removeResize()
|
initialEvent(props.visible)
|
||||||
document.removeEventListener('mouseup', this.removeResize)
|
})
|
||||||
},
|
}
|
||||||
methods: {
|
)
|
||||||
changeWidth(width) {
|
watch(
|
||||||
this.modalWidth = width
|
() => fullscreenStatus.value,
|
||||||
},
|
(newValue) => {
|
||||||
handleFullScreen(e) {
|
fullscreenClass.value = fullscreenStatus.value ? ' full-modal' : ''
|
||||||
|
}
|
||||||
|
)
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
removeMove()
|
||||||
|
document.removeEventListener('mouseup', removeUp, false)
|
||||||
|
removeResize()
|
||||||
|
document.removeEventListener('mouseup', removeResize)
|
||||||
|
})
|
||||||
|
const changeWidth = (width) => {
|
||||||
|
modalWidth.value = width
|
||||||
|
}
|
||||||
|
const handleFullScreen = (e) => {
|
||||||
e?.stopPropagation()
|
e?.stopPropagation()
|
||||||
e?.preventDefault()
|
e?.preventDefault()
|
||||||
|
|
||||||
this.fullscreenStatus = !this.fullscreenStatus
|
fullscreenStatus.value = !fullscreenStatus.value
|
||||||
this.$emit('fullscreen', e)
|
emit('fullscreen', e)
|
||||||
},
|
}
|
||||||
handleOk(e) {
|
const handleOk = (e) => {
|
||||||
this.reset()
|
reset()
|
||||||
this.$emit('ok', e)
|
emit('ok', e)
|
||||||
},
|
}
|
||||||
handleCancel(e) {
|
const handleCancel = (e) => {
|
||||||
const classList = e.target?.classList
|
const classList = e.target?.classList
|
||||||
// 过滤自定义关闭按钮的空白区域
|
// 过滤自定义关闭按钮的空白区域
|
||||||
if (classList.contains('ant-modal-close-x') || classList.contains('ant-space-item')) {
|
if (classList.contains('ant-modal-close-x') || classList.contains('ant-space-item')) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.reset()
|
reset()
|
||||||
this.$emit('close', e)
|
emit('close', e)
|
||||||
},
|
|
||||||
reset() {
|
|
||||||
// 拖拽
|
|
||||||
this.mouseDownX = 0
|
|
||||||
this.mouseDownY = 0
|
|
||||||
this.deltaX = 0
|
|
||||||
this.deltaY = 0
|
|
||||||
this.sumX = 0
|
|
||||||
this.sumY = 0
|
|
||||||
// 缩放
|
|
||||||
this.prevModalWidth = 0
|
|
||||||
this.prevModalHeight = 0
|
|
||||||
this.prevBodyWidth = 0
|
|
||||||
this.prevBodyHeight = 0
|
|
||||||
this.startX = 0
|
|
||||||
this.startY = 0
|
|
||||||
// 全屏
|
|
||||||
this.fullscreenStatus = false
|
|
||||||
},
|
|
||||||
initialEvent(visible) {
|
|
||||||
// console.log('--------- 初始化')
|
|
||||||
// console.log('simpleClass===>', this.simpleClass)
|
|
||||||
// console.log('document===>', document)
|
|
||||||
if (visible) {
|
|
||||||
this.reset()
|
|
||||||
// 获取控件
|
|
||||||
document.removeEventListener('mouseup', this.removeUp, false)
|
|
||||||
this.contain = document.getElementsByClassName(this.simpleClass)[0]
|
|
||||||
// console.log('初始化-contain:', this.contain)
|
|
||||||
this.changeWidth(this.$props.width)
|
|
||||||
if (this.$props.drag === true) {
|
|
||||||
this.header = this.contain.getElementsByClassName('ant-modal-header')[0]
|
|
||||||
this.modalContent = this.contain.getElementsByClassName('ant-modal-content')[0]
|
|
||||||
this.header.style.cursor = 'all-scroll'
|
|
||||||
this.modalContent.style.left = 0
|
|
||||||
this.modalContent.style.transform = 'translate(0px,0px)'
|
|
||||||
// console.log('初始化-header:', this.header)
|
|
||||||
// console.log('初始化-modalContent:', this.modalContent)
|
|
||||||
// 拖拽事件监听
|
|
||||||
// this.contain.onmousedown = (event) => {
|
|
||||||
this.header.onmousedown = (event) => {
|
|
||||||
this.onmousedown = true
|
|
||||||
this.mouseDownX = event.pageX
|
|
||||||
this.mouseDownY = event.pageY
|
|
||||||
document.body.onselectstart = () => false
|
|
||||||
document.addEventListener('mousemove', this.handleMove, false)
|
|
||||||
}
|
}
|
||||||
document.addEventListener('mouseup', this.removeUp, false)
|
const reset = () => {
|
||||||
|
// 拖拽
|
||||||
|
mouseDownX.value = 0
|
||||||
|
mouseDownY.value = 0
|
||||||
|
deltaX.value = 0
|
||||||
|
deltaY.value = 0
|
||||||
|
sumX.value = 0
|
||||||
|
sumY.value = 0
|
||||||
|
// 缩放
|
||||||
|
prevModalWidth.value = 0
|
||||||
|
prevModalHeight.value = 0
|
||||||
|
prevBodyWidth.value = 0
|
||||||
|
prevBodyHeight.value = 0
|
||||||
|
startX.value = 0
|
||||||
|
startY.value = 0
|
||||||
|
// 全屏
|
||||||
|
fullscreenStatus.value = false
|
||||||
|
}
|
||||||
|
const initialEvent = (visible) => {
|
||||||
|
if (visible) {
|
||||||
|
reset()
|
||||||
|
// 获取控件
|
||||||
|
document.removeEventListener('mouseup', removeUp, false)
|
||||||
|
contain.value = document.getElementsByClassName(simpleClass.value)[0]
|
||||||
|
changeWidth(props.width)
|
||||||
|
if (props.drag === true) {
|
||||||
|
header.value = contain.value.getElementsByClassName('ant-modal-header')[0]
|
||||||
|
modalContent.value = contain.value.getElementsByClassName('ant-modal-content')[0]
|
||||||
|
header.value.style.cursor = 'all-scroll'
|
||||||
|
modalContent.value.style.left = 0
|
||||||
|
modalContent.value.style.transform = 'translate(0px,0px)'
|
||||||
|
// 拖拽事件监听
|
||||||
|
header.value.onmousedown = (event) => {
|
||||||
|
onmousedown.value = true
|
||||||
|
mouseDownX.value = event.pageX
|
||||||
|
mouseDownY.value = event.pageY
|
||||||
|
document.body.onselectstart = () => false
|
||||||
|
document.addEventListener('mousemove', handleMove, false)
|
||||||
|
}
|
||||||
|
document.addEventListener('mouseup', removeUp, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.$props.resize === true) {
|
if (props.resize === true) {
|
||||||
this.modalBody = this.contain.getElementsByClassName('ant-modal-content')[0]
|
modalBody.value = contain.value.getElementsByClassName('ant-modal-content')[0]
|
||||||
this.myBody = this.contain.getElementsByClassName('ant-modal-body')[0]
|
myBody.value = contain.value.getElementsByClassName('ant-modal-body')[0]
|
||||||
this.modalBody.style.overflow = 'hidden'
|
modalBody.value.style.overflow = 'hidden'
|
||||||
this.modalBody.style.resize = 'both'
|
modalBody.value.style.resize = 'both'
|
||||||
this.myBody.style.overflow = 'auto'
|
myBody.value.style.overflow = 'auto'
|
||||||
this.myBody.style.height = 'auto'
|
myBody.value.style.height = 'auto'
|
||||||
// console.log('初始化-modalBody:', this.modalBody)
|
|
||||||
// console.log('初始化-myBody:', this.myBody)
|
|
||||||
// 缩放事件监听
|
// 缩放事件监听
|
||||||
this.modalBody.onmousedown = (event) => {
|
modalBody.value.onmousedown = (event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
const rect = this.modalBody.getBoundingClientRect()
|
const rect = modalBody.value.getBoundingClientRect()
|
||||||
const rightBorder = rect.x + rect.width - 17
|
const rightBorder = rect.x + rect.width - 17
|
||||||
const bottomBorder = rect.y + rect.height - 17
|
const bottomBorder = rect.y + rect.height - 17
|
||||||
// console.log('rightBorder:' + rightBorder, 'clientX:' + event.clientX)
|
|
||||||
// console.log('bottomBorder:' + bottomBorder, 'clientY:' + event.clientY)
|
|
||||||
if (event.clientX >= rightBorder && event.clientY >= bottomBorder) {
|
if (event.clientX >= rightBorder && event.clientY >= bottomBorder) {
|
||||||
this.prevModalWidth = this.modalBody.offsetWidth
|
prevModalWidth.value = modalBody.value.offsetWidth
|
||||||
this.prevModalHeight = this.modalBody.offsetHeight
|
prevModalHeight.value = modalBody.value.offsetHeight
|
||||||
this.prevBodyWidth = this.myBody.offsetWidth
|
prevBodyWidth.value = myBody.value.offsetWidth
|
||||||
this.prevBodyHeight = this.myBody.offsetHeight
|
prevBodyHeight.value = myBody.value.offsetHeight
|
||||||
this.startX = event.clientX
|
startX.value = event.clientX
|
||||||
this.startY = event.clientY
|
startY.value = event.clientY
|
||||||
|
document.addEventListener('mousemove', handleResize)
|
||||||
document.addEventListener('mousemove', this.handleResize)
|
|
||||||
}
|
}
|
||||||
document.addEventListener('mouseup', this.removeResize)
|
document.addEventListener('mouseup', removeResize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
handleMove(event) {
|
const handleMove = (event) => {
|
||||||
if (this.fullscreenStatus) {
|
if (fullscreenStatus.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const delta1X = event.pageX - this.mouseDownX
|
const delta1X = event.pageX - mouseDownX.value
|
||||||
const delta1Y = event.pageY - this.mouseDownY
|
const delta1Y = event.pageY - mouseDownY.value
|
||||||
this.deltaX = delta1X
|
deltaX.value = delta1X
|
||||||
this.deltaY = delta1Y
|
deltaY.value = delta1Y
|
||||||
// console.log('delta1X:' + delta1X, 'sumX:' + this.sumX, 'delta1Y:' + delta1Y, 'sumY:' + this.sumY)
|
modalContent.value.style.transform = `translate(${delta1X + sumX.value}px, ${delta1Y + sumY.value}px)`
|
||||||
this.modalContent.style.transform = `translate(${delta1X + this.sumX}px, ${delta1Y + this.sumY}px)`
|
}
|
||||||
},
|
const removeMove = () => {
|
||||||
removeMove() {
|
document.removeEventListener('mousemove', handleMove, false)
|
||||||
document.removeEventListener('mousemove', this.handleMove, false)
|
}
|
||||||
},
|
const removeUp = (event) => {
|
||||||
removeUp(event) {
|
|
||||||
document.body.onselectstart = () => true
|
document.body.onselectstart = () => true
|
||||||
if (this.onmousedown && !(event.pageX === this.mouseDownX && event.pageY === this.mouseDownY)) {
|
if (onmousedown.value && !(event.pageX === mouseDownX.value && event.pageY === mouseDownY.value)) {
|
||||||
this.onmousedown = false
|
onmousedown.value = false
|
||||||
this.sumX = this.sumX + this.deltaX
|
sumX.value = sumX.value + deltaX.value
|
||||||
this.sumY = this.sumY + this.deltaY
|
sumY.value = sumY.value + deltaY.value
|
||||||
// console.log('sumX:' + this.sumX, 'sumY:' + this.sumY)
|
|
||||||
}
|
}
|
||||||
this.removeMove()
|
removeMove()
|
||||||
// this.checkMove()
|
}
|
||||||
},
|
const handleResize = (event) => {
|
||||||
handleResize(event) {
|
if (fullscreenStatus.value) {
|
||||||
if (this.fullscreenStatus) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const diffX = event.clientX - this.startX
|
const diffX = event.clientX - startX.value
|
||||||
const diffY = event.clientY - this.startY
|
const diffY = event.clientY - startY.value
|
||||||
const minWidth = 180
|
const minWidth = 180
|
||||||
const minHeight = 0
|
const minHeight = 0
|
||||||
|
if (prevBodyWidth.value + diffX > minWidth) {
|
||||||
if (this.prevBodyWidth + diffX > minWidth) {
|
changeWidth(prevModalWidth.value + diffX + 'px')
|
||||||
this.changeWidth(this.prevModalWidth + diffX + 'px')
|
|
||||||
// this.myBody.style.width = this.prevBodyWidth + diffX + 'px'
|
|
||||||
}
|
}
|
||||||
if (this.prevBodyHeight + diffY > minHeight) {
|
if (prevBodyHeight.value + diffY > minHeight) {
|
||||||
// this.modalBody.style.height = this.prevModalHeight + diffY + 'px'
|
myBody.value.style.height = prevBodyHeight.value + diffY + 'px'
|
||||||
this.myBody.style.height = this.prevBodyHeight + diffY + 'px'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
removeResize() {
|
|
||||||
document.removeEventListener('mousemove', this.handleResize)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const removeResize = () => {
|
||||||
|
document.removeEventListener('mousemove', handleResize)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
|
|
@ -8,12 +8,7 @@
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
import Ellipsis from '@/components/Ellipsis'
|
import Ellipsis from '@/components/Ellipsis'
|
||||||
|
// vue3 不需要利用compoents去注册组件,引入后可直接使用
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Ellipsis
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
<script lang="jsx">
|
<template>
|
||||||
|
<ellipsis />
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { h } from 'vue'
|
||||||
import Tooltip from 'ant-design-vue/es/tooltip'
|
import Tooltip from 'ant-design-vue/es/tooltip'
|
||||||
import { cutStrByFullLength, getStrFullLength } from './util'
|
import { cutStrByFullLength, getStrFullLength } from './util'
|
||||||
|
import { useSlots } from 'vue'
|
||||||
|
const slots = useSlots()
|
||||||
|
|
||||||
export default {
|
const props = defineProps({
|
||||||
name: 'Ellipsis',
|
|
||||||
components: {
|
|
||||||
Tooltip
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
prefixCls: {
|
prefixCls: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'ant-pro-ellipsis'
|
default: 'ant-pro-ellipsis'
|
||||||
|
@ -27,24 +28,21 @@
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
methods: {
|
|
||||||
getStrDom(str, fullLength) {
|
const str = slots
|
||||||
return <span>{cutStrByFullLength(str, this.length) + (fullLength > this.length ? '...' : '')}</span>
|
|
||||||
},
|
|
||||||
getTooltip(fullStr, fullLength) {
|
|
||||||
return <Tooltip title={fullStr}>{this.getStrDom(fullStr, fullLength)}</Tooltip>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
render() {
|
|
||||||
const { tooltip, length } = this.$props
|
|
||||||
const str = this.$slots
|
|
||||||
.default()
|
.default()
|
||||||
.map((vNode) => vNode.children)
|
.map((vNode) => vNode.children)
|
||||||
.join('')
|
.join('')
|
||||||
|
|
||||||
const fullLength = getStrFullLength(str)
|
const fullLength = getStrFullLength(str)
|
||||||
const strDom = tooltip && fullLength > length ? this.getTooltip(str, fullLength) : this.getStrDom(str, fullLength)
|
const showStr = cutStrByFullLength(str, props.length) + (fullLength > props.length ? '...' : '')
|
||||||
return strDom
|
|
||||||
}
|
// 使用h函数注册渲染一个组件
|
||||||
|
const ellipsis = () => {
|
||||||
|
return props.tooltip && fullLength > props.length
|
||||||
|
? h(Tooltip, { title: str }, { default: () => showStr })
|
||||||
|
: // 引用组件时,需要设置默认值 default: () => xxx
|
||||||
|
h('span', showStr)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="baiduMap" :style="{height: `${height}px`}">
|
<div class="baiduMap" :style="{ height: `${height}px` }">
|
||||||
<div :id="`container-${mid}`" style="width: 100%; height: 100%">地图资源加载中...</div>
|
<div :id="`container-${mid}`" style="width: 100%; height: 100%">地图资源加载中...</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
},
|
},
|
||||||
plugins: {
|
plugins: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
// eslint-disable-next-line vue/require-valid-default-prop
|
||||||
default: ['BMap.ScaleControl', 'BMap.ZoomControl', 'BMap.LocationControl', 'BMap.NavigationControl3D']
|
default: ['BMap.ScaleControl', 'BMap.ZoomControl', 'BMap.LocationControl', 'BMap.NavigationControl3D']
|
||||||
},
|
},
|
||||||
viewMode: {
|
viewMode: {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="gaodeMap" :style="{height: `${height}px`}">
|
<div class="gaodeMap" :style="{ height: `${height}px` }">
|
||||||
<div :id="`container-${mid}`" style="width: 100%; height: 100%">地图资源加载中...</div>
|
<div :id="`container-${mid}`" style="width: 100%; height: 100%">地图资源加载中...</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
},
|
},
|
||||||
plugins: {
|
plugins: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
// eslint-disable-next-line vue/require-valid-default-prop
|
||||||
default: ['AMap.ToolBar', 'AMap.Scale', 'AMap.HawkEye', 'AMap.MapType', 'AMap.Geolocation', 'AMap.MarkerCluster']
|
default: ['AMap.ToolBar', 'AMap.Scale', 'AMap.HawkEye', 'AMap.MapType', 'AMap.Geolocation', 'AMap.MarkerCluster']
|
||||||
},
|
},
|
||||||
viewMode: {
|
viewMode: {
|
||||||
|
|
|
@ -36,69 +36,71 @@
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup>
|
||||||
<script>
|
|
||||||
import config from '@/assets/icons/mobile'
|
import config from '@/assets/icons/mobile'
|
||||||
export default {
|
const visible = ref(false)
|
||||||
data() {
|
const iconData = ref([])
|
||||||
return {
|
const modelValue = ref('')
|
||||||
visible: false,
|
const activeKey = ref('default')
|
||||||
iconData: [],
|
const iconItemDefault = ref('default')
|
||||||
modelValue: '',
|
|
||||||
activeKey: 'default',
|
onMounted(() => {
|
||||||
iconItemDefault: 'default'
|
iconData.value.push(...config.icons)
|
||||||
}
|
})
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.iconData.push(...config.icons)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 打开
|
// 打开
|
||||||
showIconModal(value) {
|
const showIconModal = (value) => {
|
||||||
this.visible = true
|
visible.value = true
|
||||||
this.defaultSetting(value)
|
defaultSetting(value)
|
||||||
},
|
}
|
||||||
|
|
||||||
|
// 暴露子组件的方法
|
||||||
|
defineExpose({
|
||||||
|
showIconModal
|
||||||
|
})
|
||||||
// 默认配置
|
// 默认配置
|
||||||
defaultSetting(value) {
|
const defaultSetting = (value) => {
|
||||||
if (value) {
|
if (value) {
|
||||||
this.modelValue = value
|
modelValue.value = value
|
||||||
// 判断展开哪个
|
// 判断展开哪个
|
||||||
if (value.indexOf('-outlined') > -1 || value.indexOf('-filled') > -1 || value.indexOf('-two-tone') > -1) {
|
if (value.indexOf('-outlined') > -1 || value.indexOf('-filled') > -1 || value.indexOf('-two-tone') > -1) {
|
||||||
this.activeKey = 'default'
|
activeKey.value = 'default'
|
||||||
if (value.indexOf('-two-tone') > -1) {
|
if (value.indexOf('-two-tone') > -1) {
|
||||||
this.iconItemDefault = 'twotone'
|
iconItemDefault.value = 'twotone'
|
||||||
} else if (value.indexOf('-filled') > -1) {
|
} else if (value.indexOf('-filled') > -1) {
|
||||||
this.iconItemDefault = 'filled'
|
iconItemDefault.value = 'filled'
|
||||||
}
|
}
|
||||||
} else if (value.indexOf('-extend') > -1) {
|
} else if (value.indexOf('-extend') > -1) {
|
||||||
// 扩展列表
|
// 扩展列表
|
||||||
this.activeKey = 'extend'
|
activeKey.value = 'extend'
|
||||||
// 如扩展其他顶部单选的情况,默认选中在这里配置,同时这里需要做判断
|
// 如扩展其他顶部单选的情况,默认选中在这里配置,同时这里需要做判断
|
||||||
// this.iconItemDefault = '您的json中配置的'
|
// this.iconItemDefault = '您的json中配置的'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
// 切换标签页,如果是切换到了没用额外的标签页的地方,我们将其置为默认
|
// 切换标签页,如果是切换到了没用额外的标签页的地方,我们将其置为默认
|
||||||
paneChange(e) {
|
const paneChange = (e) => {
|
||||||
if (e.indexOf('default') === -1) {
|
if (e.indexOf('default') === -1) {
|
||||||
this.iconItemDefault = 'default'
|
iconItemDefault.value = 'default'
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
// 切换icon风格
|
// 切换icon风格
|
||||||
radioGroupChange(e) {
|
const radioGroupChange = (e) => {
|
||||||
this.iconItemDefault = e.target.value
|
iconItemDefault.value = e.target.value
|
||||||
},
|
}
|
||||||
|
const emit = defineEmits(['iconCallBack'])
|
||||||
|
|
||||||
// 选择图标后关闭并返回
|
// 选择图标后关闭并返回
|
||||||
selectIcon(value) {
|
const selectIcon = (value) => {
|
||||||
this.defaultValue = value
|
visible.value = false
|
||||||
this.visible = false
|
|
||||||
// eslint-disable-next-line vue/require-explicit-emits
|
// eslint-disable-next-line vue/require-explicit-emits
|
||||||
this.$emit('iconCallBack', this.defaultValue)
|
emit('iconCallBack', value)
|
||||||
},
|
|
||||||
onCancel() {
|
|
||||||
this.visible = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
visible.value = false
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -36,69 +36,72 @@
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup>
|
||||||
<script>
|
|
||||||
import config from '@/config/iconSelect'
|
import config from '@/config/iconSelect'
|
||||||
export default {
|
const visible = ref(false)
|
||||||
data() {
|
const iconData = ref([])
|
||||||
return {
|
const modelValue = ref('')
|
||||||
visible: false,
|
const activeKey = ref('default')
|
||||||
iconData: [],
|
const iconItemDefault = ref('default')
|
||||||
modelValue: '',
|
|
||||||
activeKey: 'default',
|
onMounted(() => {
|
||||||
iconItemDefault: 'default'
|
iconData.value.push(...config.icons)
|
||||||
}
|
})
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.iconData.push(...config.icons)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 打开
|
// 打开
|
||||||
showIconModal(value) {
|
const showIconModal = (value) => {
|
||||||
this.visible = true
|
visible.value = true
|
||||||
this.defaultSetting(value)
|
defaultSetting(value)
|
||||||
},
|
}
|
||||||
|
|
||||||
|
// 暴露子组件的方法
|
||||||
|
defineExpose({
|
||||||
|
showIconModal
|
||||||
|
})
|
||||||
|
|
||||||
// 默认配置
|
// 默认配置
|
||||||
defaultSetting(value) {
|
const defaultSetting = (value) => {
|
||||||
if (value) {
|
if (value) {
|
||||||
this.modelValue = value
|
modelValue.value = value
|
||||||
// 判断展开哪个
|
// 判断展开哪个
|
||||||
if (value.indexOf('-outlined') > -1 || value.indexOf('-filled') > -1 || value.indexOf('-two-tone') > -1) {
|
if (value.indexOf('-outlined') > -1 || value.indexOf('-filled') > -1 || value.indexOf('-two-tone') > -1) {
|
||||||
this.activeKey = 'default'
|
activeKey.value = 'default'
|
||||||
if (value.indexOf('-two-tone') > -1) {
|
if (value.indexOf('-two-tone') > -1) {
|
||||||
this.iconItemDefault = 'twotone'
|
iconItemDefault.value = 'twotone'
|
||||||
} else if (value.indexOf('-filled') > -1) {
|
} else if (value.indexOf('-filled') > -1) {
|
||||||
this.iconItemDefault = 'filled'
|
iconItemDefault.value = 'filled'
|
||||||
}
|
}
|
||||||
} else if (value.indexOf('-extend') > -1) {
|
} else if (value.indexOf('-extend') > -1) {
|
||||||
// 扩展列表
|
// 扩展列表
|
||||||
this.activeKey = 'extend'
|
activeKey.value = 'extend'
|
||||||
// 如扩展其他顶部单选的情况,默认选中在这里配置,同时这里需要做判断
|
// 如扩展其他顶部单选的情况,默认选中在这里配置,同时这里需要做判断
|
||||||
// this.iconItemDefault = '您的json中配置的'
|
// this.iconItemDefault = '您的json中配置的'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
// 切换标签页,如果是切换到了没用额外的标签页的地方,我们将其置为默认
|
// 切换标签页,如果是切换到了没用额外的标签页的地方,我们将其置为默认
|
||||||
paneChange(e) {
|
const paneChange = (e) => {
|
||||||
if (e.indexOf('default') === -1) {
|
if (e.indexOf('default') === -1) {
|
||||||
this.iconItemDefault = 'default'
|
iconItemDefault.value = 'default'
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
// 切换icon风格
|
// 切换icon风格
|
||||||
radioGroupChange(e) {
|
const radioGroupChange = (e) => {
|
||||||
this.iconItemDefault = e.target.value
|
iconItemDefault.value = e.target.value
|
||||||
},
|
}
|
||||||
|
const emit = defineEmits(['iconCallBack'])
|
||||||
|
|
||||||
// 选择图标后关闭并返回
|
// 选择图标后关闭并返回
|
||||||
selectIcon(value) {
|
const selectIcon = (value) => {
|
||||||
this.defaultValue = value
|
visible.value = false
|
||||||
this.visible = false
|
|
||||||
// eslint-disable-next-line vue/require-explicit-emits
|
// eslint-disable-next-line vue/require-explicit-emits
|
||||||
this.$emit('iconCallBack', this.defaultValue)
|
emit('iconCallBack', value)
|
||||||
},
|
|
||||||
onCancel() {
|
|
||||||
this.visible = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
visible.value = false
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -13,29 +13,23 @@ iconSelector
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<a-button type="primary" @click="$refs.iconselector.showModal(iconValue)">选择</a-button>
|
<a-button type="primary" @click="openIcon(iconValue)">选择</a-button>
|
||||||
<icon-selector ref="iconselector" @callBack="iconCallBack"/>
|
<icon-selector ref="iconselector" @iconCallBack="iconCallBack" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import iconSelector from '@/components/Selector/iconSelector.vue'
|
const iconselector = ref() // 绑定ref="iconselector"
|
||||||
|
|
||||||
export default {
|
// 打开icon选择器
|
||||||
name: 'YourView',
|
const openIcon = (iconValue) => {
|
||||||
components: {
|
iconselector.value.showIconModal(iconValue)
|
||||||
iconSelector
|
|
||||||
},
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
}
|
}
|
||||||
},
|
// 选择后回调
|
||||||
methods: {
|
const iconCallBack = (value) => {
|
||||||
iconCallBack (icon) {
|
console.log('iconCallBack Icon', value)
|
||||||
console.log('iconCallBack Icon', icon)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="org-table">
|
<div class="org-table">
|
||||||
<a-table
|
<a-table
|
||||||
ref="table"
|
ref="tableRef"
|
||||||
size="small"
|
size="small"
|
||||||
:columns="commons"
|
:columns="commons"
|
||||||
:data-source="tableData"
|
:data-source="tableData"
|
||||||
|
@ -143,7 +143,7 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
// 主表格的ref 名称
|
// 主表格的ref 名称
|
||||||
const table = ref()
|
const tableRef = ref()
|
||||||
// 选中表格的ref 名称
|
// 选中表格的ref 名称
|
||||||
const selectedTable = ref()
|
const selectedTable = ref()
|
||||||
const tableRecordNum = ref()
|
const tableRecordNum = ref()
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="pos-table">
|
<div class="pos-table">
|
||||||
<a-table
|
<a-table
|
||||||
ref="table"
|
ref="tableRef"
|
||||||
size="small"
|
size="small"
|
||||||
:columns="commons"
|
:columns="commons"
|
||||||
:data-source="tableData"
|
:data-source="tableData"
|
||||||
|
@ -143,7 +143,7 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
// 主表格的ref 名称
|
// 主表格的ref 名称
|
||||||
const table = ref()
|
const tableRef = ref()
|
||||||
// 选中表格的ref 名称
|
// 选中表格的ref 名称
|
||||||
const selectedTable = ref()
|
const selectedTable = ref()
|
||||||
const tableRecordNum = ref()
|
const tableRecordNum = ref()
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="role-table">
|
<div class="role-table">
|
||||||
<a-table
|
<a-table
|
||||||
ref="table"
|
ref="tableRef"
|
||||||
size="small"
|
size="small"
|
||||||
:columns="commons"
|
:columns="commons"
|
||||||
:data-source="tableData"
|
:data-source="tableData"
|
||||||
|
@ -143,7 +143,7 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
// 主表格的ref 名称
|
// 主表格的ref 名称
|
||||||
const table = ref()
|
const tableRef = ref()
|
||||||
// 选中表格的ref 名称
|
// 选中表格的ref 名称
|
||||||
const selectedTable = ref()
|
const selectedTable = ref()
|
||||||
const tableRecordNum = ref()
|
const tableRecordNum = ref()
|
||||||
|
@ -192,10 +192,13 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// 是否是单选
|
// 是否是单选
|
||||||
|
// eslint-disable-next-line vue/no-setup-props-destructure
|
||||||
const radioModel = props.radioModel
|
const radioModel = props.radioModel
|
||||||
// 数据是否转换成工作流格式
|
// 数据是否转换成工作流格式
|
||||||
|
// eslint-disable-next-line vue/no-setup-props-destructure
|
||||||
const dataIsConverterFlw = props.dataIsConverterFlw
|
const dataIsConverterFlw = props.dataIsConverterFlw
|
||||||
// 是否展示‘全局’这个节点
|
// 是否展示‘全局’这个节点
|
||||||
|
// eslint-disable-next-line vue/no-setup-props-destructure
|
||||||
const roleGlobal = props.roleGlobal
|
const roleGlobal = props.roleGlobal
|
||||||
// 分页相关
|
// 分页相关
|
||||||
const current = ref(0) // 当前页数
|
const current = ref(0) // 当前页数
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="user-table">
|
<div class="user-table">
|
||||||
<a-table
|
<a-table
|
||||||
ref="table"
|
ref="tableRef"
|
||||||
size="small"
|
size="small"
|
||||||
:columns="commons"
|
:columns="commons"
|
||||||
:data-source="tableData"
|
:data-source="tableData"
|
||||||
|
@ -143,7 +143,7 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
// 主表格的ref 名称
|
// 主表格的ref 名称
|
||||||
const table = ref()
|
const tableRef = ref()
|
||||||
// 选中表格的ref 名称
|
// 选中表格的ref 名称
|
||||||
const selectedTable = ref()
|
const selectedTable = ref()
|
||||||
const tableRecordNum = ref()
|
const tableRecordNum = ref()
|
||||||
|
|
|
@ -39,16 +39,10 @@
|
||||||
switch (arguments.length) {
|
switch (arguments.length) {
|
||||||
case 1:
|
case 1:
|
||||||
return parseInt(Math.random() * minNum + 1, 10)
|
return parseInt(Math.random() * minNum + 1, 10)
|
||||||
// eslint-disable-next-line no-unreachable
|
|
||||||
break
|
|
||||||
case 2:
|
case 2:
|
||||||
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10)
|
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10)
|
||||||
// eslint-disable-next-line no-unreachable
|
|
||||||
break
|
|
||||||
default:
|
default:
|
||||||
return 0
|
return 0
|
||||||
// eslint-disable-next-line no-unreachable
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -21,7 +21,7 @@ Table 重封装组件说明
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<s-table
|
<s-table
|
||||||
ref="table"
|
ref="tableRef"
|
||||||
:rowKey="(record) => record.data.id"
|
:rowKey="(record) => record.data.id"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="loadData"
|
:data="loadData"
|
||||||
|
@ -99,44 +99,36 @@ export default {
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<s-table
|
<s-table ref="tableRef" :columns="columns" :data="loadData" :alert="false" bordered :row-key="(record) => record.id">
|
||||||
ref="table"
|
<!-- #operator 插槽可以放入一些关于表格的操作,比如新增数据。 -->
|
||||||
:columns="columns"
|
<template #operator class="table-operator">
|
||||||
:data="loadData"
|
<a-space>
|
||||||
>
|
<a-button type="primary" @click="">
|
||||||
<span slot="action" slot-scope="text, record">
|
<template #icon><plus-outlined /></template>
|
||||||
<a>编辑</a>
|
新增
|
||||||
<a-divider type="vertical"/>
|
</a-button>
|
||||||
<a-dropdown>
|
</a-space>
|
||||||
<a class="ant-dropdown-link">
|
</template>
|
||||||
更多 <a-icon type="down"/>
|
<!-- #bodyCell 放入column表格列需要显示的数据,可以通过判断进行一个自定义显示 -->
|
||||||
</a>
|
<template #bodyCell="{ column, record }">
|
||||||
<a-menu slot="overlay">
|
<template >
|
||||||
<a-menu-item>
|
<a-avatar style="width: 25px; height: 25px" />
|
||||||
<a href="javascript:;">1st menu item</a>
|
</template>
|
||||||
</a-menu-item>
|
<template v-if="column.dataIndex === 'status'">
|
||||||
<a-menu-item>
|
<!-- 进行自定义显示内容 -->
|
||||||
<a href="javascript:;">2nd menu item</a>
|
</template>
|
||||||
</a-menu-item>
|
<!-- column.dataIndex === 'action' 时,可以进行编辑删除等关于这行数据的一个操作,操作内容可进行自定义 -->
|
||||||
<a-menu-item>
|
<template v-if="column.dataIndex === 'action'">
|
||||||
<a href="javascript:;">3rd menu item</a>
|
<a @click="">编辑</a>
|
||||||
</a-menu-item>
|
</template>
|
||||||
</a-menu>
|
</template>
|
||||||
</a-dropdown>
|
|
||||||
</span>
|
|
||||||
</s-table>
|
</s-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import STable from '@/components/table/'
|
import STable from '@/components/table/'
|
||||||
|
const tableRef = ref() //一定要进行一个表格的ref绑定
|
||||||
export default {
|
const columns = ref([
|
||||||
components: {
|
|
||||||
STable,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
columns: [
|
|
||||||
{
|
{
|
||||||
title: '规则编号',
|
title: '规则编号',
|
||||||
dataIndex: 'no',
|
dataIndex: 'no',
|
||||||
|
@ -162,31 +154,25 @@ export default {
|
||||||
dataIndex: 'action',
|
dataIndex: 'action',
|
||||||
scopedSlots: { customRender: 'action' },
|
scopedSlots: { customRender: 'action' },
|
||||||
},
|
},
|
||||||
],
|
])
|
||||||
// 查询条件参数
|
const queryParam = ref({})
|
||||||
queryParam: {},
|
// 加载按钮数据
|
||||||
// 加载数据方法 必须为 Promise 对象
|
const loadData = (parameter) => {
|
||||||
loadData: (parameter) => {
|
|
||||||
return this.$http.get('/service', {
|
return this.$http.get('/service', {
|
||||||
params: Object.assign(parameter, this.queryParam),
|
params: Object.assign(parameter, queryParam.value),
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
return res.result
|
return res.result
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
}
|
const edit = (row) => {
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
edit(row) {
|
|
||||||
// axios 发送数据到后端 修改数据成功后
|
// axios 发送数据到后端 修改数据成功后
|
||||||
// 调用 refresh() 重新加载列表数据
|
// 调用 refresh() 重新加载列表数据
|
||||||
// 这里 setTimeout 模拟发起请求的网络延迟..
|
// 这里 setTimeout 模拟发起请求的网络延迟..
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$refs.table.refresh() // refresh() 不传参默认值 false 不刷新到分页第一页
|
tableRef.value.refresh() // refresh() 不传参默认值 false 不刷新到分页第一页
|
||||||
}, 1500)
|
}, 1500)
|
||||||
|
|
||||||
},
|
}
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -195,9 +181,9 @@ export default {
|
||||||
内置方法
|
内置方法
|
||||||
----
|
----
|
||||||
|
|
||||||
通过 `this.$refs.table` 调用
|
通过 `声明的ref去调用 ==> tableRef.value` 调用
|
||||||
|
|
||||||
`this.$refs.table.refresh(true)` 刷新列表 (用户新增/修改数据后,重载列表数据)
|
`tableRef.value.refresh(true)` 刷新列表 (用户新增/修改数据后,重载列表数据)
|
||||||
|
|
||||||
> 注意:要调用 `refresh(bool)` 需要给表格组件设定 `ref` 值
|
> 注意:要调用 `refresh(bool)` 需要给表格组件设定 `ref` 值
|
||||||
>
|
>
|
||||||
|
@ -233,38 +219,82 @@ alert: {
|
||||||
>
|
>
|
||||||
> 文档中的结构有可能由于组件 bug 进行修正而改动。实际修改请以当时最新版本为准
|
> 文档中的结构有可能由于组件 bug 进行修正而改动。实际修改请以当时最新版本为准
|
||||||
|
|
||||||
修改 `@/components/table/index.js` 第 156 行起
|
修改 `@/components/table/index.js` 第 348 行起
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
result.then(r => {
|
const data = reactive({
|
||||||
this.localPagination = this.showPagination && Object.assign({}, this.localPagination, {
|
needTotalList: [],
|
||||||
current: r.pageNo, // 返回结果中的当前分页数
|
localLoading: false,
|
||||||
total: r.totalCount, // 返回结果中的总记录数
|
localDataSource: [],
|
||||||
showSizeChanger: this.showSizeChanger,
|
localPagination: Object.assign({}, props.pagination),
|
||||||
pageSize: (pagination && pagination.pageSize) ||
|
isFullscreen: false,
|
||||||
this.localPagination.pageSize
|
customSize: props.compSize,
|
||||||
}) || false
|
columnsSetting: [],
|
||||||
// 为防止删除数据后导致页面当前页面数据长度为 0 ,自动翻页到上一页
|
localSettings: {
|
||||||
if (r.data.length === 0 && this.showPagination && this.localPagination.current > 1) {
|
rowClassName: props.rowClassName,
|
||||||
this.localPagination.current--
|
rowClassNameSwitch: Boolean(props.rowClassName)
|
||||||
this.loadData()
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 这里的 data.xxx 是之前声明的
|
||||||
|
// 在 loadData() 方法中去获取后端数据,进行一个数据的加载更新
|
||||||
|
result.then((r) => {
|
||||||
|
if (r == null) {
|
||||||
|
data.localLoading = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
data.localPagination =
|
||||||
|
(props.showPagination &&
|
||||||
|
Object.assign({}, data.localPagination, {
|
||||||
|
current: r.current, // pageNo, // 返回结果中的当前分页数
|
||||||
|
total: r.total, // totalRows, // 返回结果中的总记录数
|
||||||
|
showSizeChanger: props.showSizeChanger,
|
||||||
|
pageSizeOptions: props.pageSizeOptions,
|
||||||
|
showTotal: (total, range) => {
|
||||||
|
return `${range[0]}-${range[1]} 共 ${total} 条 `
|
||||||
|
},
|
||||||
|
pageSize: (pagination && pagination.pageSize) || data.localPagination.pageSize
|
||||||
|
})) ||
|
||||||
|
false
|
||||||
|
|
||||||
// 这里用于判断接口是否有返回 r.totalCount 且 this.showPagination = true 且 pageNo 和 pageSize 存在 且 totalCount 小于等于 pageNo * pageSize 的大小
|
// 后端数据records为null保存修复
|
||||||
|
if (r.records == null) {
|
||||||
|
r.records = []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 为防止删除数据后导致页面当前页面数据长度为 0 ,自动翻页到上一页
|
||||||
|
if (r.records.length === 0 && props.showPagination && data.localPagination.current > 1) {
|
||||||
|
data.localPagination.current--
|
||||||
|
loadData()
|
||||||
|
return
|
||||||
|
}
|
||||||
// 当情况满足时,表示数据不满足分页大小,关闭 table 分页功能
|
// 当情况满足时,表示数据不满足分页大小,关闭 table 分页功能
|
||||||
try {
|
try {
|
||||||
if ((['auto', true].includes(this.showPagination) && r.totalCount <= (r.pageNo * this.localPagination.pageSize))) {
|
/*
|
||||||
this.localPagination.hideOnSinglePage = true
|
if ((['auto', true].includes(props.showPagination) && r.total <= (r.pages * data.localPagination.size))) {
|
||||||
|
data.localPagination.hideOnSinglePage = true
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if (!props.showPagination) {
|
||||||
|
data.localPagination.hideOnSinglePage = true
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.localPagination = false
|
data.localPagination = false
|
||||||
}
|
}
|
||||||
console.log('loadData -> this.localPagination', this.localPagination)
|
// 返回结果中的数组数据
|
||||||
this.localDataSource = r.data // 返回结果中的数组数据
|
if (props.showPagination === false) {
|
||||||
this.localLoading = false
|
// 既然配置了不分页,那么我们这里接收到肯定是数组
|
||||||
|
data.localDataSource = []
|
||||||
|
if (r instanceof Array) {
|
||||||
|
data.localDataSource = r
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data.localDataSource = r.records
|
||||||
|
}
|
||||||
|
data.localLoading = false
|
||||||
|
getTableProps() // 获取到后端返回的数据后,需要调用一下获取table的props的方法去刷新table
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
返回 JSON 例子:
|
返回 JSON 例子:
|
||||||
|
@ -336,4 +366,4 @@ result.then(r => {
|
||||||
更新时间
|
更新时间
|
||||||
----
|
----
|
||||||
|
|
||||||
该文档最后更新于: 2019-06-23 PM 17:19
|
该文档最后更新于: 2023-12-27 PM 16:45
|
||||||
|
|
|
@ -22,76 +22,70 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup>
|
||||||
<script>
|
import Draggable from 'vuedraggable-es'
|
||||||
import draggable from 'vuedraggable-es'
|
const emit = defineEmits(['columnChange'])
|
||||||
|
const props = defineProps({
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
draggable
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
columns: {
|
columns: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => []
|
default: () => []
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
data() {
|
|
||||||
return {
|
const indeterminate = ref(false)
|
||||||
indeterminate: false,
|
const checkAll = ref(true)
|
||||||
checkAll: true,
|
const columnsSetting = ref([])
|
||||||
columnsSetting: [],
|
const originColumns = ref()
|
||||||
originColumns: []
|
|
||||||
}
|
onMounted(() => {
|
||||||
},
|
columnsSetting.value = props.columns.map((value) => {
|
||||||
mounted() {
|
if (value.checked === undefined) {
|
||||||
this.columnsSetting = this.columns.map((value) => {
|
|
||||||
if (value.checked == undefined) {
|
|
||||||
return {
|
return {
|
||||||
...value,
|
...value,
|
||||||
checked: true
|
checked: true
|
||||||
}
|
}
|
||||||
} else return value
|
} else return value
|
||||||
})
|
})
|
||||||
|
|
||||||
// 这里要用深的拷贝,否则,勾选了字段时会修改了originColumns里的内容
|
// 这里要用深的拷贝,否则,勾选了字段时会修改了originColumns里的内容
|
||||||
this.originColumns = this.columnsSetting.map((value) => ({ ...value }))
|
originColumns.value = columnsSetting.value.map((value) => ({ ...value }))
|
||||||
|
|
||||||
// 处理全选组件
|
// 处理全选组件
|
||||||
const notCheckedList = this.columnsSetting.filter((value) => !value.checked)
|
const notCheckedList = columnsSetting.value.filter((value) => !value.checked)
|
||||||
if (notCheckedList.length) this.checkAll = false
|
if (notCheckedList.length) checkAll.value = false
|
||||||
},
|
})
|
||||||
methods: {
|
|
||||||
reset() {
|
const reset = () => {
|
||||||
this.columnsSetting = this.originColumns.map((value) => ({ ...value }))
|
columnsSetting.value = originColumns.value.map((value) => ({ ...value }))
|
||||||
this.indeterminate = false
|
indeterminate.value = false
|
||||||
const checkedList = this.columnsSetting.filter((value) => value.checked)
|
const checkedList = columnsSetting.value.filter((value) => value.checked)
|
||||||
this.checkAll = checkedList.length === this.columnsSetting.length
|
checkAll.value = checkedList.length === columnsSetting.value.length
|
||||||
this.emitColumnChange()
|
emitColumnChange()
|
||||||
},
|
}
|
||||||
onChange() {
|
|
||||||
const checkedList = this.columnsSetting.filter((value) => value.checked)
|
const onChange = () => {
|
||||||
this.indeterminate = Boolean(checkedList.length) && checkedList.length < this.columnsSetting.length
|
const checkedList = columnsSetting.value.filter((value) => value.checked)
|
||||||
this.checkAll = checkedList.length === this.columnsSetting.length
|
indeterminate.value = Boolean(checkedList.length) && checkedList.length < columnsSetting.value.length
|
||||||
this.emitColumnChange()
|
checkAll.value = checkedList.length === columnsSetting.value.length
|
||||||
},
|
emitColumnChange()
|
||||||
onCheckAllChange(e) {
|
}
|
||||||
|
|
||||||
|
// 全选
|
||||||
|
const onCheckAllChange = (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const val = e.target.checked
|
const val = e.target.checked
|
||||||
Object.assign(this, {
|
|
||||||
indeterminate: false,
|
indeterminate.value = false
|
||||||
checkAll: val,
|
checkAll.value = val
|
||||||
columnsSetting: this.columns.map((value) => ({
|
columnsSetting.value = props.columns.map((value) => ({
|
||||||
...value,
|
...value,
|
||||||
checked: val
|
checked: val
|
||||||
}))
|
}))
|
||||||
})
|
emitColumnChange()
|
||||||
this.emitColumnChange()
|
}
|
||||||
},
|
|
||||||
emitColumnChange() {
|
const emitColumnChange = () => {
|
||||||
// eslint-disable-next-line vue/require-explicit-emits
|
// eslint-disable-next-line vue/require-explicit-emits
|
||||||
this.$emit('columnChange', this.columnsSetting)
|
emit('columnChange', columnsSetting.value)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
|
||||||
|
|
|
@ -1,36 +1,128 @@
|
||||||
<script lang="jsx">
|
<template>
|
||||||
|
<div className="table-wrapper">
|
||||||
|
<div className="s-table-tool">
|
||||||
|
<div className="s-table-tool-left">
|
||||||
|
<!-- 插槽操作按钮 -->
|
||||||
|
<slot name="operator"></slot>
|
||||||
|
</div>
|
||||||
|
<!-- 斑马纹 -->
|
||||||
|
<div className="layout-items-center s-table-tool-right">
|
||||||
|
<div className="layout-items-center ml-4" v-show="props.toolConfig.striped">
|
||||||
|
<a-checkbox :checked="data.localSettings.rowClassNameSwitch" @change="changeRowClass"> 斑马纹 </a-checkbox>
|
||||||
|
</div>
|
||||||
|
<span v-for="item in tool">
|
||||||
|
<!-- 刷新 -->
|
||||||
|
<a-tooltip
|
||||||
|
v-if="item.name === 'refresh' && props.toolConfig.refresh"
|
||||||
|
:title="item.title"
|
||||||
|
class="s-tool-item"
|
||||||
|
@click="refresh"
|
||||||
|
>
|
||||||
|
<component class="icons" :is="item.icon"></component>
|
||||||
|
</a-tooltip>
|
||||||
|
|
||||||
|
<!-- 列展示 -->
|
||||||
|
<a-popover
|
||||||
|
v-if="item.isPopover && item.name === 'columnSetting' && props.toolConfig.columnSetting"
|
||||||
|
trigger="click"
|
||||||
|
placement="topLeft"
|
||||||
|
overlayClassName="s-table-column-settings"
|
||||||
|
arrow-point-at-center
|
||||||
|
>
|
||||||
|
<template #content>
|
||||||
|
<columnSetting :columns="props.columns" @columnChange="columnChange" />
|
||||||
|
</template>
|
||||||
|
<a-tooltip :title="item.title" class="s-tool-item">
|
||||||
|
<component class="icons" :is="item.icon"></component>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-popover>
|
||||||
|
<!-- 密度 -->
|
||||||
|
<a-dropdown trigger="click" v-if="item.isDropdown && item.name == 'height' && props.toolConfig.height">
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu selectable :selectedKeys="[data.customSize]" @click="changeHeight">
|
||||||
|
<a-menu-item key="default">默认</a-menu-item>
|
||||||
|
<a-menu-item key="middle">中等</a-menu-item>
|
||||||
|
<a-menu-item key="small">紧凑</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
<a-tooltip :title="item.title" class="s-tool-item">
|
||||||
|
<component class="icons" :is="item.icon"></component>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-dropdown>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 统计列数据 -->
|
||||||
|
<a-alert showIcon class="mb-4" v-if="props.alert">
|
||||||
|
<template #message>
|
||||||
|
<div>
|
||||||
|
<span className="mr-3">
|
||||||
|
已选择:{{ ' ' }}
|
||||||
|
<a className="font-6">
|
||||||
|
{{
|
||||||
|
props.rowSelection && props.rowSelection.selectedRowKeys ? props.rowSelection.selectedRowKeys.length : 0
|
||||||
|
}}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
<span className="mr-3" v-for="item in data.needTotalList">
|
||||||
|
{{ item.title }} 总计{{ ' ' }}
|
||||||
|
<a className="font-6">{{ !item.customRender ? item.total : item.customRender(item.total) }}</a>
|
||||||
|
</span>
|
||||||
|
<a
|
||||||
|
v-show="
|
||||||
|
props.rowSelection && props.rowSelection.selectedRowKeys && props.rowSelection.selectedRowKeys.length > 0
|
||||||
|
"
|
||||||
|
className="ml-6"
|
||||||
|
@click="
|
||||||
|
rowClear(
|
||||||
|
typeof props.alert === 'boolean' && props.alert
|
||||||
|
? clearSelected()
|
||||||
|
: props.alert.clear && typeof props.alert.clear === 'function'
|
||||||
|
? props.alert.clear()
|
||||||
|
: null
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ ' ' }}
|
||||||
|
清空{{ ' ' }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-alert>
|
||||||
|
|
||||||
|
<!-- 表格 -->
|
||||||
|
<a-table
|
||||||
|
v-bind="{ ...renderTableProps, ...data.localSettings }"
|
||||||
|
@change="loadData"
|
||||||
|
:row-key="(record) => record.id"
|
||||||
|
@expand="
|
||||||
|
(expanded, record) => {
|
||||||
|
emit('expand', expanded, record)
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #[item]="scope" v-for="item in renderSlots">
|
||||||
|
<slot :name="item" :scope="scope" v-bind="scope || {}"></slot>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import './index.less'
|
||||||
import { tableProps } from 'ant-design-vue/es/table/Table.js'
|
import { tableProps } from 'ant-design-vue/es/table/Table.js'
|
||||||
import { get } from 'lodash-es'
|
|
||||||
import draggable from 'vuedraggable-es'
|
|
||||||
import columnSetting from './columnSetting.vue'
|
import columnSetting from './columnSetting.vue'
|
||||||
import './index.less'
|
import './index.less'
|
||||||
import i18n from '@/locales'
|
|
||||||
|
|
||||||
const { t } = i18n.global
|
import { useSlots } from 'vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
const slots = useSlots()
|
||||||
|
const route = useRoute()
|
||||||
|
const emit = defineEmits(['expand'])
|
||||||
|
const renderSlots = Object.keys(slots)
|
||||||
|
|
||||||
export default {
|
const props = defineProps(
|
||||||
name: 'STable',
|
Object.assign({}, tableProps(), {
|
||||||
components: {
|
|
||||||
draggable,
|
|
||||||
columnSetting
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
needTotalList: [],
|
|
||||||
localLoading: false,
|
|
||||||
localDataSource: [],
|
|
||||||
localPagination: Object.assign({}, this.pagination),
|
|
||||||
isFullscreen: false,
|
|
||||||
customSize: this.compSize,
|
|
||||||
columnsSetting: [],
|
|
||||||
localSettings: {
|
|
||||||
rowClassName: this.rowClassName,
|
|
||||||
rowClassNameSwitch: Boolean(this.rowClassName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// eslint-disable-next-line vue/order-in-components
|
|
||||||
props: Object.assign({}, tableProps(), {
|
|
||||||
rowKey: {
|
rowKey: {
|
||||||
type: [String, Function],
|
type: [String, Function],
|
||||||
default: 'key'
|
default: 'key'
|
||||||
|
@ -97,82 +189,161 @@
|
||||||
striped: false
|
striped: false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}),
|
|
||||||
watch: {
|
|
||||||
pageNum(val) {
|
|
||||||
Object.assign(this.localPagination, {
|
|
||||||
current: val
|
|
||||||
})
|
})
|
||||||
},
|
)
|
||||||
size(val) {
|
|
||||||
Object.assign(this.localPagination, {
|
const data = reactive({
|
||||||
size: val
|
needTotalList: [],
|
||||||
})
|
localLoading: false,
|
||||||
},
|
localDataSource: [],
|
||||||
showSizeChanger(val) {
|
localPagination: Object.assign({}, props.pagination),
|
||||||
Object.assign(this.localPagination, {
|
isFullscreen: false,
|
||||||
showSizeChanger: val
|
customSize: props.compSize,
|
||||||
})
|
columnsSetting: [],
|
||||||
},
|
localSettings: {
|
||||||
columns(v) {
|
rowClassName: props.rowClassName,
|
||||||
this.columnsSetting = v
|
rowClassNameSwitch: Boolean(props.rowClassName)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.pageNum,
|
||||||
|
(newVal) => {
|
||||||
|
Object.assign(data.localPagination, {
|
||||||
|
current: newVal
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
watch(
|
||||||
|
() => props.size,
|
||||||
|
(newVal) => {
|
||||||
|
Object.assign(data.localPagination, {
|
||||||
|
size: newVal
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
watch(
|
||||||
|
() => props.showSizeChanger,
|
||||||
|
(newVal) => {
|
||||||
|
Object.assign(data.localPagination, {
|
||||||
|
showSizeChanger: newVal
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
watch(
|
||||||
|
() => props.columns,
|
||||||
|
(newVal) => {
|
||||||
|
data.columnsSetting = newVal
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 表格props
|
||||||
|
const renderTableProps = ref([])
|
||||||
|
// 右上角工具数组
|
||||||
|
const tool = [
|
||||||
|
{
|
||||||
|
name: 'refresh',
|
||||||
|
icon: 'sync-outlined',
|
||||||
|
title: '刷新'
|
||||||
},
|
},
|
||||||
created() {
|
{
|
||||||
const { current } = this.$route.params
|
name: 'height',
|
||||||
const localPageNum = (current && parseInt(current)) || this.pageNum
|
icon: 'column-height-outlined',
|
||||||
this.localPagination =
|
title: '密度',
|
||||||
(['auto', true].includes(this.showPagination) &&
|
isDropdown: true
|
||||||
Object.assign({}, this.localPagination, {
|
},
|
||||||
|
{
|
||||||
|
name: 'columnSetting',
|
||||||
|
icon: 'setting-outlined',
|
||||||
|
title: '列设置',
|
||||||
|
isPopover: true,
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// 刷新
|
||||||
|
const refresh = (bool = false) => {
|
||||||
|
bool &&
|
||||||
|
(data.localPagination = Object.assign(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
current: 1,
|
||||||
|
pageSize: data.localPagination.pageSize
|
||||||
|
}
|
||||||
|
))
|
||||||
|
loadData()
|
||||||
|
getTableProps()
|
||||||
|
}
|
||||||
|
// 斑马纹勾选
|
||||||
|
const changeRowClass = (value) => {
|
||||||
|
const val = value.target.checked
|
||||||
|
data.localSettings.rowClassNameSwitch = val
|
||||||
|
const evenClass = val ? (_record, index) => (index % 2 === 1 ? 'table-striped' : null) : props.rowClassName
|
||||||
|
data.localSettings.rowClassName = evenClass
|
||||||
|
}
|
||||||
|
// 密度切换
|
||||||
|
const changeHeight = (v) => {
|
||||||
|
data.customSize = v.key
|
||||||
|
getTableProps()
|
||||||
|
}
|
||||||
|
// 列设置
|
||||||
|
const columnChange = (val) => {
|
||||||
|
data.columnsSetting = val
|
||||||
|
getTableProps()
|
||||||
|
}
|
||||||
|
// 列清空
|
||||||
|
const rowClear = (callback) => {
|
||||||
|
callback
|
||||||
|
clearSelected()
|
||||||
|
}
|
||||||
|
// 初始化
|
||||||
|
const init = () => {
|
||||||
|
const { current } = route.params
|
||||||
|
const localPageNum = (current && parseInt(current)) || props.pageNum
|
||||||
|
data.localPagination =
|
||||||
|
(['auto', true].includes(props.showPagination) &&
|
||||||
|
Object.assign({}, data.localPagination, {
|
||||||
current: localPageNum,
|
current: localPageNum,
|
||||||
pageSize: this.size, //this.compSize, size// 改动
|
pageSize: props.size, //props.compSize, size// 改动
|
||||||
showSizeChanger: this.showSizeChanger,
|
showSizeChanger: props.showSizeChanger,
|
||||||
defaultPageSize: this.defaultPageSize,
|
defaultPageSize: props.defaultPageSize,
|
||||||
pageSizeOptions: this.pageSizeOptions,
|
pageSizeOptions: props.pageSizeOptions,
|
||||||
showTotal: (total, range) => {
|
showTotal: (total, range) => {
|
||||||
return `${range[0]}-${range[1]} 共 ${total} 条 `
|
return `${range[0]}-${range[1]} 共 ${total} 条 `
|
||||||
}
|
}
|
||||||
})) ||
|
})) ||
|
||||||
false
|
false
|
||||||
this.needTotalList = this.initTotalList(this.columns)
|
data.needTotalList = initTotalList(props.columns)
|
||||||
this.loadData()
|
data.columnsSetting = props.columns
|
||||||
this.columnsSetting = this.columns
|
loadData()
|
||||||
/*.map((c) => {
|
|
||||||
const tt = c.title
|
|
||||||
if (typeof tt === 'string') {
|
|
||||||
c.title = () => t(tt)
|
|
||||||
}
|
}
|
||||||
return c
|
const initTotalList = (columns) => {
|
||||||
})*/
|
const totalList = []
|
||||||
},
|
columns &&
|
||||||
methods: {
|
columns instanceof Array &&
|
||||||
// 表格重新加载方法 如果参数为 true, 则强制刷新到第一页
|
columns.forEach((column) => {
|
||||||
refresh(bool = false) {
|
if (column.needTotal) {
|
||||||
bool &&
|
totalList.push({
|
||||||
(this.localPagination = Object.assign(
|
...column,
|
||||||
{},
|
total: 0
|
||||||
{
|
})
|
||||||
current: 1,
|
}
|
||||||
pageSize: this.localPagination.pageSize
|
})
|
||||||
|
return totalList
|
||||||
}
|
}
|
||||||
))
|
|
||||||
this.loadData()
|
|
||||||
},
|
|
||||||
// 加载数据方法 分页选项器 过滤条件 排序条件
|
// 加载数据方法 分页选项器 过滤条件 排序条件
|
||||||
loadData(pagination, filters, sorter) {
|
const loadData = (pagination, filters, sorter) => {
|
||||||
this.localLoading = true
|
data.localLoading = true
|
||||||
const parameter = Object.assign(
|
const parameter = Object.assign(
|
||||||
{
|
{
|
||||||
current:
|
current:
|
||||||
(pagination && pagination.current) ||
|
(pagination && pagination.current) || (props.showPagination && data.localPagination.current) || props.pageNum,
|
||||||
(this.showPagination && this.localPagination.current) ||
|
|
||||||
this.pageNum,
|
|
||||||
// 此处后端使用size作为分页参数
|
// 此处后端使用size作为分页参数
|
||||||
size:
|
size:
|
||||||
(pagination && pagination.pageSize) ||
|
(pagination && pagination.pageSize) ||
|
||||||
(this.showPagination && this.localPagination.pageSize) ||
|
(props.showPagination && data.localPagination.pageSize) ||
|
||||||
this.pageSize ||
|
props.pageSize ||
|
||||||
this.localPagination.pageSize
|
data.localPagination.pageSize
|
||||||
},
|
},
|
||||||
(sorter &&
|
(sorter &&
|
||||||
sorter.field && {
|
sorter.field && {
|
||||||
|
@ -188,85 +359,158 @@
|
||||||
...filters
|
...filters
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const result = this.data(parameter)
|
const result = props.data(parameter)
|
||||||
if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') {
|
if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') {
|
||||||
result.then((r) => {
|
result.then((r) => {
|
||||||
if (r == null) {
|
if (r == null) {
|
||||||
this.localLoading = false
|
data.localLoading = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.localPagination =
|
data.localPagination =
|
||||||
(this.showPagination &&
|
(props.showPagination &&
|
||||||
Object.assign({}, this.localPagination, {
|
Object.assign({}, data.localPagination, {
|
||||||
current: r.current, // pageNo, // 返回结果中的当前分页数
|
current: r.current, // pageNo, // 返回结果中的当前分页数
|
||||||
total: r.total, // totalRows, // 返回结果中的总记录数
|
total: r.total, // totalRows, // 返回结果中的总记录数
|
||||||
showSizeChanger: this.showSizeChanger,
|
showSizeChanger: props.showSizeChanger,
|
||||||
pageSizeOptions: this.pageSizeOptions,
|
pageSizeOptions: props.pageSizeOptions,
|
||||||
showTotal: (total, range) => {
|
showTotal: (total, range) => {
|
||||||
return `${range[0]}-${range[1]} 共 ${total} 条 `
|
return `${range[0]}-${range[1]} 共 ${total} 条 `
|
||||||
},
|
},
|
||||||
pageSize: (pagination && pagination.pageSize) || this.localPagination.pageSize
|
pageSize: (pagination && pagination.pageSize) || data.localPagination.pageSize
|
||||||
})) ||
|
})) ||
|
||||||
false
|
false
|
||||||
|
|
||||||
// 后端数据records为null保存修复
|
// 后端数据records为null保存修复
|
||||||
if (r.records == null) {
|
if (r.records == null) {
|
||||||
r.records = []
|
r.records = []
|
||||||
}
|
}
|
||||||
|
|
||||||
// 为防止删除数据后导致页面当前页面数据长度为 0 ,自动翻页到上一页
|
// 为防止删除数据后导致页面当前页面数据长度为 0 ,自动翻页到上一页
|
||||||
if (r.records.length === 0 && this.showPagination && this.localPagination.current > 1) {
|
if (r.records.length === 0 && props.showPagination && data.localPagination.current > 1) {
|
||||||
this.localPagination.current--
|
data.localPagination.current--
|
||||||
this.loadData()
|
loadData()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 当情况满足时,表示数据不满足分页大小,关闭 table 分页功能
|
// 当情况满足时,表示数据不满足分页大小,关闭 table 分页功能
|
||||||
try {
|
try {
|
||||||
/*
|
/*
|
||||||
if ((['auto', true].includes(this.showPagination) && r.total <= (r.pages * this.localPagination.size))) {
|
if ((['auto', true].includes(props.showPagination) && r.total <= (r.pages * data.localPagination.size))) {
|
||||||
this.localPagination.hideOnSinglePage = true
|
data.localPagination.hideOnSinglePage = true
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if (!this.showPagination) {
|
if (!props.showPagination) {
|
||||||
this.localPagination.hideOnSinglePage = true
|
data.localPagination.hideOnSinglePage = true
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.localPagination = false
|
data.localPagination = false
|
||||||
}
|
}
|
||||||
// 返回结果中的数组数据
|
// 返回结果中的数组数据
|
||||||
if (this.showPagination === false) {
|
if (props.showPagination === false) {
|
||||||
// 既然配置了不分页,那么我们这里接收到肯定是数组
|
// 既然配置了不分页,那么我们这里接收到肯定是数组
|
||||||
this.localDataSource = []
|
data.localDataSource = []
|
||||||
if (r instanceof Array) {
|
if (r instanceof Array) {
|
||||||
this.localDataSource = r
|
data.localDataSource = r
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.localDataSource = r.records
|
data.localDataSource = r.records
|
||||||
}
|
}
|
||||||
this.localLoading = false
|
data.localLoading = false
|
||||||
|
getTableProps()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
|
||||||
initTotalList(columns) {
|
|
||||||
const totalList = []
|
|
||||||
columns &&
|
|
||||||
columns instanceof Array &&
|
|
||||||
columns.forEach((column) => {
|
|
||||||
if (column.needTotal) {
|
|
||||||
totalList.push({
|
|
||||||
...column,
|
|
||||||
total: 0
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
// 加载props
|
||||||
|
const getTableProps = () => {
|
||||||
|
let renderProps = {}
|
||||||
|
const localKeys = Object.keys(data)
|
||||||
|
Object.keys(tableProps()).forEach((k) => {
|
||||||
|
const localKey = `local${k.substring(0, 1).toUpperCase()}${k.substring(1)}`
|
||||||
|
if (localKeys.includes(localKey)) {
|
||||||
|
renderProps[k] = data[localKey]
|
||||||
|
return renderProps[k]
|
||||||
|
}
|
||||||
|
if (k === 'rowSelection') {
|
||||||
|
if (props.rowSelection) {
|
||||||
|
// 如果需要使用alert,则重新绑定 rowSelection 事件
|
||||||
|
renderProps[k] = {
|
||||||
|
...props.rowSelection,
|
||||||
|
onChange: (selectedRowKeys, selectedRows) => {
|
||||||
|
updateSelect(selectedRowKeys, selectedRows)
|
||||||
|
typeof props[k].onChange !== 'undefined' && props[k].onChange(selectedRowKeys, selectedRows)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return renderProps[k]
|
||||||
|
} else if (!props.rowSelection) {
|
||||||
|
// 如果没打算开启 rowSelection 则清空默认的选择项
|
||||||
|
renderProps[k] = null
|
||||||
|
return renderProps[k]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (k === 'customRow') {
|
||||||
|
if (props.lineSelection && props.rowSelection) {
|
||||||
|
// 如果需要 整行选择,则重新绑定 customRow 事件
|
||||||
|
renderProps[k] = (record, index) => {
|
||||||
|
return {
|
||||||
|
...(typeof props.customRow !== 'undefined' && props.customRow(record, index)),
|
||||||
|
onClick: (event) => {
|
||||||
|
// 若存在原onClick则执行
|
||||||
|
typeof data[k] !== 'undefined' &&
|
||||||
|
typeof data[k](record, index).onClick !== 'undefined' &&
|
||||||
|
data[k](record, index).onClick(event)
|
||||||
|
// 记录为disabled则直接返回,默认为不可选
|
||||||
|
const rowDisabled =
|
||||||
|
typeof props.rowSelection.getCheckboxProps !== 'undefined' &&
|
||||||
|
props.rowSelection.getCheckboxProps(record).disabled
|
||||||
|
if (rowDisabled) return
|
||||||
|
// 过滤自定义按钮的非空白区域
|
||||||
|
const classList = event.target?.classList
|
||||||
|
if (!classList.contains('ant-table-cell')) return
|
||||||
|
const key = (typeof props.rowKey === 'function' && props.rowKey(record)) || props.rowKey || index
|
||||||
|
let selectedRows = props.rowSelection.selectedRows
|
||||||
|
let selectedRowKeys = props.rowSelection.selectedRowKeys
|
||||||
|
const rowType = props.rowSelection?.type || 'checkbox'
|
||||||
|
|
||||||
|
if (rowType === 'radio' || props.rowSelection.selectedRowKeys === undefined) {
|
||||||
|
selectedRowKeys = [key]
|
||||||
|
selectedRows = [record]
|
||||||
|
} else if (!props.rowSelection.selectedRowKeys?.includes(key)) {
|
||||||
|
selectedRowKeys.push(key)
|
||||||
|
selectedRows.push(record)
|
||||||
|
} else {
|
||||||
|
const index = props.rowSelection.selectedRowKeys?.findIndex((itemKey) => itemKey === key)
|
||||||
|
selectedRows.splice(index, 1)
|
||||||
|
selectedRowKeys.splice(index, 1)
|
||||||
|
}
|
||||||
|
updateSelect(selectedRowKeys, selectedRows)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return renderProps[k]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data[k] && (renderProps[k] = data[k])
|
||||||
|
// 此处配置表格大小与要显示的列
|
||||||
|
renderProps = {
|
||||||
|
...renderProps,
|
||||||
|
bordered: props.bordered,
|
||||||
|
size: data.customSize, // 注意这个size是a-table组件需要的,这里不能跟别的地方成为compSize
|
||||||
|
columns: data.columnsSetting.filter((value) => value.checked === undefined || value.checked)
|
||||||
|
}
|
||||||
|
return renderProps[k]
|
||||||
})
|
})
|
||||||
return totalList
|
renderTableProps.value = renderProps
|
||||||
},
|
}
|
||||||
// 用于更新已选中的列表数据 total 统计
|
// 用于更新已选中的列表数据 total 统计
|
||||||
updateSelect(selectedRowKeys, selectedRows) {
|
const updateSelect = (selectedRowKeys, selectedRows) => {
|
||||||
if (this.rowSelection) {
|
if (props.rowSelection) {
|
||||||
this.rowSelection.selectedRows = selectedRows
|
// eslint-disable-next-line vue/no-mutating-props
|
||||||
this.rowSelection.selectedRowKeys = selectedRowKeys
|
props.rowSelection.selectedRows = selectedRows
|
||||||
|
// eslint-disable-next-line vue/no-mutating-props
|
||||||
|
props.rowSelection.selectedRowKeys = selectedRowKeys
|
||||||
|
getTableProps()
|
||||||
}
|
}
|
||||||
const list = this.needTotalList
|
const list = data.needTotalList
|
||||||
this.needTotalList = list.map((item) => {
|
data.needTotalList = list.map((item) => {
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
total: selectedRows.reduce((sum, val) => {
|
total: selectedRows.reduce((sum, val) => {
|
||||||
|
@ -275,290 +519,26 @@
|
||||||
}, 0)
|
}, 0)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
// 清空 table 已选中项
|
// 清空 table 已选中项
|
||||||
clearSelected() {
|
const clearSelected = () => {
|
||||||
if (this.rowSelection) {
|
if (props.rowSelection) {
|
||||||
this.rowSelection.onChange([], [])
|
props.rowSelection.onChange([], [])
|
||||||
this.updateSelect([], [])
|
updateSelect([], [])
|
||||||
|
getTableProps()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
// 刷新并清空已选
|
// 刷新并清空已选
|
||||||
clearRefreshSelected(bool = false) {
|
const clearRefreshSelected = (bool = false) => {
|
||||||
this.refresh(bool)
|
refresh(bool)
|
||||||
this.clearSelected()
|
clearSelected()
|
||||||
},
|
|
||||||
// 处理交给 table 使用者去处理 clear 事件时,内部选中统计同时调用
|
|
||||||
renderClear(callback) {
|
|
||||||
if (this.rowSelection && this.rowSelection.selectedRowKeys && this.rowSelection.selectedRowKeys.length > 0) {
|
|
||||||
return (
|
|
||||||
<a
|
|
||||||
className="ml-6"
|
|
||||||
onClick={() => {
|
|
||||||
callback()
|
|
||||||
this.clearSelected()
|
|
||||||
}}>
|
|
||||||
{' '}
|
|
||||||
清空{' '}
|
|
||||||
</a>
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
},
|
// 暴露子组件的方法
|
||||||
renderAlert() {
|
defineExpose({
|
||||||
// 绘制统计列数据
|
clearRefreshSelected,
|
||||||
const needTotalItems = this.needTotalList.map((item) => {
|
refresh
|
||||||
return (
|
|
||||||
<span className="mr-3">
|
|
||||||
{item.title} 总计{' '}
|
|
||||||
<a className="font-6">{!item.customRender ? item.total : item.customRender(item.total)}</a>
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
// 绘制 alert 组件
|
onMounted(() => {
|
||||||
if (alert) {
|
init()
|
||||||
const showAlert =
|
|
||||||
(typeof this.alert === 'object' &&
|
|
||||||
this.alert !== null &&
|
|
||||||
this.alert.show &&
|
|
||||||
typeof this.rowSelection.selectedRowKeys !== 'undefined') ||
|
|
||||||
this.alert
|
|
||||||
if (showAlert) {
|
|
||||||
// 绘制 清空 按钮
|
|
||||||
const clearItem =
|
|
||||||
typeof this.alert === 'boolean' && this.alert
|
|
||||||
? this.renderClear(this.clearSelected)
|
|
||||||
: this.alert.clear && typeof this.alert.clear === 'function'
|
|
||||||
? this.renderClear(this.alert.clear)
|
|
||||||
: null
|
|
||||||
const message = (
|
|
||||||
<div>
|
|
||||||
<span className="mr-3">
|
|
||||||
已选择:{' '}
|
|
||||||
<a className="font-6">
|
|
||||||
{this.rowSelection && this.rowSelection.selectedRowKeys
|
|
||||||
? this.rowSelection.selectedRowKeys.length
|
|
||||||
: 0}
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
{needTotalItems}
|
|
||||||
{clearItem}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
return <a-alert showIcon class="mb-4" message={message} />
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
columnChange(val) {
|
|
||||||
this.columnsSetting = val
|
|
||||||
},
|
|
||||||
renderHeader() {
|
|
||||||
let tools = [
|
|
||||||
{
|
|
||||||
name: 'refresh',
|
|
||||||
icon: <sync-outlined class="ml-4" />,
|
|
||||||
title: '刷新',
|
|
||||||
onClick: () => {
|
|
||||||
this.refresh()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'height',
|
|
||||||
icon: <column-height-outlined />,
|
|
||||||
title: '密度',
|
|
||||||
isDropdown: true,
|
|
||||||
menu: () => {
|
|
||||||
const onClick = ({ key }) => {
|
|
||||||
this.customSize = key
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<a-menu onClick={onClick} selectable selectedKeys={[this.customSize]}>
|
|
||||||
<a-menu-item key="default">默认</a-menu-item>
|
|
||||||
<a-menu-item key="middle">中等</a-menu-item>
|
|
||||||
<a-menu-item key="small">紧凑</a-menu-item>
|
|
||||||
</a-menu>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onClick: () => {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'columnSetting',
|
|
||||||
icon: <setting-outlined />,
|
|
||||||
title: '列设置',
|
|
||||||
isPopover: true,
|
|
||||||
visible: false,
|
|
||||||
menu: () => {
|
|
||||||
return <columnSetting columns={this.columns} onColumnChange={this.columnChange} />
|
|
||||||
},
|
|
||||||
onClick: () => {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
if (this.extraTool.length) {
|
|
||||||
tools = tools.concat(this.extraTool)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 斑马纹
|
|
||||||
const changeRowClass = (value) => {
|
|
||||||
const val = value.target.checked
|
|
||||||
this.localSettings.rowClassNameSwitch = val
|
|
||||||
const evenClass = val ? (_record, index) => (index % 2 === 1 ? 'table-striped' : null) : this.rowClassName
|
|
||||||
this.localSettings.rowClassName = evenClass
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<div className="s-table-tool">
|
|
||||||
<div className="s-table-tool-left">{this.$slots.operator && this.$slots.operator()}</div>
|
|
||||||
<div className="layout-items-center s-table-tool-right">
|
|
||||||
{this.toolConfig.striped ? (
|
|
||||||
<div className="layout-items-center ml-4">
|
|
||||||
<a-checkbox checked={this.localSettings.rowClassNameSwitch} onChange={changeRowClass}>
|
|
||||||
斑马纹
|
|
||||||
</a-checkbox>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{tools.map((tool) => {
|
|
||||||
if (!this.toolConfig[tool.name]) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
const tooltipEle = (
|
|
||||||
<a-tooltip title={tool.title} class="s-tool-item" onClick={tool.onClick}>
|
|
||||||
{tool.icon}
|
|
||||||
</a-tooltip>
|
|
||||||
)
|
|
||||||
if (tool.isPopover) {
|
|
||||||
return (
|
|
||||||
<a-popover
|
|
||||||
trigger={'click'}
|
|
||||||
placement="topLeft"
|
|
||||||
overlayClassName="s-table-column-settings"
|
|
||||||
arrow-point-at-center
|
|
||||||
content={tool.menu()}>
|
|
||||||
{tooltipEle}
|
|
||||||
</a-popover>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (tool.isDropdown) {
|
|
||||||
return (
|
|
||||||
<a-dropdown trigger={['click']} overlay={tool.menu()}>
|
|
||||||
{tooltipEle}
|
|
||||||
</a-dropdown>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return tooltipEle
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let props = {}
|
|
||||||
const localKeys = Object.keys(this.$data)
|
|
||||||
Object.keys(tableProps()).forEach((k) => {
|
|
||||||
const localKey = `local${k.substring(0, 1).toUpperCase()}${k.substring(1)}`
|
|
||||||
if (localKeys.includes(localKey)) {
|
|
||||||
props[k] = this[localKey]
|
|
||||||
return props[k]
|
|
||||||
}
|
|
||||||
if (k === 'rowSelection') {
|
|
||||||
if (this.rowSelection) {
|
|
||||||
// 如果需要使用alert,则重新绑定 rowSelection 事件
|
|
||||||
props[k] = {
|
|
||||||
...this.rowSelection,
|
|
||||||
onChange: (selectedRowKeys, selectedRows) => {
|
|
||||||
this.updateSelect(selectedRowKeys, selectedRows)
|
|
||||||
typeof this[k].onChange !== 'undefined' && this[k].onChange(selectedRowKeys, selectedRows)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return props[k]
|
|
||||||
} else if (!this.rowSelection) {
|
|
||||||
// 如果没打算开启 rowSelection 则清空默认的选择项
|
|
||||||
props[k] = null
|
|
||||||
return props[k]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (k === 'customRow') {
|
|
||||||
if (this.lineSelection && this.rowSelection) {
|
|
||||||
// 如果需要 整行选择,则重新绑定 customRow 事件
|
|
||||||
props[k] = (record, index) => {
|
|
||||||
return {
|
|
||||||
...(typeof this.customRow !== 'undefined' && this.customRow(record, index)),
|
|
||||||
onClick: (event) => {
|
|
||||||
// 若存在原onClick则执行
|
|
||||||
typeof this[k] !== 'undefined' &&
|
|
||||||
typeof this[k](record, index).onClick !== 'undefined' &&
|
|
||||||
this[k](record, index).onClick(event)
|
|
||||||
// 记录为disabled则直接返回,默认为不可选
|
|
||||||
const rowDisabled =
|
|
||||||
typeof this.rowSelection.getCheckboxProps !== 'undefined' &&
|
|
||||||
this.rowSelection.getCheckboxProps(record).disabled
|
|
||||||
if (rowDisabled) return
|
|
||||||
// 过滤自定义按钮的非空白区域
|
|
||||||
const classList = event.target?.classList
|
|
||||||
if (!classList.contains('ant-table-cell')) return
|
|
||||||
const key = (typeof this.rowKey === 'function' && this.rowKey(record)) || this.rowKey || index
|
|
||||||
let selectedRows = this.rowSelection.selectedRows
|
|
||||||
let selectedRowKeys = this.rowSelection.selectedRowKeys
|
|
||||||
const rowType = this.rowSelection?.type || 'checkbox'
|
|
||||||
|
|
||||||
if (rowType === 'radio' || this.rowSelection.selectedRowKeys === undefined) {
|
|
||||||
selectedRowKeys = [key]
|
|
||||||
selectedRows = [record]
|
|
||||||
} else if (!this.rowSelection.selectedRowKeys?.includes(key)) {
|
|
||||||
selectedRowKeys.push(key)
|
|
||||||
selectedRows.push(record)
|
|
||||||
} else {
|
|
||||||
const index = this.rowSelection.selectedRowKeys?.findIndex((itemKey) => itemKey === key)
|
|
||||||
selectedRows.splice(index, 1)
|
|
||||||
selectedRowKeys.splice(index, 1)
|
|
||||||
}
|
|
||||||
this.updateSelect(selectedRowKeys, selectedRows)
|
|
||||||
typeof this.rowSelection.onChange !== 'undefined' &&
|
|
||||||
this.rowSelection.onChange(selectedRowKeys, selectedRows)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return props[k]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this[k] && (props[k] = this[k])
|
|
||||||
// 此处配置表格大小与要显示的列
|
|
||||||
props = {
|
|
||||||
...props,
|
|
||||||
size: this.customSize, // 注意这个size是a-table组件需要的,这里不能跟别的地方成为compSize
|
|
||||||
columns: this.columnsSetting.filter((value) => value.checked === undefined || value.checked)
|
|
||||||
}
|
|
||||||
// 如果在使用界面每配置scroll,那么使用全局的,对缩小屏幕下横向滚动条左右滑动
|
|
||||||
if (!props.scroll) {
|
|
||||||
props.scroll = { x: 1000 }
|
|
||||||
// 对于界面上要显示的字段太多,默认加上横向滚动条
|
|
||||||
if (props.columns && props.columns.length > 10) {
|
|
||||||
props.scroll = { x: 1200 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return props[k]
|
|
||||||
})
|
})
|
||||||
const table = (
|
|
||||||
<a-table
|
|
||||||
{...props}
|
|
||||||
{...this.localSettings}
|
|
||||||
v-slots={this.$slots}
|
|
||||||
onChange={this.loadData}
|
|
||||||
onExpand={(expanded, record) => {
|
|
||||||
this.$emit('expand', expanded, record)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="table-wrapper">
|
|
||||||
{this.renderHeader()}
|
|
||||||
{this.renderAlert()}
|
|
||||||
{table}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<a-tag color="orange">{{ item.title }}</a-tag>
|
<a-tag color="orange">{{ item.title }}</a-tag>
|
||||||
</template>
|
</template>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<template v-for="{ key, label, icon, color } in props.actions">
|
<template v-for="{ key, label, icon, color } in props.actions" :key="key">
|
||||||
<a-tooltip :title="label">
|
<a-tooltip :title="label">
|
||||||
<component :is="icon" @click="doAction(key, item)" :style="{ color: color }" />
|
<component :is="icon" @click="doAction(key, item)" :style="{ color: color }" />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
|
@ -22,9 +22,11 @@
|
||||||
<span class="xn-card-meta-title">{{ item.subTitle }}</span>
|
<span class="xn-card-meta-title">{{ item.subTitle }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #description>
|
<template #description>
|
||||||
<div v-if="item.contents" v-for="content in item.contents">
|
<div v-if="item.contents">
|
||||||
|
<div v-for="content in item.contents" :key="content.value">
|
||||||
<span>{{ content.label }}:{{ content.value }}</span>
|
<span>{{ content.label }}:{{ content.value }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</a-card-meta>
|
</a-card-meta>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|
|
@ -3,86 +3,80 @@
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup>
|
||||||
<script>
|
const props = defineProps({
|
||||||
export default {
|
|
||||||
name: 'XnContextMenu',
|
|
||||||
props: {
|
|
||||||
target: null,
|
target: null,
|
||||||
show: Boolean
|
show: Boolean
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
triggerShowFn: () => {},
|
|
||||||
triggerHideFn: () => {},
|
|
||||||
x: null,
|
|
||||||
y: null,
|
|
||||||
style: {},
|
|
||||||
binded: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
show(show) {
|
|
||||||
if (show) {
|
|
||||||
this.bindHideEvents()
|
|
||||||
} else {
|
|
||||||
this.unbindHideEvents()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
target(target) {
|
|
||||||
this.bindEvents()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.bindEvents()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 初始化事件
|
|
||||||
bindEvents() {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (!this.target || this.binded) return
|
|
||||||
this.triggerShowFn = this.contextMenuHandler.bind(this)
|
|
||||||
this.target.addEventListener('contextmenu', this.triggerShowFn)
|
|
||||||
this.binded = true
|
|
||||||
})
|
})
|
||||||
},
|
|
||||||
// 取消绑定事件
|
const x = ref(null)
|
||||||
unbindEvents() {
|
const y = ref(null)
|
||||||
if (!this.target) return
|
const style = ref({})
|
||||||
this.target.removeEventListener('contextmenu', this.triggerShowFn)
|
const binded = ref(false)
|
||||||
},
|
const emit = defineEmits(['update:show', 'get-context-menu'])
|
||||||
|
|
||||||
|
// 监听show的变化
|
||||||
|
watch(
|
||||||
|
() => props.show,
|
||||||
|
(newValue) => {
|
||||||
|
newValue ? bindHideEvents() : unbindHideEvents()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
watch(
|
||||||
|
() => props.target,
|
||||||
|
(newValue) => {
|
||||||
|
bindEvents()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 初始化事件
|
||||||
|
const bindEvents = (e) => {
|
||||||
|
nextTick(() => {
|
||||||
|
if (!props.target || binded.value) return
|
||||||
|
props.target.addEventListener('contextmenu', contextMenuHandler)
|
||||||
|
binded.value = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 绑定隐藏菜单事件
|
// 绑定隐藏菜单事件
|
||||||
bindHideEvents() {
|
const bindHideEvents = () => {
|
||||||
this.triggerHideFn = this.clickDocumentHandler.bind(this)
|
document.addEventListener('mousedown', clickDocumentHandler)
|
||||||
document.addEventListener('mousedown', this.triggerHideFn)
|
document.addEventListener('mousewheel', clickDocumentHandler)
|
||||||
document.addEventListener('mousewheel', this.triggerHideFn)
|
}
|
||||||
},
|
|
||||||
// 取消绑定隐藏菜单事件
|
// 取消绑定隐藏菜单事件
|
||||||
unbindHideEvents() {
|
const unbindHideEvents = () => {
|
||||||
document.removeEventListener('mousedown', this.triggerHideFn)
|
document.removeEventListener('mousedown', clickDocumentHandler)
|
||||||
document.removeEventListener('mousewheel', this.triggerHideFn)
|
document.removeEventListener('mousewheel', clickDocumentHandler)
|
||||||
},
|
}
|
||||||
|
|
||||||
// 鼠标按压事件处理器
|
// 鼠标按压事件处理器
|
||||||
clickDocumentHandler(e) {
|
const clickDocumentHandler = () => {
|
||||||
this.$emit('update:show', false)
|
emit('update:show', false)
|
||||||
},
|
}
|
||||||
|
|
||||||
// 右键事件事件处理
|
// 右键事件事件处理
|
||||||
contextMenuHandler(e) {
|
const contextMenuHandler = (e) => {
|
||||||
this.x = e.clientX
|
x.value = e.clientX
|
||||||
this.y = e.clientY
|
y.value = e.clientY
|
||||||
this.layout()
|
layout()
|
||||||
this.$emit('update:show', true)
|
emit('update:show', true)
|
||||||
this.$emit('get-context-menu', e)
|
emit('get-context-menu', e)
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
},
|
}
|
||||||
|
|
||||||
// 布局
|
// 布局
|
||||||
layout() {
|
const layout = () => {
|
||||||
this.style = {
|
style.value = {
|
||||||
left: this.x + 'px',
|
left: x.value + 'px',
|
||||||
top: this.y + 'px',
|
top: y.value + 'px',
|
||||||
display: 'block'
|
display: 'block'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// 取消绑定事件
|
||||||
|
const unbindEvents = () => {
|
||||||
|
if (!props.target) return
|
||||||
|
props.target.removeEventListener('contextmenu', contextMenuHandler)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -4,44 +4,50 @@
|
||||||
<slot :name="slotKey" />
|
<slot :name="slotKey" />
|
||||||
</template>
|
</template>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
<a-drawer v-else :visible="visible" v-bind="$attrs" :footer-style="{ textAlign: 'right' }">
|
<a-drawer v-else :visible="visible" v-bind="$attrs" @close="cancel" :footer-style="{ textAlign: 'right' }">
|
||||||
<template v-for="slotKey in slotKeys" #[slotKey]>
|
<template v-for="slotKey in slotKeys" #[slotKey]>
|
||||||
<slot :name="slotKey" />
|
<slot :name="slotKey" />
|
||||||
</template>
|
</template>
|
||||||
</a-drawer>
|
</a-drawer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import { mapState } from 'pinia'
|
import { useSlots } from 'vue'
|
||||||
import { globalStore } from '@/store'
|
const slots = useSlots()
|
||||||
|
|
||||||
const FormContainerTypeEnum = {
|
import { globalStore } from '@/store'
|
||||||
DRAWER: 'drawer',
|
const store = globalStore()
|
||||||
MODAL: 'modal'
|
const props = defineProps({
|
||||||
}
|
|
||||||
export default {
|
|
||||||
name: 'XnFormContainer',
|
|
||||||
inheritAttrs: false,
|
|
||||||
props: {
|
|
||||||
visible: {
|
visible: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
computed: {
|
|
||||||
...mapState(globalStore, ['formStyle']),
|
const FormContainerTypeEnum = {
|
||||||
slotKeys() {
|
DRAWER: 'drawer',
|
||||||
return Object.keys(this.$slots)
|
MODAL: 'modal'
|
||||||
},
|
|
||||||
isModal() {
|
|
||||||
return FormContainerTypeEnum.MODAL === this.formStyle
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
cancel() {
|
|
||||||
this.$emit('close')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formStyle = computed(() => {
|
||||||
|
return store.formStyle
|
||||||
|
})
|
||||||
|
const slotKeys = computed(() => {
|
||||||
|
return Object.keys(slots)
|
||||||
|
})
|
||||||
|
const isModal = computed(() => {
|
||||||
|
return FormContainerTypeEnum.MODAL === formStyle.value
|
||||||
|
})
|
||||||
|
const emit = defineEmits(['close'])
|
||||||
|
const cancel = () => {
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 声明额外的选项
|
||||||
|
export default {
|
||||||
|
inheritAttrs: false
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- 本组件这兄弟写的很好 请参照:https://blog.csdn.net/weixin_41897680/article/details/124925222-->
|
<!-- 本组件这兄弟写的很好 请参照:https://blog.csdn.net/weixin_41897680/article/details/124925222-->
|
||||||
<div class="hljs-container" :codetype="props.language">
|
<div class="hljs-container" :codetype="props.language">
|
||||||
<highlightjs :language="props.language" :autodetect="!props.language" :code="props.code"></highlightjs>
|
<highlightjs :language="props.language" :autodetect="!props.language" :code="props.code" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -54,8 +54,8 @@
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
/** 滚动条 */
|
/** 滚动条 */
|
||||||
:deep(.hljs,.hljs-container) {
|
:deep(.hljs, .hljs-container) {
|
||||||
max-height: 300px!important;
|
max-height: 300px !important;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,46 +37,50 @@ const app = createApp(App)
|
||||||
app.use(vueEsign)
|
app.use(vueEsign)
|
||||||
// 局部
|
// 局部
|
||||||
import vueEsign from 'vue-esign'
|
import vueEsign from 'vue-esign'
|
||||||
components: { vueEsign }
|
// vue3 中只需需引入组件就可以使用无需注册
|
||||||
```
|
```
|
||||||
2. 页面中使用
|
2. 页面中使用
|
||||||
**必须设置 `ref` ,用来调用组件的两个内置方法 `reset()` 和 `generate()`**
|
// 在组件中使用 ref="esign"
|
||||||
|
**在script中必须设置 `const esign = ref()` ,用来调用组件的两个内置方法 `reset()` 和 `generate()`**
|
||||||
|
|
||||||
无需给组件设置 `style` 的宽高,如果画布的 `width`属性值没超出父元素的样式宽度,则该组件的样式宽度就是画布宽度,超出的话,组件样式宽度则是父元素的100%; 所以只需设置好父元素的宽度即可;
|
无需给组件设置 `style` 的宽高,如果画布的 `width`属性值没超出父元素的样式宽度,则该组件的样式宽度就是画布宽度,超出的话,组件样式宽度则是父元素的100%; 所以只需设置好父元素的宽度即可;
|
||||||
```html
|
```html
|
||||||
<!-- vue2 -->
|
|
||||||
<vue-esign ref="esign" :width="800" :height="300" :isCrop="isCrop" :lineWidth="lineWidth" :lineColor="lineColor" :bgColor.sync="bgColor" />
|
|
||||||
<!-- vue3 -->
|
<!-- vue3 -->
|
||||||
<vue-esign ref="esign" :width="800" :height="300" :isCrop="isCrop" :lineWidth="lineWidth" :lineColor="lineColor" v-model:bgColor="bgColor" />
|
<vue-esign ref="esign" :width="800" :height="300" :isCrop="isCrop" :lineWidth="lineWidth" :lineColor="lineColor" v-model:bgColor="bgColor" :quality="1"/>
|
||||||
|
|
||||||
<!-- isClearBgColor为false时,不必再给bgColor加sync修饰符或v-model -->
|
<!-- isClearBgColor为false时,不必再给bgColor加sync修饰符或v-model -->
|
||||||
|
|
||||||
<button @click="handleReset">清空画板</button>
|
<a-button type="primary" @click="handleGenerate">预览</a-button>
|
||||||
<button @click="handleGenerate">生成图片</button>
|
<a-button @click="handleReset">清屏</a-button>
|
||||||
```
|
```
|
||||||
```js
|
|
||||||
data () {
|
```vue
|
||||||
return {
|
<script setup>
|
||||||
lineWidth: 6,
|
const esign = ref(false) // 相当于$ref
|
||||||
lineColor: '#000000',
|
|
||||||
bgColor: '',
|
// 这里const相当于vue2中的data()
|
||||||
resultImg: '',
|
const resultImg = ref('')
|
||||||
isCrop: false
|
const isCrop = ref(false)
|
||||||
|
const lineWidth = ref(6)
|
||||||
|
const lineColor = ref('#000000')
|
||||||
|
const bgColor = ref('')
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
esign.value.reset()
|
||||||
|
resultImg.value = ''
|
||||||
}
|
}
|
||||||
},
|
const handleGenerate = () => {
|
||||||
methods: {
|
esign.value
|
||||||
handleReset () {
|
.generate()
|
||||||
this.$refs.esign.reset()
|
.then((res) => {
|
||||||
},
|
resultImg.value = res
|
||||||
handleGenerate () {
|
})
|
||||||
this.$refs.esign.generate().then(res => {
|
.catch(() => {
|
||||||
this.resultImg = res
|
message.warning('无任何签字') // 画布没有签字时会执行这里 'Not Signned'
|
||||||
}).catch(err => {
|
|
||||||
alert(err) // 画布没有签字时会执行这里 'Not Signned'
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
</script>
|
||||||
```
|
|
||||||
3. 说明
|
3. 说明
|
||||||
|
|
||||||
| 属性 | 类型 | 默认值 | 说明 |
|
| 属性 | 类型 | 默认值 | 说明 |
|
||||||
|
@ -95,7 +99,7 @@ methods: {
|
||||||
|
|
||||||
**清空画布**
|
**清空画布**
|
||||||
```js
|
```js
|
||||||
this.$refs.esign.reset()
|
esign.value.reset()
|
||||||
```
|
```
|
||||||
|
|
||||||
**生成图片**
|
**生成图片**
|
||||||
|
@ -103,7 +107,7 @@ this.$refs.esign.reset()
|
||||||
```js
|
```js
|
||||||
// 可选配置参数 ,在未设置format或quality属性时可在生成图片时配置 例如: {format:'image/jpeg', quality: 0.5}
|
// 可选配置参数 ,在未设置format或quality属性时可在生成图片时配置 例如: {format:'image/jpeg', quality: 0.5}
|
||||||
// this.$refs.esign.generate({format:'image/jpeg', quality: 0.5})
|
// this.$refs.esign.generate({format:'image/jpeg', quality: 0.5})
|
||||||
this.$refs.esign.generate().then(res => {
|
esign.value.generate().then(res => {
|
||||||
console.log(res) // base64图片
|
console.log(res) // base64图片
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
alert(err) // 画布没有签字时会执行这里 'Not Signned'
|
alert(err) // 画布没有签字时会执行这里 'Not Signned'
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
<!--
|
|
||||||
本插件来源于:https://github.com/JaimeCheng/vue-esign#readme
|
|
||||||
因为集成进来跟我的Vue版本不一致,打包出问题,所以集成源码方式,感谢作者的源码
|
|
||||||
-->
|
|
||||||
<template>
|
<template>
|
||||||
<canvas
|
<canvas
|
||||||
ref="canvas"
|
ref="canvas"
|
||||||
|
@ -14,9 +10,11 @@
|
||||||
></canvas>
|
></canvas>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
export default {
|
const canvas = ref()
|
||||||
props: {
|
const emit = defineEmits(['update:bgColor'])
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
width: {
|
width: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 800
|
default: 800
|
||||||
|
@ -53,225 +51,222 @@
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 1
|
default: 1
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
data() {
|
|
||||||
return {
|
const hasDrew = ref(false)
|
||||||
hasDrew: false,
|
const resultImg = ref('')
|
||||||
resultImg: '',
|
const points = ref([])
|
||||||
points: [],
|
const canvasTxt = ref(null)
|
||||||
canvasTxt: null,
|
const startX = ref(0)
|
||||||
startX: 0,
|
const startY = ref(0)
|
||||||
startY: 0,
|
const isDrawing = ref(false)
|
||||||
isDrawing: false,
|
const sratio = ref(1)
|
||||||
sratio: 1
|
|
||||||
}
|
const ratio = computed(() => {
|
||||||
},
|
return props.height / props.width
|
||||||
computed: {
|
})
|
||||||
ratio() {
|
const stageInfo = computed(() => {
|
||||||
return this.height / this.width
|
return canvas.value.getBoundingClientRect()
|
||||||
},
|
})
|
||||||
stageInfo() {
|
const myBg = computed(() => {
|
||||||
return this.$refs.canvas.getBoundingClientRect()
|
return props.bgColor ? props.bgColor : 'rgba(255, 255, 255, 0)'
|
||||||
},
|
})
|
||||||
myBg() {
|
|
||||||
return this.bgColor ? this.bgColor : 'rgba(255, 255, 255, 0)'
|
watch(myBg, (newVal) => {
|
||||||
}
|
canvas.value.style.background = newVal
|
||||||
},
|
})
|
||||||
watch: {
|
|
||||||
myBg: function (newVal) {
|
onBeforeMount(() => {
|
||||||
this.$refs.canvas.style.background = newVal
|
window.addEventListener('resize', $_resizeHandler)
|
||||||
}
|
})
|
||||||
},
|
onBeforeUnmount(() => {
|
||||||
beforeMount() {
|
window.removeEventListener('resize', $_resizeHandler)
|
||||||
window.addEventListener('resize', this.$_resizeHandler)
|
})
|
||||||
},
|
|
||||||
// eslint-disable-next-line vue/no-deprecated-destroyed-lifecycle
|
onMounted(() => {
|
||||||
beforeDestroy() {
|
canvas.value.height = props.height
|
||||||
window.removeEventListener('resize', this.$_resizeHandler)
|
canvas.value.width = props.width
|
||||||
},
|
canvas.value.style.background = myBg.value
|
||||||
mounted() {
|
$_resizeHandler()
|
||||||
const canvas = this.$refs.canvas
|
|
||||||
canvas.height = this.height
|
|
||||||
canvas.width = this.width
|
|
||||||
canvas.style.background = this.myBg
|
|
||||||
this.$_resizeHandler()
|
|
||||||
// 在画板以外松开鼠标后冻结画笔
|
// 在画板以外松开鼠标后冻结画笔
|
||||||
document.onmouseup = () => {
|
document.onmouseup = () => {
|
||||||
this.isDrawing = false
|
isDrawing.value = false
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
methods: {
|
|
||||||
$_resizeHandler() {
|
const $_resizeHandler = () => {
|
||||||
const canvas = this.$refs.canvas
|
canvas.value.style.width = props.width + 'px'
|
||||||
canvas.style.width = this.width + 'px'
|
const realw = parseFloat(window.getComputedStyle(canvas.value).width)
|
||||||
const realw = parseFloat(window.getComputedStyle(canvas).width)
|
canvas.value.style.height = ratio.value * realw + 'px'
|
||||||
canvas.style.height = this.ratio * realw + 'px'
|
canvasTxt.value = canvas.value.getContext('2d', { willReadFrequently: true })
|
||||||
this.canvasTxt = canvas.getContext('2d')
|
canvasTxt.value.scale(Number(sratio.value), Number(sratio.value))
|
||||||
this.canvasTxt.scale(Number(this.sratio), Number(this.sratio))
|
sratio.value = realw / props.width
|
||||||
this.sratio = realw / this.width
|
canvasTxt.value.scale(1 / sratio.value, 1 / sratio.value)
|
||||||
this.canvasTxt.scale(1 / this.sratio, 1 / this.sratio)
|
}
|
||||||
},
|
|
||||||
// pc
|
// pc
|
||||||
mouseDown(e) {
|
const mouseDown = (e) => {
|
||||||
e = e || event
|
e = e || event
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
this.isDrawing = true
|
isDrawing.value = true
|
||||||
this.hasDrew = true
|
hasDrew.value = true
|
||||||
let obj = {
|
let obj = {
|
||||||
x: e.offsetX,
|
x: e.offsetX,
|
||||||
y: e.offsetY
|
y: e.offsetY
|
||||||
}
|
}
|
||||||
this.drawStart(obj)
|
drawStart(obj)
|
||||||
},
|
}
|
||||||
mouseMove(e) {
|
const mouseMove = (e) => {
|
||||||
e = e || event
|
e = e || event
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (this.isDrawing) {
|
if (isDrawing.value) {
|
||||||
let obj = {
|
let obj = {
|
||||||
x: e.offsetX,
|
x: e.offsetX,
|
||||||
y: e.offsetY
|
y: e.offsetY
|
||||||
}
|
}
|
||||||
this.drawMove(obj)
|
drawMove(obj)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
mouseUp(e) {
|
const mouseUp = (e) => {
|
||||||
e = e || event
|
e = e || event
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
let obj = {
|
let obj = {
|
||||||
x: e.offsetX,
|
x: e.offsetX,
|
||||||
y: e.offsetY
|
y: e.offsetY
|
||||||
}
|
}
|
||||||
this.drawEnd(obj)
|
drawEnd(obj)
|
||||||
this.isDrawing = false
|
isDrawing.value = false
|
||||||
},
|
}
|
||||||
|
|
||||||
// mobile
|
// mobile
|
||||||
touchStart(e) {
|
const touchStart = (e) => {
|
||||||
e = e || event
|
e = e || event
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
this.hasDrew = true
|
hasDrew.value = true
|
||||||
if (e.touches.length === 1) {
|
if (e.touches.length === 1) {
|
||||||
let obj = {
|
let obj = {
|
||||||
x: e.targetTouches[0].clientX - this.$refs.canvas.getBoundingClientRect().left,
|
x: e.targetTouches[0].clientX - canvas.value.getBoundingClientRect().left,
|
||||||
y: e.targetTouches[0].clientY - this.$refs.canvas.getBoundingClientRect().top
|
y: e.targetTouches[0].clientY - canvas.value.getBoundingClientRect().top
|
||||||
}
|
}
|
||||||
this.drawStart(obj)
|
drawStart(obj)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
touchMove(e) {
|
const touchMove = (e) => {
|
||||||
e = e || event
|
e = e || event
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (e.touches.length === 1) {
|
if (e.touches.length === 1) {
|
||||||
let obj = {
|
let obj = {
|
||||||
x: e.targetTouches[0].clientX - this.$refs.canvas.getBoundingClientRect().left,
|
x: e.targetTouches[0].clientX - canvas.value.getBoundingClientRect().left,
|
||||||
y: e.targetTouches[0].clientY - this.$refs.canvas.getBoundingClientRect().top
|
y: e.targetTouches[0].clientY - canvas.value.getBoundingClientRect().top
|
||||||
}
|
}
|
||||||
this.drawMove(obj)
|
drawMove(obj)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
touchEnd(e) {
|
const touchEnd = (e) => {
|
||||||
e = e || event
|
e = e || event
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (e.touches.length === 1) {
|
if (e.touches.length === 1) {
|
||||||
let obj = {
|
let obj = {
|
||||||
x: e.targetTouches[0].clientX - this.$refs.canvas.getBoundingClientRect().left,
|
x: e.targetTouches[0].clientX - canvas.value.getBoundingClientRect().left,
|
||||||
y: e.targetTouches[0].clientY - this.$refs.canvas.getBoundingClientRect().top
|
y: e.targetTouches[0].clientY - canvas.value.getBoundingClientRect().top
|
||||||
|
}
|
||||||
|
drawEnd(obj)
|
||||||
}
|
}
|
||||||
this.drawEnd(obj)
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
// 绘制
|
// 绘制
|
||||||
drawStart(obj) {
|
const drawStart = (obj) => {
|
||||||
this.startX = obj.x
|
startX.value = obj.x
|
||||||
this.startY = obj.y
|
startY.value = obj.y
|
||||||
this.canvasTxt.beginPath()
|
canvasTxt.value.beginPath()
|
||||||
this.canvasTxt.moveTo(this.startX, this.startY)
|
canvasTxt.value.moveTo(startX.value, startY.value)
|
||||||
this.canvasTxt.lineTo(obj.x, obj.y)
|
canvasTxt.value.lineTo(obj.x, obj.y)
|
||||||
this.canvasTxt.lineCap = 'round'
|
canvasTxt.value.lineCap = 'round'
|
||||||
this.canvasTxt.lineJoin = 'round'
|
canvasTxt.value.lineJoin = 'round'
|
||||||
this.canvasTxt.lineWidth = this.lineWidth * this.sratio
|
canvasTxt.value.lineWidth = props.lineWidth * sratio.value
|
||||||
this.canvasTxt.stroke()
|
canvasTxt.value.stroke()
|
||||||
this.canvasTxt.closePath()
|
canvasTxt.value.closePath()
|
||||||
this.points.push(obj)
|
points.value.push(obj)
|
||||||
},
|
}
|
||||||
drawMove(obj) {
|
const drawMove = (obj) => {
|
||||||
this.canvasTxt.beginPath()
|
canvasTxt.value.beginPath()
|
||||||
this.canvasTxt.moveTo(this.startX, this.startY)
|
canvasTxt.value.moveTo(startX.value, startY.value)
|
||||||
this.canvasTxt.lineTo(obj.x, obj.y)
|
canvasTxt.value.lineTo(obj.x, obj.y)
|
||||||
this.canvasTxt.strokeStyle = this.lineColor
|
canvasTxt.value.strokeStyle = props.lineColor
|
||||||
this.canvasTxt.lineWidth = this.lineWidth * this.sratio
|
canvasTxt.value.lineWidth = props.lineWidth * sratio.value
|
||||||
this.canvasTxt.lineCap = 'round'
|
canvasTxt.value.lineCap = 'round'
|
||||||
this.canvasTxt.lineJoin = 'round'
|
canvasTxt.value.lineJoin = 'round'
|
||||||
this.canvasTxt.stroke()
|
canvasTxt.value.stroke()
|
||||||
this.canvasTxt.closePath()
|
canvasTxt.value.closePath()
|
||||||
this.startY = obj.y
|
startY.value = obj.y
|
||||||
this.startX = obj.x
|
startX.value = obj.x
|
||||||
this.points.push(obj)
|
points.value.push(obj)
|
||||||
},
|
}
|
||||||
drawEnd(obj) {
|
const drawEnd = (obj) => {
|
||||||
this.canvasTxt.beginPath()
|
canvasTxt.value.beginPath()
|
||||||
this.canvasTxt.moveTo(this.startX, this.startY)
|
canvasTxt.value.moveTo(startX.value, startY.value)
|
||||||
this.canvasTxt.lineTo(obj.x, obj.y)
|
canvasTxt.value.lineTo(obj.x, obj.y)
|
||||||
this.canvasTxt.lineCap = 'round'
|
canvasTxt.value.lineCap = 'round'
|
||||||
this.canvasTxt.lineJoin = 'round'
|
canvasTxt.value.lineJoin = 'round'
|
||||||
this.canvasTxt.stroke()
|
canvasTxt.value.stroke()
|
||||||
this.canvasTxt.closePath()
|
canvasTxt.value.closePath()
|
||||||
this.points.push(obj)
|
points.value.push(obj)
|
||||||
this.points.push({ x: -1, y: -1 })
|
points.value.push({ x: -1, y: -1 })
|
||||||
},
|
}
|
||||||
|
|
||||||
// 操作
|
// 操作
|
||||||
generate(options) {
|
const generate = (options) => {
|
||||||
let imgFormat = options && options.format ? options.format : this.format
|
let imgFormat = options && options.format ? options.format : props.format
|
||||||
let imgQuality = options && options.quality ? options.quality : this.quality
|
let imgQuality = options && options.quality ? options.quality : props.quality
|
||||||
const pm = new Promise((resolve, reject) => {
|
const pm = new Promise((resolve, reject) => {
|
||||||
if (!this.hasDrew) {
|
if (!hasDrew.value) {
|
||||||
reject(`Warning: Not Signned!`)
|
reject(`Warning: Not Signned!`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var resImgData = this.canvasTxt.getImageData(0, 0, this.$refs.canvas.width, this.$refs.canvas.height)
|
var resImgData = canvasTxt.value.getImageData(0, 0, canvas.value.width, canvas.value.height)
|
||||||
this.canvasTxt.globalCompositeOperation = 'destination-over'
|
canvasTxt.value.globalCompositeOperation = 'destination-over'
|
||||||
this.canvasTxt.fillStyle = this.myBg
|
canvasTxt.value.fillStyle = myBg.value
|
||||||
this.canvasTxt.fillRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height)
|
canvasTxt.value.fillRect(0, 0, canvas.value.width, canvas.value.height)
|
||||||
this.resultImg = this.$refs.canvas.toDataURL(imgFormat, imgQuality)
|
resultImg.value = canvas.value.toDataURL(imgFormat, imgQuality)
|
||||||
var resultImg = this.resultImg
|
var resultImgData = resultImg.value
|
||||||
this.canvasTxt.clearRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height)
|
canvasTxt.value.clearRect(0, 0, canvas.value.width, canvas.value.height)
|
||||||
this.canvasTxt.putImageData(resImgData, 0, 0)
|
canvasTxt.value.putImageData(resImgData, 0, 0)
|
||||||
this.canvasTxt.globalCompositeOperation = 'source-over'
|
canvasTxt.value.globalCompositeOperation = 'source-over'
|
||||||
if (this.isCrop) {
|
if (props.isCrop) {
|
||||||
const crop_area = this.getCropArea(resImgData.data)
|
const crop_area = getCropArea(resImgData.data)
|
||||||
var crop_canvas = document.createElement('canvas')
|
var crop_canvas = document.createElement('canvas')
|
||||||
const crop_ctx = crop_canvas.getContext('2d')
|
const crop_ctx = crop_canvas.getContext('2d', { willReadFrequently: true })
|
||||||
crop_canvas.width = crop_area[2] - crop_area[0]
|
crop_canvas.width = crop_area[2] - crop_area[0]
|
||||||
crop_canvas.height = crop_area[3] - crop_area[1]
|
crop_canvas.height = crop_area[3] - crop_area[1]
|
||||||
const crop_imgData = this.canvasTxt.getImageData(...crop_area)
|
const crop_imgData = canvasTxt.value.getImageData(...crop_area)
|
||||||
crop_ctx.globalCompositeOperation = 'destination-over'
|
crop_ctx.globalCompositeOperation = 'destination-over'
|
||||||
crop_ctx.putImageData(crop_imgData, 0, 0)
|
crop_ctx.putImageData(crop_imgData, 0, 0)
|
||||||
crop_ctx.fillStyle = this.myBg
|
crop_ctx.fillStyle = myBg.value
|
||||||
crop_ctx.fillRect(0, 0, crop_canvas.width, crop_canvas.height)
|
crop_ctx.fillRect(0, 0, crop_canvas.width, crop_canvas.height)
|
||||||
resultImg = crop_canvas.toDataURL(imgFormat, imgQuality)
|
resultImgData = crop_canvas.toDataURL(imgFormat, imgQuality)
|
||||||
crop_canvas = null
|
crop_canvas = null
|
||||||
}
|
}
|
||||||
resolve(resultImg)
|
resolve(resultImgData)
|
||||||
})
|
})
|
||||||
return pm
|
return pm
|
||||||
},
|
|
||||||
reset() {
|
|
||||||
this.canvasTxt.clearRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height)
|
|
||||||
if (this.isClearBgColor) {
|
|
||||||
this.$emit('update:bgColor', '')
|
|
||||||
this.$refs.canvas.style.background = 'rgba(255, 255, 255, 0)'
|
|
||||||
}
|
}
|
||||||
this.points = []
|
const reset = () => {
|
||||||
this.hasDrew = false
|
canvasTxt.value.clearRect(0, 0, canvas.value.width, canvas.value.height)
|
||||||
this.resultImg = ''
|
if (props.isClearBgColor) {
|
||||||
},
|
emit('update:bgColor', '')
|
||||||
getCropArea(imgData) {
|
canvas.value.style.background = 'rgba(255, 255, 255, 0)'
|
||||||
var topX = this.$refs.canvas.width
|
}
|
||||||
var btmX = 0
|
points.value = []
|
||||||
var topY = this.$refs.canvas.height
|
hasDrew.value = false
|
||||||
var btnY = 0
|
resultImg.value = ''
|
||||||
for (var i = 0; i < this.$refs.canvas.width; i++) {
|
}
|
||||||
for (var j = 0; j < this.$refs.canvas.height; j++) {
|
const getCropArea = (imgData) => {
|
||||||
var pos = (i + this.$refs.canvas.width * j) * 4
|
let topX = canvas.value.width
|
||||||
|
let btmX = 0
|
||||||
|
let topY = canvas.value.height
|
||||||
|
let btnY = 0
|
||||||
|
for (let i = 0; i < canvas.value.width; i++) {
|
||||||
|
for (let j = 0; j < canvas.value.height; j++) {
|
||||||
|
let pos = (i + canvas.value.width * j) * 4
|
||||||
if (imgData[pos] > 0 || imgData[pos + 1] > 0 || imgData[pos + 2] || imgData[pos + 3] > 0) {
|
if (imgData[pos] > 0 || imgData[pos + 1] > 0 || imgData[pos + 2] || imgData[pos + 3] > 0) {
|
||||||
btnY = Math.max(j, btnY)
|
btnY = Math.max(j, btnY)
|
||||||
btmX = Math.max(i, btmX)
|
btmX = Math.max(i, btmX)
|
||||||
|
@ -284,13 +279,14 @@
|
||||||
btmX++
|
btmX++
|
||||||
topY++
|
topY++
|
||||||
btnY++
|
btnY++
|
||||||
const data = [topX, topY, btmX, btnY]
|
return [topX, topY, btmX, btnY]
|
||||||
return data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// 向父组件暴露使用的方法
|
||||||
|
defineExpose({
|
||||||
|
generate,
|
||||||
|
reset
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
canvas {
|
canvas {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||||
*/
|
*/
|
||||||
import { defineAsyncComponent } from 'vue'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 图标选择器基础数据
|
* 图标选择器基础数据
|
||||||
* 推荐前往https://icones.js.org下载图标的Vue文件,然后放在src/assets/icons文件夹里面
|
* 推荐前往https://icones.js.org下载图标的Vue文件,然后放在src/assets/icons文件夹里面
|
||||||
|
|
|
@ -1,49 +1,53 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-show="$route.meta.type === 'iframe'" class="iframe-pages">
|
<div v-show="route.meta.type === 'iframe'" class="iframe-pages">
|
||||||
|
<div></div>
|
||||||
<iframe
|
<iframe
|
||||||
v-for="item in iframeList"
|
v-for="item in iframeList"
|
||||||
v-show="$route.meta.url === item.meta.url"
|
v-show="route.meta.url === item.meta.url"
|
||||||
:key="item.meta.url"
|
:key="item.meta.url"
|
||||||
:src="item.meta.url"
|
:src="item.meta.url"
|
||||||
frameborder="0"
|
frameborder="0"
|
||||||
></iframe>
|
></iframe>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup>
|
||||||
<script>
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { mapState, mapActions } from 'pinia'
|
|
||||||
import { iframeStore, globalStore } from '@/store'
|
import { iframeStore, globalStore } from '@/store'
|
||||||
|
const iStore = iframeStore()
|
||||||
|
const store = globalStore()
|
||||||
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
export default {
|
const iframeList = computed(() => {
|
||||||
data() {
|
return iStore.iframeList
|
||||||
return {}
|
})
|
||||||
},
|
|
||||||
computed: {
|
const isMobile = computed(() => {
|
||||||
...mapState(iframeStore, ['iframeList']),
|
return store.isMobile
|
||||||
...mapState(globalStore, ['isMobile', 'layoutTags'])
|
})
|
||||||
},
|
const layoutTags = computed(() => {
|
||||||
watch: {
|
return store.layoutTags
|
||||||
$route(e) {
|
})
|
||||||
this.push(e)
|
|
||||||
}
|
watch(route, () => {
|
||||||
},
|
push(router.currentRoute.value)
|
||||||
created() {
|
})
|
||||||
this.push(this.$route)
|
onBeforeMount(() => {
|
||||||
},
|
push(router.currentRoute.value)
|
||||||
mounted() {},
|
})
|
||||||
methods: {
|
|
||||||
...mapActions(iframeStore, ['setIframeList', 'pushIframeList', 'clearIframeList']),
|
const setIframeList = iStore.setIframeList
|
||||||
push(route) {
|
const pushIframeList = iStore.pushIframeList
|
||||||
|
const clearIframeList = iStore.clearIframeList
|
||||||
|
const push = (route) => {
|
||||||
if (route.meta.type === 'iframe') {
|
if (route.meta.type === 'iframe') {
|
||||||
if (this.isMobile || !this.layoutTags) {
|
if (isMobile || !layoutTags) {
|
||||||
this.setIframeList(route)
|
setIframeList(route)
|
||||||
} else {
|
} else {
|
||||||
this.pushIframeList(route)
|
pushIframeList(route)
|
||||||
}
|
|
||||||
} else if (this.isMobile || !this.layoutTags) {
|
|
||||||
this.clearIframeList()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else if (isMobile || !layoutTags) {
|
||||||
|
clearIframeList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="查收情况:" name="receiveInfoList">
|
<a-form-item label="查收情况:" name="receiveInfoList">
|
||||||
<s-table
|
<s-table
|
||||||
ref="table"
|
ref="tableRef"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="loadData"
|
:data="loadData"
|
||||||
:alert="false"
|
:alert="false"
|
||||||
|
@ -146,7 +146,7 @@
|
||||||
Object.assign(message, data)
|
Object.assign(message, data)
|
||||||
formData.value = message
|
formData.value = message
|
||||||
receiveInfoList.value = data.receiveInfoList
|
receiveInfoList.value = data.receiveInfoList
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
})
|
})
|
||||||
unreadMessageNum.value = Math.max(unreadMessageNum.value - 1, 0)
|
unreadMessageNum.value = Math.max(unreadMessageNum.value - 1, 0)
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
const receiveInfoList = ref([])
|
const receiveInfoList = ref([])
|
||||||
const formData = ref({})
|
const formData = ref({})
|
||||||
const table = ref()
|
const tableRef = ref()
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '姓名',
|
title: '姓名',
|
||||||
|
|
|
@ -97,6 +97,7 @@
|
||||||
moduleBackColor.value
|
moduleBackColor.value
|
||||||
? moduleMenu.classList.add('module-menu-color')
|
? moduleMenu.classList.add('module-menu-color')
|
||||||
: moduleMenu.classList.remove('module-menu-color')
|
: moduleMenu.classList.remove('module-menu-color')
|
||||||
|
// eslint-disable-next-line no-empty
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
setSelectedKeys()
|
setSelectedKeys()
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<a-divider />
|
<a-divider />
|
||||||
<a-form ref="form" class="text-right">
|
<a-form ref="formRef" class="text-right">
|
||||||
<a-form-item label="模块坞">
|
<a-form-item label="模块坞">
|
||||||
<a-switch :checked="moduleUnfoldOpen" @change="toggleState('moduleUnfoldOpen')" />
|
<a-switch :checked="moduleUnfoldOpen" @change="toggleState('moduleUnfoldOpen')" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
@ -86,14 +86,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup>
|
||||||
<script>
|
|
||||||
import { colorList } from '@/config/settingConfig'
|
import { colorList } from '@/config/settingConfig'
|
||||||
import { ThemeModeEnum } from '@/utils/enum'
|
import { ThemeModeEnum } from '@/utils/enum'
|
||||||
import { globalStore } from '@/store'
|
import { globalStore } from '@/store'
|
||||||
import { mapState, mapStores } from 'pinia'
|
|
||||||
import tool from '@/utils/tool'
|
import tool from '@/utils/tool'
|
||||||
|
const store = globalStore()
|
||||||
const toolDataNameMap = {
|
const toolDataNameMap = {
|
||||||
menuIsCollapse: 'MENU_COLLAPSE',
|
menuIsCollapse: 'MENU_COLLAPSE',
|
||||||
sideUniqueOpen: 'SIDE_UNIQUE_OPEN',
|
sideUniqueOpen: 'SIDE_UNIQUE_OPEN',
|
||||||
|
@ -103,10 +101,7 @@
|
||||||
topHeaderThemeColorSpread: 'TOP_HEADER_THEME_COLOR_SPREAD',
|
topHeaderThemeColorSpread: 'TOP_HEADER_THEME_COLOR_SPREAD',
|
||||||
moduleUnfoldOpen: 'MODULE_UNFOLD_OPEN'
|
moduleUnfoldOpen: 'MODULE_UNFOLD_OPEN'
|
||||||
}
|
}
|
||||||
export default defineComponent({
|
const sideStyleList = ref([
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
sideStyleList: [
|
|
||||||
{
|
{
|
||||||
tips: '暗色主题风格',
|
tips: '暗色主题风格',
|
||||||
value: ThemeModeEnum.DARK,
|
value: ThemeModeEnum.DARK,
|
||||||
|
@ -122,8 +117,9 @@
|
||||||
value: ThemeModeEnum.REAL_DARK,
|
value: ThemeModeEnum.REAL_DARK,
|
||||||
style: 'snowy-setting-checkbox-item-realdark'
|
style: 'snowy-setting-checkbox-item-realdark'
|
||||||
}
|
}
|
||||||
],
|
])
|
||||||
layoutList: [
|
|
||||||
|
const layoutList = ref([
|
||||||
{
|
{
|
||||||
tips: '经典',
|
tips: '经典',
|
||||||
value: 'classical',
|
value: 'classical',
|
||||||
|
@ -134,8 +130,9 @@
|
||||||
value: 'doublerow',
|
value: 'doublerow',
|
||||||
style: 'snowy-setting-layout-menu-doublerow'
|
style: 'snowy-setting-layout-menu-doublerow'
|
||||||
}
|
}
|
||||||
],
|
])
|
||||||
xnFormStyleOptions: [
|
|
||||||
|
const xnFormStyleOptions = ref([
|
||||||
{
|
{
|
||||||
label: '抽屉',
|
label: '抽屉',
|
||||||
value: 'drawer'
|
value: 'drawer'
|
||||||
|
@ -144,68 +141,81 @@
|
||||||
label: '对话框',
|
label: '对话框',
|
||||||
value: 'modal'
|
value: 'modal'
|
||||||
}
|
}
|
||||||
],
|
|
||||||
colorList
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapStores(globalStore),
|
|
||||||
...mapState(globalStore, [
|
|
||||||
'theme',
|
|
||||||
'themeColor',
|
|
||||||
'layout',
|
|
||||||
'menuIsCollapse',
|
|
||||||
'sideUniqueOpen',
|
|
||||||
'layoutTagsOpen',
|
|
||||||
'breadcrumbOpen',
|
|
||||||
'moduleUnfoldOpen',
|
|
||||||
'topHeaderThemeColorOpen',
|
|
||||||
'topHeaderThemeColorSpread',
|
|
||||||
'formStyle'
|
|
||||||
])
|
])
|
||||||
},
|
|
||||||
mounted() {},
|
const theme = computed(() => {
|
||||||
methods: {
|
return store.theme
|
||||||
changeTopHanderThemeColorOpen() {
|
})
|
||||||
this.toggleState('topHeaderThemeColorOpen')
|
const themeColor = computed(() => {
|
||||||
if (!this.topHeaderThemeColorOpen) {
|
return store.themeColor
|
||||||
this.globalStore.topHeaderThemeColorSpread = false
|
})
|
||||||
|
const layout = computed(() => {
|
||||||
|
return store.layout
|
||||||
|
})
|
||||||
|
const menuIsCollapse = computed(() => {
|
||||||
|
return store.menuIsCollapse
|
||||||
|
})
|
||||||
|
const sideUniqueOpen = computed(() => {
|
||||||
|
return store.sideUniqueOpen
|
||||||
|
})
|
||||||
|
const layoutTagsOpen = computed(() => {
|
||||||
|
return store.layoutTagsOpen
|
||||||
|
})
|
||||||
|
const breadcrumbOpen = computed(() => {
|
||||||
|
return store.breadcrumbOpen
|
||||||
|
})
|
||||||
|
const moduleUnfoldOpen = computed(() => {
|
||||||
|
return store.moduleUnfoldOpen
|
||||||
|
})
|
||||||
|
const topHeaderThemeColorOpen = computed(() => {
|
||||||
|
return store.topHeaderThemeColorOpen
|
||||||
|
})
|
||||||
|
const topHeaderThemeColorSpread = computed(() => {
|
||||||
|
return store.topHeaderThemeColorSpread
|
||||||
|
})
|
||||||
|
const formStyle = computed(() => {
|
||||||
|
return store.formStyle
|
||||||
|
})
|
||||||
|
|
||||||
|
const changeTopHanderThemeColorOpen = () => {
|
||||||
|
toggleState('topHeaderThemeColorOpen')
|
||||||
|
if (!topHeaderThemeColorOpen) {
|
||||||
|
store.topHeaderThemeColorSpread = false
|
||||||
tool.data.set('SNOWY_TOP_HEADER_THEME_COLOR_SPREAD', false)
|
tool.data.set('SNOWY_TOP_HEADER_THEME_COLOR_SPREAD', false)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
changeTopHanderThemeColorSpread() {
|
|
||||||
this.toggleState('topHeaderThemeColorSpread')
|
const changeTopHanderThemeColorSpread = () => {
|
||||||
},
|
toggleState('topHeaderThemeColorSpread')
|
||||||
toggleState(stateName) {
|
}
|
||||||
this.globalStore.toggleConfig(stateName)
|
const toggleState = (stateName) => {
|
||||||
|
store.toggleConfig(stateName)
|
||||||
const toolDataName = toolDataNameMap[stateName]
|
const toolDataName = toolDataNameMap[stateName]
|
||||||
tool.data.set(`SNOWY_${toolDataName}`, this.globalStore[stateName])
|
tool.data.set(`SNOWY_${toolDataName}`, store[stateName])
|
||||||
},
|
}
|
||||||
// 设置整体风格主题
|
// 设置整体风格主题
|
||||||
setSideStyle(value) {
|
const setSideStyle = (value) => {
|
||||||
this.globalStore.setTheme(value)
|
store.setTheme(value)
|
||||||
tool.data.set('SNOWY_THEME', value)
|
tool.data.set('SNOWY_THEME', value)
|
||||||
},
|
}
|
||||||
// 设置整体界面布局
|
// 设置整体界面布局
|
||||||
layoutStyle(value) {
|
const layoutStyle = (value) => {
|
||||||
this.globalStore.setLayout(value)
|
store.setLayout(value)
|
||||||
tool.data.set('SNOWY_LAYOUT', value)
|
tool.data.set('SNOWY_LAYOUT', value)
|
||||||
},
|
}
|
||||||
// 切换颜色
|
// 切换颜色
|
||||||
tagColor(value) {
|
const tagColor = (value) => {
|
||||||
tool.data.set('SNOWY_THEME_COLOR', value)
|
tool.data.set('SNOWY_THEME_COLOR', value)
|
||||||
this.globalStore.setThemeColor(value)
|
store.setThemeColor(value)
|
||||||
},
|
}
|
||||||
// 切换表单风格
|
// 切换表单风格
|
||||||
formStyleChange(value) {
|
const formStyleChange = (value) => {
|
||||||
tool.data.set('SNOWY_FORM_STYLE', value)
|
tool.data.set('SNOWY_FORM_STYLE', value)
|
||||||
this.globalStore.setFormStyle(value)
|
store.setFormStyle(value)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style type="less" scoped>
|
<style lang="less" scoped>
|
||||||
.snowy-setting-checkbox {
|
.snowy-setting-checkbox {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
|
|
@ -16,18 +16,15 @@
|
||||||
</a-menu>
|
</a-menu>
|
||||||
</a-drawer>
|
</a-drawer>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup>
|
||||||
<script>
|
|
||||||
import NavMenu from './NavMenu.vue'
|
import NavMenu from './NavMenu.vue'
|
||||||
import { globalStore } from '@/store'
|
import { globalStore } from '@/store'
|
||||||
import { mapState } from 'pinia'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
export default {
|
const router = useRouter()
|
||||||
components: {
|
const store = globalStore()
|
||||||
NavMenu
|
|
||||||
},
|
const vDrag = (el) => {
|
||||||
directives: {
|
|
||||||
drag(el) {
|
|
||||||
const oDiv = el // 当前元素
|
const oDiv = el // 当前元素
|
||||||
let firstTime = ''
|
let firstTime = ''
|
||||||
let lastTime = ''
|
let lastTime = ''
|
||||||
|
@ -65,39 +62,37 @@
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
data() {
|
const visible = ref(false)
|
||||||
return {
|
const menu = ref([])
|
||||||
visible: false,
|
|
||||||
menu: []
|
const sysBaseConfig = computed(() => {
|
||||||
}
|
return store.sysBaseConfig
|
||||||
},
|
})
|
||||||
computed: {
|
|
||||||
...mapState(globalStore, ['sysBaseConfig'])
|
onBeforeMount(() => {
|
||||||
},
|
const menus = router.getMenu()
|
||||||
created() {
|
menu.value = filterUrl(menus)
|
||||||
const menu = this.$router.getMenu()
|
})
|
||||||
this.menu = this.filterUrl(menu)
|
|
||||||
},
|
const showMobileNav = (e) => {
|
||||||
methods: {
|
|
||||||
showMobileNav(e) {
|
|
||||||
const isdrag = e.currentTarget.getAttribute('drag-flag')
|
const isdrag = e.currentTarget.getAttribute('drag-flag')
|
||||||
this.visible = true
|
visible.value = true
|
||||||
if (isdrag === 'true') {
|
if (isdrag === 'true') {
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
this.visible = true
|
visible.value = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
// 当菜单被选中时
|
// 当菜单被选中时
|
||||||
onSelect(obj) {
|
const onSelect = (obj) => {
|
||||||
const pathLength = obj.keyPath.length
|
const pathLength = obj.keyPath.length
|
||||||
const path = obj.keyPath[pathLength - 1]
|
const path = obj.keyPath[pathLength - 1]
|
||||||
this.$router.push({ path })
|
router.push({ path })
|
||||||
this.visible = false
|
visible.value = false
|
||||||
},
|
}
|
||||||
// 转换外部链接的路由
|
// 转换外部链接的路由
|
||||||
filterUrl(map) {
|
const filterUrl = (map) => {
|
||||||
map.forEach((item, index) => {
|
map.forEach((item, index) => {
|
||||||
item.meta = item.meta ? item.meta : {}
|
item.meta = item.meta ? item.meta : {}
|
||||||
// 处理隐藏
|
// 处理隐藏
|
||||||
|
@ -105,19 +100,16 @@
|
||||||
map.splice(index, 1)
|
map.splice(index, 1)
|
||||||
}
|
}
|
||||||
// 处理http
|
// 处理http
|
||||||
// eslint-disable-next-line eqeqeq
|
if (item.meta.type === 'iframe') {
|
||||||
if (item.meta.type == 'iframe') {
|
|
||||||
item.path = `/i/${item.name}`
|
item.path = `/i/${item.name}`
|
||||||
}
|
}
|
||||||
// 递归循环
|
// 递归循环
|
||||||
if (item.children && item.children.length > 0) {
|
if (item.children && item.children.length > 0) {
|
||||||
item.children = this.filterUrl(item.children)
|
item.children = filterUrl(item.children)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return map
|
return map
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -58,242 +58,245 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import tool from '@/utils/tool'
|
|
||||||
import XnContextMenu from '@/components/XnContextMenu/index.vue'
|
import XnContextMenu from '@/components/XnContextMenu/index.vue'
|
||||||
import { globalStore, iframeStore, keepAliveStore, viewTagsStore } from '@/store'
|
import { globalStore, iframeStore, keepAliveStore, viewTagsStore } from '@/store'
|
||||||
import { mapState, mapActions } from 'pinia'
|
|
||||||
import routerUtil from '@/utils/routerUtil'
|
import routerUtil from '@/utils/routerUtil'
|
||||||
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
import { watch } from 'vue'
|
||||||
|
|
||||||
export default {
|
const route = useRoute()
|
||||||
name: 'Tags',
|
const router = useRouter()
|
||||||
components: { XnContextMenu },
|
const store = globalStore()
|
||||||
props: {},
|
const kStore = keepAliveStore()
|
||||||
data() {
|
const iStore = iframeStore()
|
||||||
return {
|
const vStore = viewTagsStore()
|
||||||
// tagList: [],
|
|
||||||
activeKey: this.$route.fullPath,
|
const activeKey = ref()
|
||||||
maxTabs: 20,
|
const maxTabs = ref(20)
|
||||||
contextMenuTarget: null,
|
const contextMenuTarget = ref(null)
|
||||||
contextMenuVisible: false,
|
const contextMenuVisible = ref(false)
|
||||||
currentContextMenuTabIndex: 0
|
const currentContextMenuTabIndex = ref(0)
|
||||||
}
|
|
||||||
},
|
const viewTags = computed(() => {
|
||||||
computed: {
|
return vStore.viewTags
|
||||||
...mapState(viewTagsStore, ['viewTags']),
|
})
|
||||||
...mapState(globalStore, ['layoutTagsOpen']),
|
|
||||||
tagList() {
|
const layoutTagsOpen = computed(() => {
|
||||||
return this.viewTags
|
return store.layoutTagsOpen
|
||||||
}
|
})
|
||||||
},
|
|
||||||
watch: {
|
const tagList = computed(() => {
|
||||||
$route(to) {
|
return viewTags.value
|
||||||
this.addViewTags(to)
|
})
|
||||||
},
|
|
||||||
layoutTagsOpen() {
|
watch(route, (to) => {
|
||||||
this.closeOtherCacheTabs()
|
addViewTags(to)
|
||||||
}
|
activeKey.value = to.fullPath
|
||||||
},
|
})
|
||||||
created() {
|
watch(layoutTagsOpen, () => {
|
||||||
const module = this.$router.getMenu()
|
// closeOtherCacheTabs()
|
||||||
const indexMenu = routerUtil.getIndexMenu(module).path
|
})
|
||||||
// eslint-disable-next-line eqeqeq
|
|
||||||
const dashboardRoute = this.treeFind(module, (node) => node.path === indexMenu)
|
onMounted(() => {
|
||||||
if (dashboardRoute) {
|
|
||||||
dashboardRoute.fullPath = dashboardRoute.path
|
|
||||||
this.addViewTags(dashboardRoute)
|
|
||||||
this.addViewTags(this.$route)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
const tabNavList = document.querySelector('.ant-tabs-nav-list')
|
const tabNavList = document.querySelector('.ant-tabs-nav-list')
|
||||||
if (tabNavList) {
|
if (tabNavList) {
|
||||||
this.contextMenuTarget = tabNavList
|
contextMenuTarget.value = tabNavList
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
methods: {
|
// 增加tag
|
||||||
...mapActions(viewTagsStore, ['addViewTags', 'pushViewTags', 'removeViewTags']),
|
const addViewTags = (to) => {
|
||||||
...mapActions(iframeStore, ['addIframe', 'removeIframeList', 'refreshIframe']),
|
activeKey.value = to.fullPath
|
||||||
...mapActions(keepAliveStore, ['pushKeepLive', 'removeKeepLive', 'setRouteShow']),
|
if (to.name && !to.meta.fullpage) {
|
||||||
handleTabContextMenu(evt) {
|
vStore.pushViewTags(to)
|
||||||
evt.preventDefault()
|
kStore.pushKeepLive(to.name)
|
||||||
let target = evt.target
|
|
||||||
// 修复关闭时出现"使用了错误的类型或对象"的问题
|
|
||||||
while (!target.classList.contains('ant-tabs-tab')) {
|
|
||||||
if (target.classList.contains('ant-tabs')) {
|
|
||||||
this.currentContextMenuTabIndex = 0
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
target = target.parentNode
|
if (tagList.value.length - 1 > maxTabs.value) {
|
||||||
|
const firstTag = tagList.value[1]
|
||||||
|
vStore.removeViewTags(firstTag)
|
||||||
}
|
}
|
||||||
const tabList = document.querySelectorAll('.ant-tabs-nav-list .ant-tabs-tab')
|
|
||||||
this.currentContextMenuTabIndex = Array.from(tabList).findIndex((tab) => tab === target)
|
|
||||||
},
|
|
||||||
onTabClick(tab) {
|
|
||||||
this.$router.push(tab)
|
|
||||||
},
|
|
||||||
getCurrentTag() {
|
|
||||||
return this.tagList[this.currentContextMenuTabIndex]
|
|
||||||
},
|
|
||||||
onTabRemove(tabKey, action) {
|
|
||||||
if (action === 'remove') {
|
|
||||||
const tag = this.tagList.find((tag) => tag.fullPath === tabKey)
|
|
||||||
this.closeSelectedTag(tag)
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
// 处理鼠标放开事件
|
|
||||||
onTabUp(e) {
|
|
||||||
// 鼠标中键
|
|
||||||
if (e.which === 2) {
|
|
||||||
this.handleTabContextMenu(e)
|
|
||||||
this.closeTabs()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getTabWrapEl() {
|
|
||||||
return document.querySelector('.ant-tabs-nav-wrap')
|
|
||||||
},
|
|
||||||
scrollLeft() {
|
|
||||||
const wrapEl = this.getTabWrapEl()
|
|
||||||
if (wrapEl) {
|
|
||||||
const event = new WheelEvent('wheel', { deltaX: 0, deltaY: -100 })
|
|
||||||
wrapEl.dispatchEvent(event)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scrollRight() {
|
|
||||||
const wrapEl = this.getTabWrapEl()
|
|
||||||
if (wrapEl) {
|
|
||||||
const event = new WheelEvent('wheel', { deltaX: 0, deltaY: 100 })
|
|
||||||
wrapEl.dispatchEvent(event)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 查找树
|
// 查找树
|
||||||
treeFind(tree, func) {
|
const treeFind = (tree, func) => {
|
||||||
for (const data of tree) {
|
for (const data of tree) {
|
||||||
if (func(data)) return data
|
if (func(data)) return data
|
||||||
if (data.children) {
|
if (data.children) {
|
||||||
const res = this.treeFind(data.children, func)
|
const res = treeFind(data.children, func)
|
||||||
if (res) return res
|
if (res) return res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
},
|
|
||||||
// 增加tag
|
|
||||||
addViewTags(route) {
|
|
||||||
this.activeKey = route.fullPath
|
|
||||||
if (route.name && !route.meta.fullpage) {
|
|
||||||
this.pushViewTags(route)
|
|
||||||
this.pushKeepLive(route.name)
|
|
||||||
}
|
}
|
||||||
if (this.tagList.length - 1 > this.maxTabs) {
|
|
||||||
const firstTag = this.tagList[1]
|
const getCurrentTag = () => {
|
||||||
this.removeViewTags(firstTag)
|
return tagList.value[currentContextMenuTabIndex.value]
|
||||||
}
|
}
|
||||||
},
|
|
||||||
// 高亮tag
|
// 高亮tag
|
||||||
isActive(route) {
|
const isActive = (to) => {
|
||||||
return route.path === this.$route.path
|
return to.path === route.path
|
||||||
},
|
}
|
||||||
// 关闭tag
|
// 关闭tag
|
||||||
closeSelectedTag(tag, autoPushLatestView = true) {
|
const closeSelectedTag = (tag, autoPushLatestView = true) => {
|
||||||
this.removeViewTags(tag)
|
vStore.removeViewTags(tag)
|
||||||
this.removeIframeList(tag)
|
iStore.removeIframeList(tag)
|
||||||
this.removeKeepLive(tag.name)
|
kStore.removeKeepLive(tag.name)
|
||||||
if (autoPushLatestView && this.isActive(tag)) {
|
if (autoPushLatestView && isActive(tag)) {
|
||||||
const latestView = this.tagList.slice(-1)[0]
|
const latestView = tagList.value.slice(-1)[0]
|
||||||
if (latestView) {
|
if (latestView) {
|
||||||
this.$router.push(latestView)
|
router.push(latestView)
|
||||||
} else {
|
} else {
|
||||||
this.$router.push('/')
|
router.push('/')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
// TAB 刷新
|
// TAB 刷新
|
||||||
refreshTab() {
|
const refreshTab = () => {
|
||||||
this.contextMenuVisible = false
|
contextMenuVisible.value = false
|
||||||
const nowTag = this.getCurrentTag()
|
const nowTag = getCurrentTag()
|
||||||
// 判断是否当前路由,否的话跳转
|
// 判断是否当前路由,否的话跳转
|
||||||
// eslint-disable-next-line eqeqeq
|
// eslint-disable-next-line eqeqeq
|
||||||
if (this.$route.fullPath !== nowTag.fullPath) {
|
if (route.fullPath !== nowTag.fullPath) {
|
||||||
this.$router.push({
|
router.push({
|
||||||
path: nowTag.fullPath,
|
path: nowTag.fullPath,
|
||||||
query: nowTag.query
|
query: nowTag.query
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.refreshIframe(nowTag)
|
iStore.refreshIframe(nowTag)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.removeKeepLive(nowTag.name)
|
kStore.removeKeepLive(nowTag.name)
|
||||||
this.setRouteShow(false)
|
kStore.setRouteShow(false)
|
||||||
this.$nextTick(() => {
|
nextTick(() => {
|
||||||
this.pushKeepLive(nowTag.name)
|
kStore.pushKeepLive(nowTag.name)
|
||||||
this.setRouteShow(true)
|
kStore.setRouteShow(true)
|
||||||
})
|
})
|
||||||
}, 0)
|
}, 0)
|
||||||
},
|
|
||||||
// TAB 关闭
|
|
||||||
closeTabs() {
|
|
||||||
this.contextMenuVisible = false
|
|
||||||
const nowTag = this.getCurrentTag()
|
|
||||||
if (!nowTag.meta.affix) {
|
|
||||||
this.closeSelectedTag(nowTag)
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
// TAB 关闭
|
||||||
|
const closeTabs = () => {
|
||||||
|
contextMenuVisible.value = false
|
||||||
|
const nowTag = getCurrentTag()
|
||||||
|
if (!nowTag.meta.affix) {
|
||||||
|
closeSelectedTag(nowTag)
|
||||||
|
}
|
||||||
|
}
|
||||||
// TAB 关闭其他
|
// TAB 关闭其他
|
||||||
closeOtherTabs() {
|
const closeOtherTabs = () => {
|
||||||
this.contextMenuVisible = false
|
contextMenuVisible.value = false
|
||||||
const nowTag = this.getCurrentTag()
|
const nowTag = getCurrentTag()
|
||||||
// 判断是否当前路由,否的话跳转
|
// 判断是否当前路由,否的话跳转
|
||||||
// eslint-disable-next-line eqeqeq
|
// eslint-disable-next-line eqeqeq
|
||||||
if (this.$route.fullPath !== nowTag.fullPath) {
|
if (route.fullPath !== nowTag.fullPath) {
|
||||||
this.$router.push({
|
router.push({
|
||||||
path: nowTag.fullPath,
|
path: nowTag.fullPath,
|
||||||
query: nowTag.query
|
query: nowTag.query
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const tags = [...this.tagList]
|
const tags = [...tagList.value]
|
||||||
tags.forEach((tag) => {
|
tags.forEach((tag) => {
|
||||||
// eslint-disable-next-line eqeqeq
|
// eslint-disable-next-line eqeqeq
|
||||||
if ((tag.meta && tag.meta.affix) || nowTag.fullPath === tag.fullPath) {
|
if ((tag.meta && tag.meta.affix) || nowTag.fullPath === tag.fullPath) {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
this.closeSelectedTag(tag, false)
|
closeSelectedTag(tag, false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
|
|
||||||
// 多标签功能关闭时关闭被缓存的标签
|
// 多标签功能关闭时关闭被缓存的标签
|
||||||
closeOtherCacheTabs() {
|
const closeOtherCacheTabs = () => {
|
||||||
const tags = [...this.tagList]
|
const tags = [...tagList]
|
||||||
tags.forEach((tag) => {
|
tags.forEach((tag) => {
|
||||||
this.closeSelectedTag(tag, false)
|
closeSelectedTag(tag, false)
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
// TAB 最大化(包括标签栏)
|
// TAB 最大化(包括标签栏)
|
||||||
maximize() {
|
const maximize = () => {
|
||||||
this.contextMenuVisible = false
|
contextMenuVisible.value = false
|
||||||
const nowTag = this.getCurrentTag()
|
const nowTag = getCurrentTag()
|
||||||
// 判断是否当前路由,否的话跳转
|
// 判断是否当前路由,否的话跳转
|
||||||
// eslint-disable-next-line eqeqeq
|
// eslint-disable-next-line eqeqeq
|
||||||
if (this.$route.fullPath !== nowTag.fullPath) {
|
if (route.fullPath !== nowTag.fullPath) {
|
||||||
this.$router.push({
|
router.push({
|
||||||
path: nowTag.fullPath,
|
path: nowTag.fullPath,
|
||||||
query: nowTag.query
|
query: nowTag.query
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
document.getElementById('app').classList.add('main-maximize')
|
document.getElementById('app').classList.add('main-maximize')
|
||||||
},
|
}
|
||||||
// 新窗口打开
|
// 新窗口打开
|
||||||
openWindow() {
|
const openWindow = () => {
|
||||||
this.contextMenuVisible = false
|
contextMenuVisible.value = false
|
||||||
const nowTag = this.getCurrentTag()
|
const nowTag = getCurrentTag()
|
||||||
const url = nowTag.href || '/'
|
const url = nowTag.path || '/'
|
||||||
if (!nowTag.meta.affix) {
|
if (!nowTag.meta.affix) {
|
||||||
this.closeSelectedTag(nowTag)
|
closeSelectedTag(nowTag)
|
||||||
}
|
}
|
||||||
window.open(url)
|
window.open(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleTabContextMenu = (evt) => {
|
||||||
|
evt.preventDefault()
|
||||||
|
let target = evt.target
|
||||||
|
// 修复关闭时出现"使用了错误的类型或对象"的问题
|
||||||
|
while (!target.classList.contains('ant-tabs-tab')) {
|
||||||
|
if (target.classList.contains('ant-tabs')) {
|
||||||
|
currentContextMenuTabIndex.value = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
target = target.parentNode
|
||||||
|
}
|
||||||
|
const tabList = document.querySelectorAll('.ant-tabs-nav-list .ant-tabs-tab')
|
||||||
|
currentContextMenuTabIndex.value = Array.from(tabList).findIndex((tab) => tab === target)
|
||||||
|
}
|
||||||
|
|
||||||
|
const module = router.getMenu()
|
||||||
|
const indexMenu = routerUtil.getIndexMenu(module).path
|
||||||
|
// eslint-disable-next-line eqeqeq
|
||||||
|
const dashboardRoute = treeFind(module, (node) => node.path === indexMenu)
|
||||||
|
if (dashboardRoute) {
|
||||||
|
dashboardRoute.fullPath = dashboardRoute.path
|
||||||
|
addViewTags(dashboardRoute)
|
||||||
|
addViewTags(route)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onTabRemove = (tabKey, action) => {
|
||||||
|
if (action === 'remove') {
|
||||||
|
const tag = tagList.value.find((tag) => tag.fullPath === tabKey)
|
||||||
|
closeSelectedTag(tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const onTabClick = (tab) => {
|
||||||
|
router.push(tab)
|
||||||
|
}
|
||||||
|
// 处理鼠标放开事件
|
||||||
|
const onTabUp = (e) => {
|
||||||
|
// 鼠标中键
|
||||||
|
if (e.which === 2) {
|
||||||
|
handleTabContextMenu(e)
|
||||||
|
closeTabs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const getTabWrapEl = () => {
|
||||||
|
return document.querySelector('.ant-tabs-nav-wrap')
|
||||||
|
}
|
||||||
|
const scrollLeft = () => {
|
||||||
|
const wrapEl = getTabWrapEl()
|
||||||
|
if (wrapEl) {
|
||||||
|
const event = new WheelEvent('wheel', { deltaX: 0, deltaY: -100 })
|
||||||
|
wrapEl.dispatchEvent(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const scrollRight = () => {
|
||||||
|
const wrapEl = getTabWrapEl()
|
||||||
|
if (wrapEl) {
|
||||||
|
const event = new WheelEvent('wheel', { deltaX: 0, deltaY: 100 })
|
||||||
|
wrapEl.dispatchEvent(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.snowy-admin-tabs {
|
.snowy-admin-tabs {
|
||||||
&.ant-tabs {
|
&.ant-tabs {
|
||||||
|
@ -316,7 +319,9 @@
|
||||||
background: none;
|
background: none;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
transition: background-color 0.3s, color 0.3s;
|
transition:
|
||||||
|
background-color 0.3s,
|
||||||
|
color 0.3s;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
|
@ -15,27 +15,22 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { watch } from 'vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
<script>
|
const route = useRoute()
|
||||||
export default {
|
const breadList = ref([])
|
||||||
data() {
|
|
||||||
return {
|
watch(route, () => {
|
||||||
breadList: []
|
getBreadcrumb()
|
||||||
}
|
})
|
||||||
},
|
|
||||||
watch: {
|
onBeforeMount(() => {
|
||||||
$route() {
|
getBreadcrumb()
|
||||||
this.getBreadcrumb()
|
})
|
||||||
}
|
|
||||||
},
|
const getBreadcrumb = () => {
|
||||||
created() {
|
breadList.value = route.meta.breadcrumb
|
||||||
this.getBreadcrumb()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getBreadcrumb() {
|
|
||||||
const matched = this.$route.meta.breadcrumb
|
|
||||||
this.breadList = matched
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -53,9 +53,9 @@
|
||||||
<Tags v-if="!isMobile && layoutTagsOpen" />
|
<Tags v-if="!isMobile && layoutTagsOpen" />
|
||||||
<a-layout-content class="main-content-wrapper">
|
<a-layout-content class="main-content-wrapper">
|
||||||
<div id="admin-ui-main" class="admin-ui-main">
|
<div id="admin-ui-main" class="admin-ui-main">
|
||||||
<router-view v-slot="{ Component }" :key="route.fullPath">
|
<router-view v-slot="{ Component }">
|
||||||
<keep-alive :include="keepLiveRoute">
|
<keep-alive :include="kStore.keepLiveRoute">
|
||||||
<component :is="Component" :key="route.name" v-if="routeShow" />
|
<component :is="Component" v-if="kStore.routeShow" :key="route.name" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</router-view>
|
</router-view>
|
||||||
<iframe-view />
|
<iframe-view />
|
||||||
|
@ -149,12 +149,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 多标签 -->
|
<!-- 多标签 -->
|
||||||
<Tags v-if="!isMobile && layoutTagsOpen"></Tags>
|
<Tags v-if="!isMobile && layoutTagsOpen" />
|
||||||
<a-layout-content class="main-content-wrapper">
|
<a-layout-content class="main-content-wrapper">
|
||||||
<div id="admin-ui-main" class="admin-ui-main">
|
<div id="admin-ui-main" class="admin-ui-main">
|
||||||
<router-view v-slot="{ Component }" :key="route.fullPath">
|
<router-view v-slot="{ Component }">
|
||||||
<keep-alive :include="keepLiveRoute">
|
<keep-alive :include="kStore.keepLiveRoute">
|
||||||
<component :is="Component" v-if="routeShow" :key="route.name" />
|
<component :is="Component" v-if="kStore.routeShow" :key="route.name" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</router-view>
|
</router-view>
|
||||||
<iframe-view />
|
<iframe-view />
|
||||||
|
@ -215,6 +215,10 @@
|
||||||
return store.theme
|
return store.theme
|
||||||
})
|
})
|
||||||
const layoutTagsOpen = computed(() => {
|
const layoutTagsOpen = computed(() => {
|
||||||
|
// 当关闭多标签时,清理keepAlive的缓存
|
||||||
|
if (!store.layoutTagsOpen) {
|
||||||
|
kStore.keepLiveRoute = []
|
||||||
|
}
|
||||||
return store.layoutTagsOpen
|
return store.layoutTagsOpen
|
||||||
})
|
})
|
||||||
const breadcrumbOpen = computed(() => {
|
const breadcrumbOpen = computed(() => {
|
||||||
|
@ -235,12 +239,6 @@
|
||||||
const module = computed(() => {
|
const module = computed(() => {
|
||||||
return store.module
|
return store.module
|
||||||
})
|
})
|
||||||
const keepLiveRoute = computed(() => {
|
|
||||||
return kStore.keepLiveRoute
|
|
||||||
})
|
|
||||||
const routeShow = computed(() => {
|
|
||||||
return kStore.routeShow
|
|
||||||
})
|
|
||||||
const sideTheme = computed(() => {
|
const sideTheme = computed(() => {
|
||||||
return theme.value === ThemeModeEnum.REAL_DARK ? ThemeModeEnum.DARK : theme.value
|
return theme.value === ThemeModeEnum.REAL_DARK ? ThemeModeEnum.DARK : theme.value
|
||||||
})
|
})
|
||||||
|
@ -355,6 +353,7 @@
|
||||||
topHeaderThemeColorSpread.value
|
topHeaderThemeColorSpread.value
|
||||||
? headerLogin.classList.add('snowy-header-logo-primary-color')
|
? headerLogin.classList.add('snowy-header-logo-primary-color')
|
||||||
: headerLogin.classList.remove('snowy-header-logo-primary-color')
|
: headerLogin.classList.remove('snowy-header-logo-primary-color')
|
||||||
|
// eslint-disable-next-line no-empty
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
// 如果是双排菜单,吧第二排的也给渲染了
|
// 如果是双排菜单,吧第二排的也给渲染了
|
||||||
if (layout.value === 'doublerow') {
|
if (layout.value === 'doublerow') {
|
||||||
|
@ -363,6 +362,7 @@
|
||||||
topHeaderThemeColorSpread.value
|
topHeaderThemeColorSpread.value
|
||||||
? snowyDoublerowSideTop.classList.add('snowy-doublerow-side-top-primary-color')
|
? snowyDoublerowSideTop.classList.add('snowy-doublerow-side-top-primary-color')
|
||||||
: snowyDoublerowSideTop.classList.remove('snowy-doublerow-side-top-primary-color')
|
: snowyDoublerowSideTop.classList.remove('snowy-doublerow-side-top-primary-color')
|
||||||
|
// eslint-disable-next-line no-empty
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
<template>
|
<template>
|
||||||
<a-result status="403" title="403" sub-title="对不起,您没有访问此页面的权限。"> </a-result>
|
<a-result status="403" title="403" sub-title="对不起,您没有访问此页面的权限。" />
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -6,16 +6,13 @@
|
||||||
</template>
|
</template>
|
||||||
</a-result>
|
</a-result>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup>
|
||||||
<script>
|
import { useRouter } from 'vue-router'
|
||||||
export default {
|
const router = useRouter()
|
||||||
methods: {
|
const gohome = () => {
|
||||||
gohome() {
|
|
||||||
location.href = '/'
|
location.href = '/'
|
||||||
},
|
|
||||||
goback() {
|
|
||||||
this.$router.go(-1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
const goback = () => {
|
||||||
|
router.go(-1)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -20,7 +20,7 @@ export default {
|
||||||
searchKey: 'Search Key',
|
searchKey: 'Search Key',
|
||||||
imports: 'Import',
|
imports: 'Import',
|
||||||
more: 'More',
|
more: 'More',
|
||||||
export: 'Export',
|
export: 'Export'
|
||||||
},
|
},
|
||||||
model: {
|
model: {
|
||||||
user: 'user',
|
user: 'user',
|
||||||
|
|
|
@ -22,7 +22,7 @@ export default {
|
||||||
searchKey: '关键词',
|
searchKey: '关键词',
|
||||||
imports: '导入',
|
imports: '导入',
|
||||||
more: '更多',
|
more: '更多',
|
||||||
export: '导出',
|
export: '导出'
|
||||||
},
|
},
|
||||||
model: {
|
model: {
|
||||||
user: '用户',
|
user: '用户',
|
||||||
|
|
|
@ -109,7 +109,7 @@ router.beforeEach(async (to, from, next) => {
|
||||||
apiMenu[0] = cloneDeep(userRoutes.module[0])
|
apiMenu[0] = cloneDeep(userRoutes.module[0])
|
||||||
}
|
}
|
||||||
const childrenApiMenu = apiMenu[0].children
|
const childrenApiMenu = apiMenu[0].children
|
||||||
apiMenu[0].children = [...childrenApiMenu ? childrenApiMenu : [], ...userRoutes.menu]
|
apiMenu[0].children = [...(childrenApiMenu ? childrenApiMenu : []), ...userRoutes.menu]
|
||||||
let menuRouter = filterAsyncRouter(apiMenu)
|
let menuRouter = filterAsyncRouter(apiMenu)
|
||||||
menuRouter = flatAsyncRoutes(menuRouter)
|
menuRouter = flatAsyncRoutes(menuRouter)
|
||||||
menuRouter.forEach((item) => {
|
menuRouter.forEach((item) => {
|
||||||
|
@ -148,7 +148,7 @@ router.getMenu = () => {
|
||||||
apiMenu[0] = cloneDeep(userRoutes.module[0])
|
apiMenu[0] = cloneDeep(userRoutes.module[0])
|
||||||
}
|
}
|
||||||
const childrenApiMenu = apiMenu[0].children
|
const childrenApiMenu = apiMenu[0].children
|
||||||
apiMenu[0].children = [...childrenApiMenu ? childrenApiMenu : [], ...userRoutes.menu]
|
apiMenu[0].children = [...(childrenApiMenu ? childrenApiMenu : []), ...userRoutes.menu]
|
||||||
return filterUrl(apiMenu)
|
return filterUrl(apiMenu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,77 +30,132 @@ const getCacheConfig = (value) => {
|
||||||
/**
|
/**
|
||||||
* deprecated 请使用 useGlobalStore
|
* deprecated 请使用 useGlobalStore
|
||||||
*/
|
*/
|
||||||
export const globalStore = defineStore({
|
export const globalStore = defineStore('global', () => {
|
||||||
id: 'global',
|
// 利用Vue3组合式API,ref()定义state的属性
|
||||||
state: () => ({
|
// function() 定义actions
|
||||||
|
// computed 定义getters
|
||||||
|
|
||||||
|
// 定义state
|
||||||
// 移动端布局
|
// 移动端布局
|
||||||
isMobile: false,
|
const isMobile = ref(false)
|
||||||
// 布局
|
// 布局
|
||||||
layout: getCacheConfig('SNOWY_LAYOUT'),
|
const layout = ref(getCacheConfig('SNOWY_LAYOUT'))
|
||||||
|
|
||||||
// 菜单是否折叠 toggle
|
// 菜单是否折叠 toggle
|
||||||
menuIsCollapse: getCacheConfig('SNOWY_MENU_COLLAPSE'),
|
const menuIsCollapse = ref(getCacheConfig('SNOWY_MENU_COLLAPSE'))
|
||||||
// 侧边菜单是否排他展开
|
// 侧边菜单是否排他展开
|
||||||
sideUniqueOpen: getCacheConfig('SNOWY_SIDE_UNIQUE_OPEN'),
|
const sideUniqueOpen = ref(getCacheConfig('SNOWY_SIDE_UNIQUE_OPEN'))
|
||||||
// 多标签栏
|
// 多标签栏
|
||||||
layoutTagsOpen: getCacheConfig('SNOWY_LAYOUT_TAGS_OPEN'),
|
const layoutTagsOpen = ref(getCacheConfig('SNOWY_LAYOUT_TAGS_OPEN'))
|
||||||
// 是否展示面包屑
|
// 是否展示面包屑
|
||||||
breadcrumbOpen: getCacheConfig('SNOWY_BREADCRUMD_OPEN'),
|
const breadcrumbOpen = ref(getCacheConfig('SNOWY_BREADCRUMD_OPEN'))
|
||||||
// 顶栏是否应用主题色
|
// 顶栏是否应用主题色
|
||||||
topHeaderThemeColorOpen: getCacheConfig('SNOWY_TOP_HEADER_THEME_COLOR_OPEN'),
|
const topHeaderThemeColorOpen = ref(getCacheConfig('SNOWY_TOP_HEADER_THEME_COLOR_OPEN'))
|
||||||
// 顶栏主题色通栏
|
// 顶栏主题色通栏
|
||||||
topHeaderThemeColorSpread: getCacheConfig('SNOWY_TOP_HEADER_THEME_COLOR_SPREAD'),
|
const topHeaderThemeColorSpread = ref(getCacheConfig('SNOWY_TOP_HEADER_THEME_COLOR_SPREAD'))
|
||||||
// 模块坞
|
// 模块坞
|
||||||
moduleUnfoldOpen: getCacheConfig('SNOWY_MODULE_UNFOLD_OPEN'),
|
const moduleUnfoldOpen = ref(getCacheConfig('SNOWY_MODULE_UNFOLD_OPEN'))
|
||||||
|
|
||||||
// 主题
|
// 主题
|
||||||
theme: getCacheConfig('SNOWY_THEME'),
|
const theme = ref(getCacheConfig('SNOWY_THEME'))
|
||||||
// 主题颜色
|
// 主题颜色
|
||||||
themeColor: toolDataGet('SNOWY_THEME_COLOR') || config.COLOR,
|
const themeColor = ref(toolDataGet('SNOWY_THEME_COLOR') || config.COLOR)
|
||||||
// 整体表单风格
|
// 整体表单风格
|
||||||
formStyle: getCacheConfig('SNOWY_FORM_STYLE'),
|
const formStyle = ref(getCacheConfig('SNOWY_FORM_STYLE'))
|
||||||
// 用户信息
|
// 用户信息
|
||||||
userInfo: toolDataGet('USER_INFO') || {},
|
const userInfo = ref(toolDataGet('USER_INFO') || {})
|
||||||
// 系统配置
|
// 系统配置
|
||||||
sysBaseConfig: toolDataGet('SNOWY_SYS_BASE_CONFIG') || config.SYS_BASE_CONFIG,
|
const sysBaseConfig = ref(toolDataGet('SNOWY_SYS_BASE_CONFIG') || config.SYS_BASE_CONFIG)
|
||||||
// 默认应用
|
// 默认应用
|
||||||
module: getCacheConfig('SNOWY_MENU_MODULE_ID')
|
const module = ref(getCacheConfig('SNOWY_MENU_MODULE_ID'))
|
||||||
}),
|
|
||||||
getters: {},
|
// 定义action
|
||||||
actions: {
|
const setIsMobile = (key) => {
|
||||||
setIsMobile(key) {
|
isMobile.value = key
|
||||||
this.isMobile = key
|
|
||||||
},
|
|
||||||
setLayout(key) {
|
|
||||||
this.layout = key
|
|
||||||
},
|
|
||||||
setTheme(key) {
|
|
||||||
this.theme = key
|
|
||||||
const closeMessage = message.loading(`加载中...`)
|
|
||||||
changeColor(this.themeColor, key).then(closeMessage)
|
|
||||||
},
|
|
||||||
setThemeColor(key) {
|
|
||||||
this.themeColor = key
|
|
||||||
const closeMessage = message.loading(`加载中...`)
|
|
||||||
changeColor(key, this.theme).then(closeMessage)
|
|
||||||
},
|
|
||||||
initTheme() {
|
|
||||||
const closeMessage = message.loading(`加载中...`)
|
|
||||||
changeColor(this.themeColor, this.theme).then(closeMessage)
|
|
||||||
},
|
|
||||||
toggleConfig(key) {
|
|
||||||
this[key] = !this[key]
|
|
||||||
},
|
|
||||||
setFormStyle(key) {
|
|
||||||
this.formStyle = key
|
|
||||||
},
|
|
||||||
setUserInfo(key) {
|
|
||||||
this.userInfo = key
|
|
||||||
},
|
|
||||||
setSysBaseConfig(key) {
|
|
||||||
this.sysBaseConfig = key
|
|
||||||
},
|
|
||||||
setModule(key) {
|
|
||||||
this.module = key
|
|
||||||
}
|
}
|
||||||
|
const setLayout = (key) => {
|
||||||
|
layout.value = key
|
||||||
|
}
|
||||||
|
const setTheme = (key) => {
|
||||||
|
theme.value = key
|
||||||
|
const closeMessage = message.loading(`加载中...`)
|
||||||
|
changeColor(themeColor.value, key).then(closeMessage)
|
||||||
|
}
|
||||||
|
const setThemeColor = (key) => {
|
||||||
|
themeColor.value = key
|
||||||
|
const closeMessage = message.loading(`加载中...`)
|
||||||
|
changeColor(key, theme.value).then(closeMessage)
|
||||||
|
}
|
||||||
|
const initTheme = () => {
|
||||||
|
const closeMessage = message.loading(`加载中...`)
|
||||||
|
changeColor(themeColor.value, theme.value).then(closeMessage)
|
||||||
|
}
|
||||||
|
const toggleConfig = (key) => {
|
||||||
|
switch (key) {
|
||||||
|
case 'menuIsCollapse':
|
||||||
|
menuIsCollapse.value = !menuIsCollapse.value
|
||||||
|
break
|
||||||
|
case 'topHeaderThemeColorSpread':
|
||||||
|
topHeaderThemeColorSpread.value = !topHeaderThemeColorSpread.value
|
||||||
|
break
|
||||||
|
case 'sideUniqueOpen':
|
||||||
|
sideUniqueOpen.value = !sideUniqueOpen.value
|
||||||
|
break
|
||||||
|
case 'layoutTagsOpen':
|
||||||
|
layoutTagsOpen.value = !layoutTagsOpen.value
|
||||||
|
break
|
||||||
|
case 'breadcrumbOpen':
|
||||||
|
breadcrumbOpen.value = !breadcrumbOpen.value
|
||||||
|
break
|
||||||
|
case 'topHeaderThemeColorOpen':
|
||||||
|
topHeaderThemeColorOpen.value = !topHeaderThemeColorOpen.value
|
||||||
|
topHeaderThemeColorSpread.value = topHeaderThemeColorOpen.value
|
||||||
|
? topHeaderThemeColorSpread.value
|
||||||
|
: topHeaderThemeColorOpen.value
|
||||||
|
break
|
||||||
|
case 'moduleUnfoldOpen':
|
||||||
|
moduleUnfoldOpen.value = !moduleUnfoldOpen.value
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const setFormStyle = (key) => {
|
||||||
|
formStyle.value = key
|
||||||
|
}
|
||||||
|
const setUserInfo = (key) => {
|
||||||
|
userInfo.value = key
|
||||||
|
}
|
||||||
|
const setSysBaseConfig = (key) => {
|
||||||
|
sysBaseConfig.value = key
|
||||||
|
}
|
||||||
|
const setModule = (key) => {
|
||||||
|
module.value = key
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
isMobile,
|
||||||
|
layout,
|
||||||
|
menuIsCollapse,
|
||||||
|
sideUniqueOpen,
|
||||||
|
layoutTagsOpen,
|
||||||
|
breadcrumbOpen,
|
||||||
|
topHeaderThemeColorOpen,
|
||||||
|
topHeaderThemeColorSpread,
|
||||||
|
moduleUnfoldOpen,
|
||||||
|
theme,
|
||||||
|
themeColor,
|
||||||
|
formStyle,
|
||||||
|
userInfo,
|
||||||
|
sysBaseConfig,
|
||||||
|
module,
|
||||||
|
setIsMobile,
|
||||||
|
setLayout,
|
||||||
|
setTheme,
|
||||||
|
setThemeColor,
|
||||||
|
initTheme,
|
||||||
|
toggleConfig,
|
||||||
|
setFormStyle,
|
||||||
|
setUserInfo,
|
||||||
|
setSysBaseConfig,
|
||||||
|
setModule
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -10,32 +10,30 @@
|
||||||
*/
|
*/
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
export const iframeStore = defineStore({
|
export const iframeStore = defineStore('iframe', () => {
|
||||||
id: 'iframe',
|
// 定义state
|
||||||
state: () => ({
|
const iframeList = ref([])
|
||||||
iframeList: []
|
const setIframeList = (route) => {
|
||||||
}),
|
iframeList.value = []
|
||||||
getters: {},
|
iframeList.value.push(route)
|
||||||
actions: {
|
|
||||||
setIframeList(route) {
|
|
||||||
this.iframeList = []
|
|
||||||
this.iframeList.push(route)
|
|
||||||
},
|
|
||||||
pushIframeList(route) {
|
|
||||||
const target = this.iframeList.find((item) => item.path === route.path)
|
|
||||||
if (!target) {
|
|
||||||
this.iframeList.push(route)
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
removeIframeList(route) {
|
// 定义action
|
||||||
this.iframeList.forEach((item, index) => {
|
const pushIframeList = (route) => {
|
||||||
|
const target = iframeList.value.find((item) => item.path === route.path)
|
||||||
|
if (!target) {
|
||||||
|
iframeList.value.push(route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const removeIframeList = (route) => {
|
||||||
|
iframeList.value.forEach((item, index) => {
|
||||||
if (item.path === route.path) {
|
if (item.path === route.path) {
|
||||||
this.iframeList.splice(index, 1)
|
iframeList.value.splice(index, 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
refreshIframe(route) {
|
const refreshIframe = (route) => {
|
||||||
this.iframeList.forEach((item) => {
|
iframeList.value.forEach((item) => {
|
||||||
if (item.path === route.path) {
|
if (item.path === route.path) {
|
||||||
const url = route.meta.url
|
const url = route.meta.url
|
||||||
item.meta.url = ''
|
item.meta.url = ''
|
||||||
|
@ -44,9 +42,17 @@ export const iframeStore = defineStore({
|
||||||
}, 200)
|
}, 200)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
|
||||||
clearIframeList() {
|
|
||||||
this.iframeList = []
|
|
||||||
}
|
}
|
||||||
|
const clearIframeList = () => {
|
||||||
|
iframeList.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
iframeList,
|
||||||
|
setIframeList,
|
||||||
|
pushIframeList,
|
||||||
|
removeIframeList,
|
||||||
|
refreshIframe,
|
||||||
|
clearIframeList
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,37 +10,46 @@
|
||||||
*/
|
*/
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
export const keepAliveStore = defineStore({
|
export const keepAliveStore = defineStore('keepAlive', () => {
|
||||||
id: 'keepAlive',
|
// 定义state
|
||||||
state: () => ({
|
const keepLiveRoute = ref([])
|
||||||
keepLiveRoute: [],
|
const routeKey = ref(null)
|
||||||
routeKey: null,
|
const routeShow = ref(true)
|
||||||
routeShow: true
|
|
||||||
}),
|
// 定义action
|
||||||
getters: {},
|
const pushKeepLive = (component) => {
|
||||||
actions: {
|
if (!keepLiveRoute.value.includes(component)) {
|
||||||
pushKeepLive(component) {
|
keepLiveRoute.value.push(component)
|
||||||
if (!this.keepLiveRoute.includes(component)) {
|
|
||||||
this.keepLiveRoute.push(component)
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
removeKeepLive(component) {
|
const removeKeepLive = (component) => {
|
||||||
const index = this.keepLiveRoute.indexOf(component)
|
const index = keepLiveRoute.value.indexOf(component)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
this.keepLiveRoute.splice(index, 1)
|
keepLiveRoute.value.splice(index, 1)
|
||||||
}
|
}
|
||||||
},
|
|
||||||
clearKeepLive() {
|
|
||||||
this.keepLiveRoute = []
|
|
||||||
},
|
|
||||||
setRouteKey(key) {
|
|
||||||
this.routeKey = key
|
|
||||||
},
|
|
||||||
setRouteShow(key) {
|
|
||||||
this.routeShow = key
|
|
||||||
},
|
|
||||||
setRouteKeyAction(key) {
|
|
||||||
this.setRouteKey(key)
|
|
||||||
}
|
}
|
||||||
|
const clearKeepLive = () => {
|
||||||
|
keepLiveRoute.value = []
|
||||||
|
}
|
||||||
|
const setRouteKey = (key) => {
|
||||||
|
routeKey.value = key
|
||||||
|
}
|
||||||
|
const setRouteShow = (key) => {
|
||||||
|
routeShow.value = key
|
||||||
|
}
|
||||||
|
const setRouteKeyAction = (key) => {
|
||||||
|
setRouteKey(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
keepLiveRoute,
|
||||||
|
routeKey,
|
||||||
|
routeShow,
|
||||||
|
pushKeepLive,
|
||||||
|
removeKeepLive,
|
||||||
|
clearKeepLive,
|
||||||
|
setRouteKey,
|
||||||
|
setRouteShow,
|
||||||
|
setRouteKeyAction
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,26 +1,24 @@
|
||||||
import '@/utils/objects'
|
import '@/utils/objects'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
export const searchStore = defineStore({
|
export const searchStore = defineStore('search', () => {
|
||||||
id: 'search',
|
// 定义state
|
||||||
state: () => ({
|
const pool = ref([])
|
||||||
active: false,
|
const hotkey = ref({
|
||||||
hotkey: {
|
|
||||||
open: 's',
|
open: 's',
|
||||||
close: 'esc'
|
close: 'esc'
|
||||||
},
|
})
|
||||||
pool: []
|
const active = ref(false)
|
||||||
}),
|
|
||||||
getters: {},
|
// 定义action
|
||||||
actions: {
|
const toggleActive = () => {
|
||||||
toggleActive() {
|
active.value = !active.value
|
||||||
this.active = !this.active
|
}
|
||||||
},
|
const setActive = (val) => {
|
||||||
setActive(active) {
|
active.value = val
|
||||||
this.active = active
|
}
|
||||||
},
|
const init = (menu) => {
|
||||||
init(menu) {
|
const poolList = []
|
||||||
const pool = []
|
|
||||||
const getFullName = function (meta) {
|
const getFullName = function (meta) {
|
||||||
if (meta.breadcrumb) {
|
if (meta.breadcrumb) {
|
||||||
let list = []
|
let list = []
|
||||||
|
@ -37,7 +35,7 @@ export const searchStore = defineStore({
|
||||||
if (m.children) {
|
if (m.children) {
|
||||||
push(m.children)
|
push(m.children)
|
||||||
} else if (m.children === null) {
|
} else if (m.children === null) {
|
||||||
pool.push({
|
poolList.push({
|
||||||
icon: m.meta.icon,
|
icon: m.meta.icon,
|
||||||
path: m.path,
|
path: m.path,
|
||||||
fullPath: m.path,
|
fullPath: m.path,
|
||||||
|
@ -51,7 +49,15 @@ export const searchStore = defineStore({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
push(menu)
|
push(menu)
|
||||||
this.pool = pool
|
pool.value = poolList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
pool,
|
||||||
|
hotkey,
|
||||||
|
active,
|
||||||
|
toggleActive,
|
||||||
|
setActive,
|
||||||
|
init
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,51 +10,59 @@
|
||||||
*/
|
*/
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
export const viewTagsStore = defineStore({
|
export const viewTagsStore = defineStore('viewTags', () => {
|
||||||
id: 'viewTags',
|
// 定义state
|
||||||
state: () => ({
|
const viewTags = ref([])
|
||||||
viewTags: []
|
|
||||||
}),
|
// 定义action
|
||||||
getters: {},
|
const pushViewTags = (route) => {
|
||||||
actions: {
|
const target = viewTags.value.find((item) => item.path === route.path)
|
||||||
pushViewTags(route) {
|
|
||||||
const target = this.viewTags.find((item) => item.path === route.path)
|
|
||||||
const isName = route.name
|
const isName = route.name
|
||||||
if (!target && isName) {
|
if (!target && isName) {
|
||||||
this.viewTags.push(route)
|
viewTags.value.push(route)
|
||||||
}
|
}
|
||||||
if (target) {
|
if (target) {
|
||||||
this.viewTags.forEach((item) => {
|
viewTags.value.forEach((item, index) => {
|
||||||
if (item.path === route.path) {
|
if (item.path === route.path) {
|
||||||
Object.assign(item, route)
|
viewTags.value[index] = { ...route, ...item }
|
||||||
|
// Object.assign(item, route)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
removeViewTags(route) {
|
const removeViewTags = (route) => {
|
||||||
this.viewTags.forEach((item, index) => {
|
viewTags.value.forEach((item, index) => {
|
||||||
if (item.fullPath === route.fullPath) {
|
if (item.fullPath === route.fullPath) {
|
||||||
this.viewTags.splice(index, 1)
|
viewTags.value.splice(index, 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
updateViewTags(route) {
|
const updateViewTags = (route) => {
|
||||||
this.viewTags.forEach((item) => {
|
viewTags.value.forEach((item, index) => {
|
||||||
if (item.fullPath == route.fullPath) {
|
if (item.fullPath === route.fullPath) {
|
||||||
Object.assign(item, route)
|
viewTags.value[index] = { ...route, ...item }
|
||||||
|
// Object.assign(item, route)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
updateViewTagsTitle(title = '') {
|
const updateViewTagsTitle = (title = '') => {
|
||||||
const nowFullPath = location.hash.substring(1)
|
const nowFullPath = location.hash.substring(1)
|
||||||
this.viewTags.forEach((item) => {
|
viewTags.value.forEach((item) => {
|
||||||
if (item.fullPath == nowFullPath) {
|
if (item.fullPath === nowFullPath) {
|
||||||
item.meta.title = title
|
item.meta.title = title
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
|
||||||
clearViewTags() {
|
|
||||||
this.viewTags = []
|
|
||||||
}
|
}
|
||||||
|
const clearViewTags = () => {
|
||||||
|
viewTags.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
viewTags,
|
||||||
|
pushViewTags,
|
||||||
|
removeViewTags,
|
||||||
|
updateViewTags,
|
||||||
|
updateViewTagsTitle,
|
||||||
|
clearViewTags
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -21,7 +21,7 @@ export default {
|
||||||
RgbToHex(a, b, c) {
|
RgbToHex(a, b, c) {
|
||||||
const hexs = [a.toString(16), b.toString(16), c.toString(16)]
|
const hexs = [a.toString(16), b.toString(16), c.toString(16)]
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
if (hexs[i].length == 1) hexs[i] = `0${hexs[i]}`
|
if (hexs[i].length === 1) hexs[i] = `0${hexs[i]}`
|
||||||
}
|
}
|
||||||
return `#${hexs.join('')}`
|
return `#${hexs.join('')}`
|
||||||
},
|
},
|
||||||
|
|
|
@ -57,13 +57,11 @@ export const watermark = {
|
||||||
if (wmInstance) {
|
if (wmInstance) {
|
||||||
// 避免一直触发
|
// 避免一直触发
|
||||||
// observer.disconnect();
|
// observer.disconnect();
|
||||||
// console.log('水印属性修改了');
|
|
||||||
wmInstance.setAttribute('style', styleStr)
|
wmInstance.setAttribute('style', styleStr)
|
||||||
} else {
|
} else {
|
||||||
/* 此处根据用户登录状态,判断是否终止监听,避免用户退出后登录页面仍然有水印 */
|
/* 此处根据用户登录状态,判断是否终止监听,避免用户退出后登录页面仍然有水印 */
|
||||||
if (tool.data.get('TOKEN')) {
|
if (tool.data.get('TOKEN')) {
|
||||||
//标签被移除,重新添加标签
|
//标签被移除,重新添加标签
|
||||||
// console.log('水印标签被移除了');
|
|
||||||
document.body.appendChild(watermark)
|
document.body.appendChild(watermark)
|
||||||
} else {
|
} else {
|
||||||
observer.disconnect()
|
observer.disconnect()
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
import loginApi from '@/api/auth/loginApi'
|
import loginApi from '@/api/auth/loginApi'
|
||||||
import userCenterApi from '@/api/sys/userCenterApi'
|
import userCenterApi from '@/api/sys/userCenterApi'
|
||||||
import dictApi from '@/api/dev/dictApi'
|
import dictApi from '@/api/dev/dictApi'
|
||||||
import { onMounted } from 'vue'
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 获取当前url
|
// 获取当前url
|
||||||
|
|
|
@ -97,48 +97,37 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup>
|
||||||
<script>
|
|
||||||
import loginApi from '@/api/auth/loginApi'
|
import loginApi from '@/api/auth/loginApi'
|
||||||
import phoneLoginForm from './phoneLoginForm.vue'
|
import PhoneLoginForm from './phoneLoginForm.vue'
|
||||||
import threeLogin from './threeLogin.vue'
|
import ThreeLogin from './threeLogin.vue'
|
||||||
import smCrypto from '@/utils/smCrypto'
|
import smCrypto from '@/utils/smCrypto'
|
||||||
import { required } from '@/utils/formRules'
|
import { required } from '@/utils/formRules'
|
||||||
import { afterLogin } from './util'
|
import { afterLogin } from './util'
|
||||||
import config from '@/config'
|
import configData from '@/config'
|
||||||
import configApi from '@/api/dev/configApi'
|
import configApi from '@/api/dev/configApi'
|
||||||
import tool from '@/utils/tool'
|
import tool from '@/utils/tool'
|
||||||
import { globalStore, iframeStore, keepAliveStore, viewTagsStore } from '@/store'
|
import { globalStore, iframeStore, keepAliveStore, viewTagsStore } from '@/store'
|
||||||
import { mapActions, mapState } from 'pinia'
|
const { proxy } = getCurrentInstance()
|
||||||
|
|
||||||
export default {
|
const activeKey = ref('userAccount')
|
||||||
name: 'Login',
|
const captchaOpen = ref(configData.SYS_BASE_CONFIG.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN)
|
||||||
components: {
|
const validCodeBase64 = ref('')
|
||||||
phoneLoginForm,
|
const loading = ref(false)
|
||||||
threeLogin
|
|
||||||
},
|
const ruleForm = reactive({
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
activeKey: 'userAccount',
|
|
||||||
captchaOpen: config.SYS_BASE_CONFIG.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN,
|
|
||||||
validCodeBase64: '',
|
|
||||||
ruleForm: {
|
|
||||||
account: 'superAdmin',
|
account: 'superAdmin',
|
||||||
password: '123456',
|
password: '123456',
|
||||||
validCode: '',
|
validCode: '',
|
||||||
validCodeReqNo: '',
|
validCodeReqNo: '',
|
||||||
autologin: false
|
autologin: false
|
||||||
},
|
})
|
||||||
rules: {
|
|
||||||
account: [required(this.$t('login.accountError'), 'blur')],
|
const rules = reactive({
|
||||||
password: [required(this.$t('login.PWError'), 'blur')]
|
account: [required(proxy.$t('login.accountError'), 'blur')],
|
||||||
},
|
password: [required(proxy.$t('login.PWError'), 'blur')]
|
||||||
loading: false,
|
})
|
||||||
config: {
|
const lang = ref([
|
||||||
lang: tool.data.get('APP_LANG') || this.$CONFIG.LANG,
|
|
||||||
theme: tool.data.get('APP_THEME') || 'default'
|
|
||||||
},
|
|
||||||
lang: [
|
|
||||||
{
|
{
|
||||||
name: '简体中文',
|
name: '简体中文',
|
||||||
value: 'zh-cn'
|
value: 'zh-cn'
|
||||||
|
@ -147,90 +136,106 @@
|
||||||
name: 'English',
|
name: 'English',
|
||||||
value: 'en'
|
value: 'en'
|
||||||
}
|
}
|
||||||
]
|
])
|
||||||
}
|
const config = ref({
|
||||||
},
|
lang: tool.data.get('APP_LANG') || proxy.$CONFIG.LANG,
|
||||||
computed: {
|
theme: tool.data.get('APP_THEME') || 'default'
|
||||||
...mapState(globalStore, ['sysBaseConfig']),
|
})
|
||||||
},
|
|
||||||
watch: {
|
const store = globalStore()
|
||||||
'config.theme': function (val) {
|
const kStore = keepAliveStore()
|
||||||
document.body.setAttribute('data-theme', val)
|
const iStore = iframeStore()
|
||||||
},
|
const vStore = viewTagsStore()
|
||||||
'config.lang': function (val) {
|
|
||||||
this.$i18n.locale = val
|
const setSysBaseConfig = store.setSysBaseConfig
|
||||||
tool.data.set('APP_LANG', val)
|
const clearKeepLive = kStore.clearKeepLive
|
||||||
}
|
const clearIframeList = iStore.clearIframeList
|
||||||
},
|
const clearViewTags = vStore.clearViewTags
|
||||||
created() {
|
|
||||||
this.clearViewTags()
|
const sysBaseConfig = computed(() => {
|
||||||
this.clearKeepLive()
|
return store.sysBaseConfig
|
||||||
this.clearIframeList()
|
})
|
||||||
},
|
|
||||||
mounted() {
|
onMounted(() => {
|
||||||
let formData = ref(config.SYS_BASE_CONFIG)
|
let formData = ref(configData.SYS_BASE_CONFIG)
|
||||||
configApi.configSysBaseList().then((data) => {
|
configApi.configSysBaseList().then((data) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
data.forEach((item) => {
|
data.forEach((item) => {
|
||||||
formData.value[item.configKey] = item.configValue
|
formData.value[item.configKey] = item.configValue
|
||||||
})
|
})
|
||||||
this.captchaOpen = formData.value.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN
|
captchaOpen.value = formData.value.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN
|
||||||
tool.data.set('SNOWY_SYS_BASE_CONFIG', formData.value)
|
tool.data.set('SNOWY_SYS_BASE_CONFIG', formData.value)
|
||||||
this.setSysBaseConfig(formData.value)
|
setSysBaseConfig(formData.value)
|
||||||
this.refreshSwitch()
|
refreshSwitch()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
})
|
||||||
methods: {
|
|
||||||
...mapActions(keepAliveStore, ['clearKeepLive']),
|
onBeforeMount(() => {
|
||||||
...mapActions(viewTagsStore, ['clearViewTags']),
|
clearViewTags()
|
||||||
...mapActions(iframeStore, ['clearIframeList']),
|
clearKeepLive()
|
||||||
...mapActions(globalStore, ['setSysBaseConfig']),
|
clearIframeList()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听语言
|
||||||
|
watch(
|
||||||
|
() => config.value.lang,
|
||||||
|
(newValue) => {
|
||||||
|
proxy.$i18n.locale = newValue
|
||||||
|
tool.data.set('APP_LANG', newValue)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// 主题
|
||||||
|
watch(
|
||||||
|
() => config.value.theme,
|
||||||
|
(newValue) => {
|
||||||
|
document.body.setAttribute('data-theme', newValue)
|
||||||
|
}
|
||||||
|
)
|
||||||
// 通过开关加载内容
|
// 通过开关加载内容
|
||||||
refreshSwitch() {
|
const refreshSwitch = () => {
|
||||||
// 判断是否开启验证码
|
// 判断是否开启验证码
|
||||||
if (this.captchaOpen === 'true') {
|
if (captchaOpen.value === 'true') {
|
||||||
// 加载验证码
|
// 加载验证码
|
||||||
this.loginCaptcha()
|
loginCaptcha()
|
||||||
// 加入校验
|
// 加入校验
|
||||||
this.rules.validCode = [required(this.$t('login.validError'), 'blur')]
|
rules.validCode = [required(proxy.$t('login.validError'), 'blur')]
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
// 获取验证码
|
// 获取验证码
|
||||||
loginCaptcha() {
|
const loginCaptcha = () => {
|
||||||
loginApi.getPicCaptcha().then((data) => {
|
loginApi.getPicCaptcha().then((data) => {
|
||||||
this.validCodeBase64 = data.validCodeBase64
|
validCodeBase64.value = data.validCodeBase64
|
||||||
this.ruleForm.validCodeReqNo = data.validCodeReqNo
|
ruleForm.validCodeReqNo = data.validCodeReqNo
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
// 用户名密码登录
|
//登陆
|
||||||
async login() {
|
const loginForm = ref()
|
||||||
this.$refs.loginForm.validate().then(async () => {
|
const login = async () => {
|
||||||
this.loading = true
|
loginForm.value.validate().then(async () => {
|
||||||
|
loading.value = true
|
||||||
const loginData = {
|
const loginData = {
|
||||||
account: this.ruleForm.account,
|
account: ruleForm.account,
|
||||||
// 密码进行SM2加密,传输过程中看到的只有密文,后端存储使用hash
|
// 密码进行SM2加密,传输过程中看到的只有密文,后端存储使用hash
|
||||||
password: smCrypto.doSm2Encrypt(this.ruleForm.password),
|
password: smCrypto.doSm2Encrypt(ruleForm.password),
|
||||||
validCode: this.ruleForm.validCode,
|
validCode: ruleForm.validCode,
|
||||||
validCodeReqNo: this.ruleForm.validCodeReqNo
|
validCodeReqNo: ruleForm.validCodeReqNo
|
||||||
}
|
}
|
||||||
// 获取token
|
// 获取token
|
||||||
try {
|
try {
|
||||||
const loginToken = await loginApi.login(loginData)
|
const loginToken = await loginApi.login(loginData)
|
||||||
afterLogin(loginToken)
|
afterLogin(loginToken)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.loading = false
|
loading.value = false
|
||||||
this.loginCaptcha()
|
loginCaptcha()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
|
||||||
configLang(key) {
|
|
||||||
this.config.lang = key
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
const configLang = (key) => {
|
||||||
|
config.value.lang = key
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
@import 'login';
|
@import 'login';
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -22,7 +22,7 @@ export const afterLogin = async (loginToken) => {
|
||||||
// 重置系统默认应用
|
// 重置系统默认应用
|
||||||
tool.data.set('SNOWY_MENU_MODULE_ID', menu[0].id)
|
tool.data.set('SNOWY_MENU_MODULE_ID', menu[0].id)
|
||||||
message.success('登录成功')
|
message.success('登录成功')
|
||||||
if (!!tool.data.get('LAST_VIEWS_PATH')) {
|
if (tool.data.get('LAST_VIEWS_PATH')) {
|
||||||
// 如果有缓存,将其登录跳转到最后访问的路由
|
// 如果有缓存,将其登录跳转到最后访问的路由
|
||||||
indexMenu = tool.data.get('LAST_VIEWS_PATH')
|
indexMenu = tool.data.get('LAST_VIEWS_PATH')
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<s-table ref="table" :columns="columns" :data="loadDataB" :alert="false" bordered :row-key="(record) => record.id">
|
<s-table ref="tableRef" :columns="columns" :data="loadDataB" :alert="false" bordered :row-key="(record) => record.id">
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
<template v-if="column.dataIndex === 'avatar'">
|
<template v-if="column.dataIndex === 'avatar'">
|
||||||
<a-avatar :src="record.avatar" style="width: 25px; height: 25px" />
|
<a-avatar :src="record.avatar" style="width: 25px; height: 25px" />
|
||||||
|
@ -18,13 +18,13 @@
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</s-table>
|
</s-table>
|
||||||
<token-info-list ref="tokenInfoList" @successful="table.refresh()" />
|
<token-info-list ref="tokenInfoList" @successful="tableRef.refresh()" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="monitorBTab">
|
<script setup name="monitorBTab">
|
||||||
import monitorApi from '@/api/auth/monitorApi'
|
import monitorApi from '@/api/auth/monitorApi'
|
||||||
import TokenInfoList from './tokenInfoList.vue'
|
import TokenInfoList from './tokenInfoList.vue'
|
||||||
const table = ref(null)
|
const tableRef = ref(null)
|
||||||
const tokenInfoList = ref()
|
const tokenInfoList = ref()
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
monitorApi.monitorBExit(params).then(() => {
|
monitorApi.monitorBExit(params).then(() => {
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<s-table ref="table" :columns="columns" :data="loadDataC" :alert="false" bordered :row-key="(record) => record.id">
|
<s-table ref="tableRef" :columns="columns" :data="loadDataC" :alert="false" bordered :row-key="(record) => record.id">
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
<template v-if="column.dataIndex === 'avatar'">
|
<template v-if="column.dataIndex === 'avatar'">
|
||||||
<a-avatar :src="record.avatar" style="width: 25px; height: 25px" />
|
<a-avatar :src="record.avatar" style="width: 25px; height: 25px" />
|
||||||
|
@ -18,13 +18,13 @@
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</s-table>
|
</s-table>
|
||||||
<token-info-list ref="tokenInfoList" @successful="table.refresh()" />
|
<token-info-list ref="tokenInfoList" @successful="tableRef.refresh()" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="monitorCTab">
|
<script setup name="monitorCTab">
|
||||||
import monitorApi from '@/api/auth/monitorApi'
|
import monitorApi from '@/api/auth/monitorApi'
|
||||||
import TokenInfoList from './tokenInfoList.vue'
|
import TokenInfoList from './tokenInfoList.vue'
|
||||||
const table = ref(null)
|
const tableRef = ref(null)
|
||||||
const tokenInfoList = ref()
|
const tokenInfoList = ref()
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
monitorApi.monitorCExit(params).then(() => {
|
monitorApi.monitorCExit(params).then(() => {
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="authMonitor">
|
<script setup name="authMonitor">
|
||||||
import analyse from './analyse.vue'
|
import Analyse from './analyse.vue'
|
||||||
import monitorBTab from './bTab.vue'
|
import MonitorBTab from './bTab.vue'
|
||||||
import monitorCTab from './cTab.vue'
|
import MonitorCTab from './cTab.vue'
|
||||||
const activeKey = ref('1')
|
const activeKey = ref('1')
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<xn-form-container
|
<xn-form-container title="令牌列表" :width="650" :visible="visible" :destroy-on-close="true" @close="onClose">
|
||||||
title="令牌列表"
|
|
||||||
:width="650"
|
|
||||||
:visible="visible"
|
|
||||||
:destroy-on-close="true"
|
|
||||||
@close="onClose"
|
|
||||||
>
|
|
||||||
<a-button
|
<a-button
|
||||||
danger
|
danger
|
||||||
style="margin-bottom: 10px"
|
style="margin-bottom: 10px"
|
||||||
|
@ -104,7 +98,7 @@
|
||||||
// 字段数据
|
// 字段数据
|
||||||
const loadData = ref([])
|
const loadData = ref([])
|
||||||
// 默认是关闭状态
|
// 默认是关闭状态
|
||||||
let visible = $ref(false)
|
const visible = ref(false)
|
||||||
// 多选的
|
// 多选的
|
||||||
const selectedRowKeys = ref([])
|
const selectedRowKeys = ref([])
|
||||||
const exitLoading = ref(false)
|
const exitLoading = ref(false)
|
||||||
|
@ -116,13 +110,13 @@
|
||||||
const onOpen = (tokenInfoList, type) => {
|
const onOpen = (tokenInfoList, type) => {
|
||||||
monitorType.value = type
|
monitorType.value = type
|
||||||
loadData.value = cloneDeep(tokenInfoList)
|
loadData.value = cloneDeep(tokenInfoList)
|
||||||
visible = true
|
visible.value = true
|
||||||
}
|
}
|
||||||
// 关闭抽屉
|
// 关闭抽屉
|
||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
loadData.value = []
|
loadData.value = []
|
||||||
monitorType.value = ''
|
monitorType.value = ''
|
||||||
visible = false
|
visible.value = false
|
||||||
}
|
}
|
||||||
// 多选
|
// 多选
|
||||||
const rowSelection = {
|
const rowSelection = {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-button type="primary" @click="table.refresh(true)">查询</a-button>
|
<a-button type="primary" @click="tableRef.refresh(true)">查询</a-button>
|
||||||
<a-button style="margin: 0 8px" @click="reset">重置</a-button>
|
<a-button style="margin: 0 8px" @click="reset">重置</a-button>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
</a-card>
|
</a-card>
|
||||||
<a-card :bordered="false">
|
<a-card :bordered="false">
|
||||||
<s-table
|
<s-table
|
||||||
ref="table"
|
ref="tableRef"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="loadData"
|
:data="loadData"
|
||||||
:alert="false"
|
:alert="false"
|
||||||
|
@ -45,9 +45,9 @@
|
||||||
<script setup name="authThird">
|
<script setup name="authThird">
|
||||||
import thirdApi from '@/api/auth/thirdApi'
|
import thirdApi from '@/api/auth/thirdApi'
|
||||||
import tool from '@/utils/tool'
|
import tool from '@/utils/tool'
|
||||||
let searchFormState = reactive({})
|
const searchFormState = ref({})
|
||||||
const searchFormRef = ref()
|
const searchFormRef = ref()
|
||||||
const table = ref()
|
const tableRef = ref()
|
||||||
const toolConfig = { refresh: true, height: true, columnSetting: false, striped: false }
|
const toolConfig = { refresh: true, height: true, columnSetting: false, striped: false }
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
|
@ -83,14 +83,14 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
const loadData = (parameter) => {
|
const loadData = (parameter) => {
|
||||||
return thirdApi.thirdPage(Object.assign(parameter, searchFormState)).then((res) => {
|
return thirdApi.thirdPage(Object.assign(parameter, searchFormState.value)).then((res) => {
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 重置
|
// 重置
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
searchFormRef.value.resetFields();
|
searchFormRef.value.resetFields();
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 分类
|
// 分类
|
||||||
const categoryOptions = tool.dictList('THIRD_CATEGORY')
|
const categoryOptions = tool.dictList('THIRD_CATEGORY')
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-button type="primary" @click="table.refresh(true)">
|
<a-button type="primary" @click="tableRef.refresh(true)">
|
||||||
<template #icon><SearchOutlined /></template>
|
<template #icon><SearchOutlined /></template>
|
||||||
查询
|
查询
|
||||||
</a-button>
|
</a-button>
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
</a-card>
|
</a-card>
|
||||||
<a-card :bordered="false" style="margin-bottom: 10px">
|
<a-card :bordered="false" style="margin-bottom: 10px">
|
||||||
<s-table
|
<s-table
|
||||||
ref="table"
|
ref="tableRef"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="loadData"
|
:data="loadData"
|
||||||
:expand-row-by-click="true"
|
:expand-row-by-click="true"
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 定义tableDOM
|
// 定义tableDOM
|
||||||
const table = ref(null)
|
const tableRef = ref(null)
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
const cardLoading = ref(true)
|
const cardLoading = ref(true)
|
||||||
const searchFormRef = ref()
|
const searchFormRef = ref()
|
||||||
|
@ -136,7 +136,7 @@
|
||||||
// 重置
|
// 重置
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
searchFormRef.value.resetFields()
|
searchFormRef.value.resetFields()
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 加载左侧的树
|
// 加载左侧的树
|
||||||
const loadTreeData = () => {
|
const loadTreeData = () => {
|
||||||
|
@ -166,11 +166,11 @@
|
||||||
delete searchFormState.value.parentId
|
delete searchFormState.value.parentId
|
||||||
columns.splice(2, 1)
|
columns.splice(2, 1)
|
||||||
}
|
}
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 表单界面回调
|
// 表单界面回调
|
||||||
const formSuccessful = () => {
|
const formSuccessful = () => {
|
||||||
table.value.refresh()
|
tableRef.value.refresh()
|
||||||
refreshStoreDict()
|
refreshStoreDict()
|
||||||
}
|
}
|
||||||
// 刷新store中的字典
|
// 刷新store中的字典
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
// 定义emit事件
|
// 定义emit事件
|
||||||
const emit = defineEmits({ successful: null })
|
const emit = defineEmits({ successful: null })
|
||||||
// 默认是关闭状态
|
// 默认是关闭状态
|
||||||
let visible = $ref(false)
|
const visible = ref(false)
|
||||||
let UserSelectorPlus = ref()
|
let UserSelectorPlus = ref()
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
// 表单数据,也就是默认给一些数据
|
// 表单数据,也就是默认给一些数据
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
|
|
||||||
// 打开抽屉
|
// 打开抽屉
|
||||||
const onOpen = (record, parentId) => {
|
const onOpen = (record, parentId) => {
|
||||||
visible = true
|
visible.value = true
|
||||||
formData.value = {
|
formData.value = {
|
||||||
sortCode: 99
|
sortCode: 99
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@
|
||||||
}
|
}
|
||||||
// 关闭抽屉
|
// 关闭抽屉
|
||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
visible = false
|
visible.value = false
|
||||||
}
|
}
|
||||||
// 默认要校验的
|
// 默认要校验的
|
||||||
const formRules = {
|
const formRules = {
|
||||||
|
@ -152,7 +152,7 @@
|
||||||
bizOrgApi
|
bizOrgApi
|
||||||
.submitForm(formData.value, formData.value.id)
|
.submitForm(formData.value, formData.value.id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
visible = false
|
visible.value = false
|
||||||
emit('successful')
|
emit('successful')
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-button type="primary" @click="table.refresh(true)">
|
<a-button type="primary" @click="tableRef.refresh(true)">
|
||||||
<template #icon><SearchOutlined /></template>
|
<template #icon><SearchOutlined /></template>
|
||||||
查询
|
查询
|
||||||
</a-button>
|
</a-button>
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
</a-card>
|
</a-card>
|
||||||
<a-card :bordered="false">
|
<a-card :bordered="false">
|
||||||
<s-table
|
<s-table
|
||||||
ref="table"
|
ref="tableRef"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="loadData"
|
:data="loadData"
|
||||||
:expand-row-by-click="true"
|
:expand-row-by-click="true"
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button
|
<a-button
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="form.onOpen(undefined, searchFormState.parentId)"
|
@click="formRef.onOpen(undefined, searchFormState.parentId)"
|
||||||
v-if="hasPerm('bizOrgAdd')"
|
v-if="hasPerm('bizOrgAdd')"
|
||||||
>
|
>
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
{{ $TOOL.dictTypeData('ORG_CATEGORY', record.category) }}
|
{{ $TOOL.dictTypeData('ORG_CATEGORY', record.category) }}
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.dataIndex === 'action'">
|
<template v-if="column.dataIndex === 'action'">
|
||||||
<a @click="form.onOpen(record)" v-if="hasPerm('bizOrgEdit')">编辑</a>
|
<a @click="formRef.onOpen(record)" v-if="hasPerm('bizOrgEdit')">编辑</a>
|
||||||
<a-divider type="vertical" v-if="hasPerm(['bizOrgEdit', 'bizOrgDelete'], 'and')" />
|
<a-divider type="vertical" v-if="hasPerm(['bizOrgEdit', 'bizOrgDelete'], 'and')" />
|
||||||
<a-popconfirm title="删除此机构与下级机构吗?" @confirm="removeOrg(record)">
|
<a-popconfirm title="删除此机构与下级机构吗?" @confirm="removeOrg(record)">
|
||||||
<a-button type="link" danger size="small" v-if="hasPerm('bizOrgDelete')">删除</a-button>
|
<a-button type="link" danger size="small" v-if="hasPerm('bizOrgDelete')">删除</a-button>
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<Form ref="form" @successful="table.refresh()" />
|
<Form ref="formRef" @successful="tableRef.refresh()" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="bizOrg">
|
<script setup name="bizOrg">
|
||||||
|
@ -129,8 +129,8 @@
|
||||||
}
|
}
|
||||||
const toolConfig = { refresh: true, height: true, columnSetting: true }
|
const toolConfig = { refresh: true, height: true, columnSetting: true }
|
||||||
// 定义tableDOM
|
// 定义tableDOM
|
||||||
const table = ref(null)
|
const tableRef = ref(null)
|
||||||
const form = ref()
|
const formRef = ref()
|
||||||
const searchFormRef = ref()
|
const searchFormRef = ref()
|
||||||
const searchFormState = ref({})
|
const searchFormState = ref({})
|
||||||
// 默认展开的节点
|
// 默认展开的节点
|
||||||
|
@ -150,7 +150,7 @@
|
||||||
// 重置
|
// 重置
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
searchFormRef.value.resetFields()
|
searchFormRef.value.resetFields()
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 加载左侧的树
|
// 加载左侧的树
|
||||||
const loadTreeData = () => {
|
const loadTreeData = () => {
|
||||||
|
@ -188,7 +188,7 @@
|
||||||
} else {
|
} else {
|
||||||
delete searchFormState.value.parentId
|
delete searchFormState.value.parentId
|
||||||
}
|
}
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 删除
|
// 删除
|
||||||
const removeOrg = (record) => {
|
const removeOrg = (record) => {
|
||||||
|
@ -198,13 +198,13 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
bizOrgApi.orgDelete(params).then(() => {
|
bizOrgApi.orgDelete(params).then(() => {
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 批量删除
|
// 批量删除
|
||||||
const deleteBatchOrg = (params) => {
|
const deleteBatchOrg = (params) => {
|
||||||
bizOrgApi.orgDelete(params).then(() => {
|
bizOrgApi.orgDelete(params).then(() => {
|
||||||
table.value.clearRefreshSelected()
|
tableRef.value.clearRefreshSelected()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-button type="primary" @click="table.refresh(true)">
|
<a-button type="primary" @click="tableRef.refresh(true)">
|
||||||
<template #icon><SearchOutlined /></template>
|
<template #icon><SearchOutlined /></template>
|
||||||
查询
|
查询
|
||||||
</a-button>
|
</a-button>
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
</a-card>
|
</a-card>
|
||||||
<a-card :bordered="false">
|
<a-card :bordered="false">
|
||||||
<s-table
|
<s-table
|
||||||
ref="table"
|
ref="tableRef"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="loadData"
|
:data="loadData"
|
||||||
:expand-row-by-click="true"
|
:expand-row-by-click="true"
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<Form ref="formRef" @successful="table.refresh(true)" />
|
<Form ref="formRef" @successful="tableRef.refresh(true)" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="bizPosition">
|
<script setup name="bizPosition">
|
||||||
|
@ -129,7 +129,7 @@
|
||||||
}
|
}
|
||||||
const toolConfig = { refresh: true, height: true, columnSetting: true }
|
const toolConfig = { refresh: true, height: true, columnSetting: true }
|
||||||
// 定义tableDOM
|
// 定义tableDOM
|
||||||
const table = ref(null)
|
const tableRef = ref(null)
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
const searchFormRef = ref()
|
const searchFormRef = ref()
|
||||||
const searchFormState = ref({})
|
const searchFormState = ref({})
|
||||||
|
@ -149,7 +149,7 @@
|
||||||
// 重置
|
// 重置
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
searchFormRef.value.resetFields()
|
searchFormRef.value.resetFields()
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 加载左侧的树
|
// 加载左侧的树
|
||||||
bizOrgApi
|
bizOrgApi
|
||||||
|
@ -185,7 +185,7 @@
|
||||||
} else {
|
} else {
|
||||||
delete searchFormState.value.orgId
|
delete searchFormState.value.orgId
|
||||||
}
|
}
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 删除
|
// 删除
|
||||||
const removeOrg = (record) => {
|
const removeOrg = (record) => {
|
||||||
|
@ -195,13 +195,13 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
bizPositionApi.positionDelete(params).then(() => {
|
bizPositionApi.positionDelete(params).then(() => {
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 批量删除
|
// 批量删除
|
||||||
const deleteBatchPosition = (params) => {
|
const deleteBatchPosition = (params) => {
|
||||||
bizPositionApi.positionDelete(params).then(() => {
|
bizPositionApi.positionDelete(params).then(() => {
|
||||||
table.value.clearRefreshSelected()
|
tableRef.value.clearRefreshSelected()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-button type="primary" @click="table.refresh(true)">
|
<a-button type="primary" @click="tableRef.refresh(true)">
|
||||||
<template #icon><SearchOutlined /></template>
|
<template #icon><SearchOutlined /></template>
|
||||||
{{ $t('common.searchButton') }}
|
{{ $t('common.searchButton') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
</a-card>
|
</a-card>
|
||||||
<a-card :bordered="false">
|
<a-card :bordered="false">
|
||||||
<s-table
|
<s-table
|
||||||
ref="table"
|
ref="tableRef"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="loadData"
|
:data="loadData"
|
||||||
:expand-row-by-click="true"
|
:expand-row-by-click="true"
|
||||||
|
@ -140,7 +140,7 @@
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<Form ref="formRef" @successful="table.refresh()" />
|
<Form ref="formRef" @successful="tableRef.refresh()" />
|
||||||
<role-selector-plus
|
<role-selector-plus
|
||||||
ref="RoleSelectorPlusRef"
|
ref="RoleSelectorPlusRef"
|
||||||
:org-tree-api="selectorApiFunction.orgTreeApi"
|
:org-tree-api="selectorApiFunction.orgTreeApi"
|
||||||
|
@ -216,7 +216,7 @@
|
||||||
const searchFormRef = ref()
|
const searchFormRef = ref()
|
||||||
const defaultExpandedKeys = ref([])
|
const defaultExpandedKeys = ref([])
|
||||||
const searchFormState = ref({})
|
const searchFormState = ref({})
|
||||||
const table = ref(null)
|
const tableRef = ref(null)
|
||||||
const treeData = ref([])
|
const treeData = ref([])
|
||||||
const selectedRowKeys = ref([])
|
const selectedRowKeys = ref([])
|
||||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||||
|
@ -234,7 +234,7 @@
|
||||||
// 重置
|
// 重置
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
searchFormRef.value.resetFields()
|
searchFormRef.value.resetFields()
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 左侧树查询
|
// 左侧树查询
|
||||||
bizOrgApi
|
bizOrgApi
|
||||||
|
@ -284,7 +284,7 @@
|
||||||
} else {
|
} else {
|
||||||
delete searchFormState.value.orgId
|
delete searchFormState.value.orgId
|
||||||
}
|
}
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 修改状态
|
// 修改状态
|
||||||
const editStatus = (record) => {
|
const editStatus = (record) => {
|
||||||
|
@ -293,7 +293,7 @@
|
||||||
bizUserApi
|
bizUserApi
|
||||||
.userDisableUser(record)
|
.userDisableUser(record)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
table.value.refresh()
|
tableRef.value.refresh()
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
@ -302,7 +302,7 @@
|
||||||
bizUserApi
|
bizUserApi
|
||||||
.userEnableUser(record)
|
.userEnableUser(record)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
table.value.refresh()
|
tableRef.value.refresh()
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
@ -317,7 +317,7 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
bizUserApi.userDelete(params).then(() => {
|
bizUserApi.userDelete(params).then(() => {
|
||||||
table.value.refresh()
|
tableRef.value.refresh()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 批量导出校验并加参数
|
// 批量导出校验并加参数
|
||||||
|
@ -348,13 +348,13 @@
|
||||||
const exportBatchUser = (params) => {
|
const exportBatchUser = (params) => {
|
||||||
bizUserApi.userExport(params).then((res) => {
|
bizUserApi.userExport(params).then((res) => {
|
||||||
downloadUtil.resultDownload(res)
|
downloadUtil.resultDownload(res)
|
||||||
table.value.clearSelected()
|
tableRef.value.clearSelected()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 批量删除
|
// 批量删除
|
||||||
const deleteBatchUser = (params) => {
|
const deleteBatchUser = (params) => {
|
||||||
bizUserApi.userDelete(params).then(() => {
|
bizUserApi.userDelete(params).then(() => {
|
||||||
table.value.clearRefreshSelected()
|
tableRef.value.clearRefreshSelected()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 打开角色选择器
|
// 打开角色选择器
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="emailConfig">
|
<script setup name="emailConfig">
|
||||||
import localEmailForm from './localEmailForm.vue'
|
import LocalEmailForm from './localEmailForm.vue'
|
||||||
import aliyunEmailForm from './aliyunEmailForm.vue'
|
import AliyunEmailForm from './aliyunEmailForm.vue'
|
||||||
import tencentEmailForm from './tencentEmailForm.vue'
|
import TencentEmailForm from './tencentEmailForm.vue'
|
||||||
const activeKey = ref('localEmail')
|
const activeKey = ref('localEmail')
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="fileConfig">
|
<script setup name="fileConfig">
|
||||||
import localFileForm from './localFileForm.vue'
|
import LocalFileForm from './localFileForm.vue'
|
||||||
import aliyunFileForm from './aliyunFileForm.vue'
|
import AliyunFileForm from './aliyunFileForm.vue'
|
||||||
import tencentFileForm from './tencentFileForm.vue'
|
import TencentFileForm from './tencentFileForm.vue'
|
||||||
import minioFileForm from './minioFileForm.vue'
|
import MinioFileForm from './minioFileForm.vue'
|
||||||
const activeKey = ref('localFile')
|
const activeKey = ref('localFile')
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
import { required } from '@/utils/formRules'
|
import { required } from '@/utils/formRules'
|
||||||
import configApi from '@/api/dev/configApi'
|
import configApi from '@/api/dev/configApi'
|
||||||
// 默认是关闭状态
|
// 默认是关闭状态
|
||||||
let visible = $ref(false)
|
const visible = ref(false)
|
||||||
const emit = defineEmits({ successful: null })
|
const emit = defineEmits({ successful: null })
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
// 表单数据
|
// 表单数据
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
// 打开抽屉
|
// 打开抽屉
|
||||||
const onOpen = (record) => {
|
const onOpen = (record) => {
|
||||||
visible = true
|
visible.value = true
|
||||||
formData.value = {
|
formData.value = {
|
||||||
sortCode: 99
|
sortCode: 99
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
// 关闭抽屉
|
// 关闭抽屉
|
||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
formRef.value.resetFields()
|
formRef.value.resetFields()
|
||||||
visible = false
|
visible.value = false
|
||||||
}
|
}
|
||||||
// 默认要校验的
|
// 默认要校验的
|
||||||
const formRules = {
|
const formRules = {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<s-table
|
<s-table
|
||||||
ref="table"
|
ref="tableRef"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="loadData"
|
:data="loadData"
|
||||||
:alert="false"
|
:alert="false"
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
>
|
>
|
||||||
<template #operator class="table-operator">
|
<template #operator class="table-operator">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button type="primary" @click="form.onOpen()">
|
<a-button type="primary" @click="formRef.onOpen()">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<plus-outlined />
|
<plus-outlined />
|
||||||
</template>
|
</template>
|
||||||
|
@ -21,14 +21,14 @@
|
||||||
placeholder="请输入关键字"
|
placeholder="请输入关键字"
|
||||||
enter-button
|
enter-button
|
||||||
allowClear
|
allowClear
|
||||||
@search="table.refresh(true)"
|
@search="tableRef.refresh(true)"
|
||||||
/>
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
<template v-if="column.key === 'action'">
|
<template v-if="column.key === 'action'">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a @click="form.onOpen(record)">编辑</a>
|
<a @click="formRef.onOpen(record)">编辑</a>
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
<a-popconfirm title="确定要删除此配置吗?" @confirm="deleteConfig(record)">
|
<a-popconfirm title="确定要删除此配置吗?" @confirm="deleteConfig(record)">
|
||||||
<a-button type="link" danger size="small">删除</a-button>
|
<a-button type="link" danger size="small">删除</a-button>
|
||||||
|
@ -37,16 +37,15 @@
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</s-table>
|
</s-table>
|
||||||
<Form ref="form" @successful="table.refresh(true)" />
|
<Form ref="formRef" @successful="tableRef.refresh(true)" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="sysModule">
|
<script setup name="sysModule">
|
||||||
import Form from './form.vue'
|
import Form from './form.vue'
|
||||||
import configApi from '@/api/dev/configApi'
|
import configApi from '@/api/dev/configApi'
|
||||||
let searchFormState = reactive({})
|
const searchFormState = ref({})
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
const table = ref()
|
const tableRef = ref()
|
||||||
let form = ref()
|
|
||||||
const toolConfig = { refresh: true, height: true, columnSetting: false, striped: false }
|
const toolConfig = { refresh: true, height: true, columnSetting: false, striped: false }
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
|
@ -77,7 +76,7 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
const loadData = (parameter) => {
|
const loadData = (parameter) => {
|
||||||
return configApi.configPage(Object.assign(parameter, searchFormState)).then((res) => {
|
return configApi.configPage(Object.assign(parameter, searchFormState.value)).then((res) => {
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -89,7 +88,7 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
configApi.configDelete(params).then(() => {
|
configApi.configDelete(params).then(() => {
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="smsConfig">
|
<script setup name="smsConfig">
|
||||||
import aliyunSmsForm from './aliyunSmsForm.vue'
|
import AliyunSmsForm from './aliyunSmsForm.vue'
|
||||||
import tencentSmsForm from './tencentSmsForm.vue'
|
import TencentSmsForm from './tencentSmsForm.vue'
|
||||||
const activeKey = ref('aliyunSms')
|
const activeKey = ref('aliyunSms')
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -102,7 +102,7 @@
|
||||||
import { message } from 'ant-design-vue'
|
import { message } from 'ant-design-vue'
|
||||||
import configApi from '@/api/dev/configApi'
|
import configApi from '@/api/dev/configApi'
|
||||||
import tool from '@/utils/tool'
|
import tool from '@/utils/tool'
|
||||||
import menuTreeSelect from '@/components/TreeSelect/menuTreeSelect.vue'
|
import MenuTreeSelect from '@/components/TreeSelect/menuTreeSelect.vue'
|
||||||
|
|
||||||
// 定义emit事件
|
// 定义emit事件
|
||||||
const emit = defineEmits({ successful: null })
|
const emit = defineEmits({ successful: null })
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="thirdConfig">
|
<script setup name="thirdConfig">
|
||||||
import wechatThirdForm from './wechatThirdForm.vue'
|
import WechatThirdForm from './wechatThirdForm.vue'
|
||||||
import giteeThirdForm from './giteeThirdForm.vue'
|
import GiteeThirdForm from './giteeThirdForm.vue'
|
||||||
const activeKey = ref('wechatThird')
|
const activeKey = ref('wechatThird')
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-button type="primary" @click="$refs.table.refresh(true)">
|
<a-button type="primary" @click="tableRef.refresh(true)">
|
||||||
<template #icon><SearchOutlined /></template>
|
<template #icon><SearchOutlined /></template>
|
||||||
查询
|
查询
|
||||||
</a-button>
|
</a-button>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
</a-form>
|
</a-form>
|
||||||
<a-divider class="m-3 mx-0" />
|
<a-divider class="m-3 mx-0" />
|
||||||
<s-table
|
<s-table
|
||||||
ref="table"
|
ref="tableRef"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="loadData"
|
:data="loadData"
|
||||||
:expand-row-by-click="true"
|
:expand-row-by-click="true"
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
:row-key="(record) => record.id"
|
:row-key="(record) => record.id"
|
||||||
>
|
>
|
||||||
<template #operator class="table-operator">
|
<template #operator class="table-operator">
|
||||||
<a-button type="primary" @click="form.onOpen(undefined, 'BIZ', searchFormState.parentId)">
|
<a-button type="primary" @click="formRef.onOpen(undefined, 'BIZ', searchFormState.parentId)">
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新增
|
新增
|
||||||
</a-button>
|
</a-button>
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
<a-tag color="green" v-else>子级</a-tag>
|
<a-tag color="green" v-else>子级</a-tag>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.dataIndex === 'action'">
|
<template v-if="column.dataIndex === 'action'">
|
||||||
<a @click="form.onOpen(record, 'BIZ')">编辑</a>
|
<a @click="formRef.onOpen(record, 'BIZ')">编辑</a>
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
<a-popconfirm title="删除此字典与下级字典吗?" @confirm="remove(record)">
|
<a-popconfirm title="删除此字典与下级字典吗?" @confirm="remove(record)">
|
||||||
<a-button type="link" danger size="small">删除</a-button>
|
<a-button type="link" danger size="small">删除</a-button>
|
||||||
|
@ -63,14 +63,14 @@
|
||||||
</s-table>
|
</s-table>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<Form ref="form" @successful="formSuccessful()" />
|
<Form ref="formRef" @successful="formSuccessful()" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Empty } from 'ant-design-vue'
|
import { Empty } from 'ant-design-vue'
|
||||||
import dictApi from '@/api/dev/dictApi'
|
import dictApi from '@/api/dev/dictApi'
|
||||||
import Form from './form.vue'
|
import Form from './form.vue'
|
||||||
const { proxy } = getCurrentInstance()
|
import tool from '@/utils/tool'
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '字典名称',
|
title: '字典名称',
|
||||||
|
@ -94,10 +94,10 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
// 定义tableDOM
|
// 定义tableDOM
|
||||||
const table = ref(null)
|
const tableRef = ref(null)
|
||||||
const form = ref()
|
const formRef = ref()
|
||||||
const searchFormRef = ref()
|
const searchFormRef = ref()
|
||||||
let searchFormState = reactive({})
|
const searchFormState = ref({})
|
||||||
// 默认展开的节点
|
// 默认展开的节点
|
||||||
let defaultExpandedKeys = ref([])
|
let defaultExpandedKeys = ref([])
|
||||||
const treeData = ref([])
|
const treeData = ref([])
|
||||||
|
@ -109,9 +109,9 @@
|
||||||
const loadData = (parameter) => {
|
const loadData = (parameter) => {
|
||||||
loadTreeData()
|
loadTreeData()
|
||||||
parameter.category = 'BIZ'
|
parameter.category = 'BIZ'
|
||||||
return dictApi.dictPage(Object.assign(parameter, searchFormState)).then((data) => {
|
return dictApi.dictPage(Object.assign(parameter, searchFormState.value)).then((data) => {
|
||||||
if (data.records) {
|
if (data.records) {
|
||||||
if (searchFormState.parentId) {
|
if (searchFormState.value.parentId) {
|
||||||
let dataArray = []
|
let dataArray = []
|
||||||
data.records.forEach((item) => {
|
data.records.forEach((item) => {
|
||||||
const obj = data.records.find((f) => f.id === item.parentId)
|
const obj = data.records.find((f) => f.id === item.parentId)
|
||||||
|
@ -135,7 +135,7 @@
|
||||||
// 重置
|
// 重置
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
searchFormRef.value.resetFields()
|
searchFormRef.value.resetFields()
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 加载左侧的树
|
// 加载左侧的树
|
||||||
const loadTreeData = () => {
|
const loadTreeData = () => {
|
||||||
|
@ -151,7 +151,7 @@
|
||||||
// 点击树查询
|
// 点击树查询
|
||||||
const treeSelect = (selectedKeys) => {
|
const treeSelect = (selectedKeys) => {
|
||||||
if (selectedKeys && selectedKeys.length > 0) {
|
if (selectedKeys && selectedKeys.length > 0) {
|
||||||
searchFormState.parentId = selectedKeys.toString()
|
searchFormState.value.parentId = selectedKeys.toString()
|
||||||
if (!columns.find((f) => f.title === '层级')) {
|
if (!columns.find((f) => f.title === '层级')) {
|
||||||
columns.splice(2, 0, {
|
columns.splice(2, 0, {
|
||||||
title: '层级',
|
title: '层级',
|
||||||
|
@ -160,10 +160,10 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
delete searchFormState.parentId
|
delete searchFormState.value.parentId
|
||||||
columns.splice(2, 1)
|
columns.splice(2, 1)
|
||||||
}
|
}
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 删除
|
// 删除
|
||||||
const remove = (record) => {
|
const remove = (record) => {
|
||||||
|
@ -173,19 +173,19 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
dictApi.dictDelete(params).then(() => {
|
dictApi.dictDelete(params).then(() => {
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
})
|
})
|
||||||
refreshStoreDict()
|
refreshStoreDict()
|
||||||
}
|
}
|
||||||
// 表单界面回调
|
// 表单界面回调
|
||||||
const formSuccessful = () => {
|
const formSuccessful = () => {
|
||||||
table.value.refresh()
|
tableRef.value.refresh()
|
||||||
refreshStoreDict()
|
refreshStoreDict()
|
||||||
}
|
}
|
||||||
// 刷新store中的字典
|
// 刷新store中的字典
|
||||||
const refreshStoreDict = () => {
|
const refreshStoreDict = () => {
|
||||||
dictApi.dictTree().then((res) => {
|
dictApi.dictTree().then((res) => {
|
||||||
proxy.$TOOL.data.set('DICT_TYPE_TREE_DATA', res)
|
tool.data.set('DICT_TYPE_TREE_DATA', res)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
// 定义emit事件
|
// 定义emit事件
|
||||||
const emit = defineEmits({ successful: null })
|
const emit = defineEmits({ successful: null })
|
||||||
// 默认是关闭状态
|
// 默认是关闭状态
|
||||||
let visible = $ref(false)
|
const visible = ref(false)
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
// 表单数据
|
// 表单数据
|
||||||
let formData = ref({})
|
let formData = ref({})
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
|
|
||||||
// 打开抽屉
|
// 打开抽屉
|
||||||
const onOpen = (record, type, parentId) => {
|
const onOpen = (record, type, parentId) => {
|
||||||
visible = true
|
visible.value = true
|
||||||
formData.value = {
|
formData.value = {
|
||||||
sortCode: 99,
|
sortCode: 99,
|
||||||
category: type
|
category: type
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
}
|
}
|
||||||
// 关闭抽屉
|
// 关闭抽屉
|
||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
visible = false
|
visible.value = false
|
||||||
}
|
}
|
||||||
// 默认要校验的
|
// 默认要校验的
|
||||||
const formRules = {
|
const formRules = {
|
||||||
|
@ -112,7 +112,7 @@
|
||||||
const onSubmit = () => {
|
const onSubmit = () => {
|
||||||
formRef.value.validate().then(() => {
|
formRef.value.validate().then(() => {
|
||||||
dictApi.submitForm(formData.value, formData.value.id).then(() => {
|
dictApi.submitForm(formData.value, formData.value.id).then(() => {
|
||||||
visible = false
|
visible.value = false
|
||||||
emit('successful')
|
emit('successful')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-button type="primary" @click="$refs.table.refresh(true)">
|
<a-button type="primary" @click="tableRef.refresh(true)">
|
||||||
<template #icon><SearchOutlined /></template>
|
<template #icon><SearchOutlined /></template>
|
||||||
查询
|
查询
|
||||||
</a-button>
|
</a-button>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
</a-form>
|
</a-form>
|
||||||
<a-divider class="m-3 mx-0" />
|
<a-divider class="m-3 mx-0" />
|
||||||
<s-table
|
<s-table
|
||||||
ref="table"
|
ref="tableRef"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="loadData"
|
:data="loadData"
|
||||||
:expand-row-by-click="true"
|
:expand-row-by-click="true"
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
:row-key="(record) => record.id"
|
:row-key="(record) => record.id"
|
||||||
>
|
>
|
||||||
<template #operator class="table-operator">
|
<template #operator class="table-operator">
|
||||||
<a-button type="primary" @click="form.onOpen(undefined, 'FRM', searchFormState.parentId)">
|
<a-button type="primary" @click="formRef.onOpen(undefined, 'FRM', searchFormState.parentId)">
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新增
|
新增
|
||||||
</a-button>
|
</a-button>
|
||||||
|
@ -53,21 +53,21 @@
|
||||||
<a-tag color="green" v-else>子级</a-tag>
|
<a-tag color="green" v-else>子级</a-tag>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.dataIndex === 'action'">
|
<template v-if="column.dataIndex === 'action'">
|
||||||
<a @click="form.onOpen(record, 'FRM')">编辑</a>
|
<a @click="formRef.onOpen(record, 'FRM')">编辑</a>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</s-table>
|
</s-table>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<Form ref="form" @successful="formSuccessful()" />
|
<Form ref="formRef" @successful="formSuccessful()" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Empty } from 'ant-design-vue'
|
import { Empty } from 'ant-design-vue'
|
||||||
import dictApi from '@/api/dev/dictApi'
|
import dictApi from '@/api/dev/dictApi'
|
||||||
import Form from './form.vue'
|
import Form from './form.vue'
|
||||||
const { proxy } = getCurrentInstance()
|
import tool from '@/utils/tool'
|
||||||
let searchFormState = reactive({})
|
const searchFormState = ref({})
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '字典名称',
|
title: '字典名称',
|
||||||
|
@ -91,11 +91,11 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
// 定义tableDOM
|
// 定义tableDOM
|
||||||
const table = ref(null)
|
const tableRef = ref(null)
|
||||||
const form = ref()
|
const formRef = ref()
|
||||||
const searchFormRef = ref()
|
const searchFormRef = ref()
|
||||||
// 默认展开的节点
|
// 默认展开的节点
|
||||||
let defaultExpandedKeys = ref([])
|
const defaultExpandedKeys = ref([])
|
||||||
const treeData = ref([])
|
const treeData = ref([])
|
||||||
// 替换treeNode 中 title,key,children
|
// 替换treeNode 中 title,key,children
|
||||||
const treeFieldNames = { children: 'children', title: 'dictLabel', key: 'id' }
|
const treeFieldNames = { children: 'children', title: 'dictLabel', key: 'id' }
|
||||||
|
@ -105,9 +105,9 @@
|
||||||
const loadData = (parameter) => {
|
const loadData = (parameter) => {
|
||||||
loadTreeData()
|
loadTreeData()
|
||||||
parameter.category = 'FRM'
|
parameter.category = 'FRM'
|
||||||
return dictApi.dictPage(Object.assign(parameter, searchFormState)).then((data) => {
|
return dictApi.dictPage(Object.assign(parameter, searchFormState.value)).then((data) => {
|
||||||
if (data.records) {
|
if (data.records) {
|
||||||
if (searchFormState.parentId) {
|
if (searchFormState.value.parentId) {
|
||||||
let dataArray = []
|
let dataArray = []
|
||||||
data.records.forEach((item) => {
|
data.records.forEach((item) => {
|
||||||
const obj = data.records.find((f) => f.id === item.parentId)
|
const obj = data.records.find((f) => f.id === item.parentId)
|
||||||
|
@ -131,7 +131,7 @@
|
||||||
// 重置
|
// 重置
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
searchFormRef.value.resetFields()
|
searchFormRef.value.resetFields()
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 加载左侧的树
|
// 加载左侧的树
|
||||||
const loadTreeData = () => {
|
const loadTreeData = () => {
|
||||||
|
@ -147,7 +147,7 @@
|
||||||
// 点击树查询
|
// 点击树查询
|
||||||
const treeSelect = (selectedKeys) => {
|
const treeSelect = (selectedKeys) => {
|
||||||
if (selectedKeys && selectedKeys.length > 0) {
|
if (selectedKeys && selectedKeys.length > 0) {
|
||||||
searchFormState.parentId = selectedKeys.toString()
|
searchFormState.value.parentId = selectedKeys.toString()
|
||||||
if (!columns.find((f) => f.title === '层级')) {
|
if (!columns.find((f) => f.title === '层级')) {
|
||||||
columns.splice(2, 0, {
|
columns.splice(2, 0, {
|
||||||
title: '层级',
|
title: '层级',
|
||||||
|
@ -156,20 +156,20 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
delete searchFormState.parentId
|
delete searchFormState.value.parentId
|
||||||
columns.splice(2, 1)
|
columns.splice(2, 1)
|
||||||
}
|
}
|
||||||
table.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 表单界面回调
|
// 表单界面回调
|
||||||
const formSuccessful = () => {
|
const formSuccessful = () => {
|
||||||
table.value.refresh()
|
tableRef.value.refresh()
|
||||||
refreshStoreDict()
|
refreshStoreDict()
|
||||||
}
|
}
|
||||||
// 刷新store中的字典
|
// 刷新store中的字典
|
||||||
const refreshStoreDict = () => {
|
const refreshStoreDict = () => {
|
||||||
dictApi.dictTree().then((res) => {
|
dictApi.dictTree().then((res) => {
|
||||||
proxy.$TOOL.data.set('DICT_TYPE_TREE_DATA', res)
|
tool.data.set('DICT_TYPE_TREE_DATA', res)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue