ZaiZai 1 ano atrás
pai
commit
c3677f6372
68 arquivos alterados com 77 adições e 10917 exclusões
  1. BIN
      src/assets/images/datav-1.png
  2. BIN
      src/assets/images/datav-2.png
  3. BIN
      src/assets/images/datav-3.png
  4. BIN
      src/assets/images/datav-4.png
  5. BIN
      src/assets/images/datav-bg.png
  6. BIN
      src/assets/login/bg.png
  7. BIN
      src/assets/login/img.png
  8. 1 2
      src/config/index.js
  9. 0 56
      src/plugins/HcSocket.js
  10. 10 5
      src/router/index.js
  11. 7 184
      src/router/modules/base.js
  12. 1 3
      src/router/modules/token.js
  13. 2 2
      src/router/routers.js
  14. 7 38
      src/store/index.js
  15. 2 2
      src/store/modules/app.js
  16. 14 43
      src/store/modules/user.js
  17. 0 131
      src/styles/home/agent-charge.scss
  18. 0 28
      src/styles/home/home.scss
  19. 0 1
      src/styles/index.scss
  20. 0 0
      src/styles/view/config.scss
  21. 0 0
      src/styles/view/datav.scss
  22. 0 0
      src/styles/view/home.scss
  23. 0 81
      src/styles/view/login.dark.scss
  24. 0 132
      src/styles/view/login.scss
  25. 0 133
      src/views/authority/api.vue
  26. 0 133
      src/views/authority/data.vue
  27. 0 305
      src/views/authority/modules/api/auth.vue
  28. 0 336
      src/views/authority/modules/data/auth.vue
  29. 0 186
      src/views/authority/modules/role/auth.vue
  30. 0 293
      src/views/authority/role.vue
  31. 0 105
      src/views/certificate/admin.vue
  32. 0 153
      src/views/certificate/list.vue
  33. 0 136
      src/views/certificate/modules/admin/see.vue
  34. 0 329
      src/views/certificate/modules/list/form.vue
  35. 13 0
      src/views/home/datav.vue
  36. 0 203
      src/views/home/index.vue
  37. 0 281
      src/views/home/modules/agent-charge.vue
  38. 0 83
      src/views/home/modules/chart-person.vue
  39. 0 104
      src/views/home/modules/chart-pfx.vue
  40. 0 61
      src/views/home/modules/chart-type.vue
  41. 0 260
      src/views/login/components/pic.vue
  42. 20 157
      src/views/login/index.vue
  43. 0 223
      src/views/project/list.vue
  44. 0 252
      src/views/project/modules/list/info-dialog.vue
  45. 0 324
      src/views/project/modules/list/tree-node-edit.vue
  46. 0 487
      src/views/project/modules/list/wbs-tree.vue
  47. 0 13
      src/views/project/tree.vue
  48. 0 179
      src/views/resource/attach.vue
  49. 0 401
      src/views/resource/oss.vue
  50. 0 442
      src/views/resource/sms.vue
  51. 0 478
      src/views/system/app.vue
  52. 0 309
      src/views/system/client.vue
  53. 0 343
      src/views/system/dept.vue
  54. 0 271
      src/views/system/dict.vue
  55. 0 271
      src/views/system/dictbiz.vue
  56. 0 234
      src/views/system/menu-top.vue
  57. 0 478
      src/views/system/menu.vue
  58. 0 289
      src/views/system/modules/dict/dict.vue
  59. 0 289
      src/views/system/modules/dictbiz/dictbiz.vue
  60. 0 92
      src/views/system/modules/tenant/data-source.vue
  61. 0 230
      src/views/system/modules/tenant/package-data.vue
  62. 0 136
      src/views/system/modules/tenant/package.vue
  63. 0 87
      src/views/system/modules/tenant/setting.vue
  64. 0 221
      src/views/system/param.vue
  65. 0 300
      src/views/system/post.vue
  66. 0 398
      src/views/system/tenant.vue
  67. 0 7
      src/views/system/user.vue
  68. 0 197
      src/views/user/index.vue

BIN
src/assets/images/datav-1.png


BIN
src/assets/images/datav-2.png


BIN
src/assets/images/datav-3.png


BIN
src/assets/images/datav-4.png


BIN
src/assets/images/datav-bg.png


BIN
src/assets/login/bg.png


BIN
src/assets/login/img.png


+ 1 - 2
src/config/index.js

@@ -2,8 +2,7 @@ import config from './index.json'
 
 //主要配置
 export default {
-    title: '工程数字档案管理后台',
-    name: '工程数字档案管理后台',
+    title: '数据分析工具',
     key: 'analysis', // 配置主键,目前用于存储
     clientId: 'analysis', // 客户端id
     clientSecret: 'analysis_secret', // 客户端密钥

+ 0 - 56
src/plugins/HcSocket.js

@@ -1,56 +0,0 @@
-import website from '~src/config/index'
-import { isNullES } from 'js-fast-way'
-
-// 长链接推送插件
-export default class HcSocket {
-
-    static socket = null
-
-    static create(data, change) {
-        const socket = new WebSocket(website.socket + data)
-        socket.onopen = function () {
-            console.log('websocket 链接成功')
-        }
-        socket.onclose = function () {
-            console.log('websocket 链接已断开')
-        }
-        socket.onmessage = function ({ data }) {
-            if (typeof change !== 'function') {
-                return false
-            } else {
-                change(JSON.parse(data))
-            }
-        }
-        socket.onerror = function ({ data }) {
-            console.log('websocket 发生错误:', data)
-        }
-        this.socket = socket
-    }
-
-    //发送消息
-    static async send(data) {
-        const is_socket = await this.isSocket()
-        if (!is_socket) return false
-        this.socket.send(data)
-    }
-
-    //链接是否存在
-    static async isSocket(i = 0) {
-        let _this = this
-        return new Promise((resolve) => {
-            if (isNullES(_this.socket)) {
-                if (i <= 30) {
-                    setTimeout(async () => {
-                        i++
-                        resolve(await _this.isSocket(i))
-                    }, 1000)
-                } else {
-                    resolve(false)
-                }
-            } else {
-                resolve(true)
-            }
-        })
-    }
-
-}

+ 10 - 5
src/router/index.js

@@ -1,9 +1,13 @@
+import NProgress from 'nprogress'
+import '~src/styles/app/nprogress.scss'
+
+//路由插件
 import * as vueRouter from 'vue-router'
 import baseData from './modules/base'
-import { getToken } from '~src/api/auth'
 import { getRouterData } from './routers'
-import NProgress from 'nprogress'
-import '~src/styles/app/nprogress.scss'
+
+//其它工具
+import { getToken } from "hc-vue3-ui"
 import config from '~src/config/index'
 
 //设置路由数据
@@ -15,7 +19,7 @@ const router = vueRouter.createRouter({
 //路由拦截
 router.beforeResolve(async (to) => {
     NProgress.start()
-    const token = getToken(), auth = ['/login']
+    /*const token = getToken(), auth = ['/login']
     if (auth.indexOf(to.path) !== -1) {
         return true
     } else if (!token) {
@@ -27,7 +31,8 @@ router.beforeResolve(async (to) => {
         } else {
             return '/login'
         }
-    }
+    }*/
+    return true
 })
 
 router.afterEach((to) => {

+ 7 - 184
src/router/modules/base.js

@@ -4,7 +4,7 @@ import Layout from '~src/layout/index.vue'
 export default [
     {
         path: '/',
-        redirect: '/index',
+        redirect: '/datav',
     },
     {
         path: '/login',
@@ -13,194 +13,17 @@ export default [
         component: () => import('~src/views/login/index.vue'),
     },
     {
-        path: '/home',
-        name: 'home',
-        redirect: '/index',
+        path: '/datav',
+        name: 'datav',
+        redirect: '/datav',
         meta: { title: '首页' },
         component: Layout,
         children: [
             {
-                path: '/index',
-                name: 'index',
+                path: '/datav',
+                name: 'datav',
                 meta: { title: '首页' },
-                component: () => import('~src/views/home/index.vue'),
-            },
-            {
-                path: '/user-info',
-                name: 'user-info',
-                meta: { title: '个人中心' },
-                component: () => import('~src/views/user/index.vue'),
-            },
-        ],
-    },
-    {
-        path: '/manager/projectinfo',
-        name: 'projectinfo1',
-        redirect: '/manager/projectinfo/list',
-        meta: { title: '项目管理' },
-        component: Layout,
-        children: [
-            {
-                path: '/manager/projectinfo/list',
-                name: 'projectinfo/list',
-                meta: { title: '项目列表' },
-                component: () => import('~src/views/project/list.vue'),
-            },
-            {
-                path: '/manager/projectinfo/archivetreeconfig',
-                name: 'projectinfo_archivetreeconfig',
-                meta: { title: '项目归档树' },
-                component: () => import('~src/views/project/tree.vue'),
-            },
-        ],
-    },
-    {
-        path: '/certificate',
-        name: 'certificate',
-        redirect: '/certificate/management',
-        meta: { title: '电签管理' },
-        component: Layout,
-        children: [
-            {
-                path: '/certificate/admin',
-                name: '/certificate/management',
-                meta: { title: '证书管理' },
-                component: () => import('~src/views/certificate/admin.vue'),
-            },
-            {
-                path: '/certificate/list',
-                name: '/certificate/list',
-                meta: { title: '证书列表' },
-                component: () => import('~src/views/certificate/list.vue'),
-            },
-        ],
-    },
-    {
-        path: '/authority',
-        name: 'authority',
-        redirect: '/authority/role',
-        meta: { title: '权限管理' },
-        component: Layout,
-        children: [
-            {
-                path: '/authority/role',
-                name: 'role',
-                meta: { title: '角色管理' },
-                component: () => import('~src/views/authority/role.vue'),
-            },
-            {
-                path: '/authority/data-scope',
-                name: 'data_scope',
-                meta: { title: '数据权限' },
-                component: () => import('~src/views/authority/data.vue'),
-            },
-            {
-                path: '/authority/api-scope',
-                name: 'api_scope',
-                meta: { title: '接口权限' },
-                component: () => import('~src/views/authority/api.vue'),
-            },
-        ],
-    },
-    {
-        path: '/system',
-        name: 'system',
-        redirect: '/system/client',
-        meta: { title: '系统管理' },
-        component: Layout,
-        children: [
-            {
-                path: '/system/client',
-                name: 'client',
-                meta: { title: '应用管理' },
-                component: () => import('~src/views/system/client.vue'),
-            },
-            {
-                path: '/system/tenant',
-                name: 'tenant',
-                meta: { title: '租户管理' },
-                component: () => import('~src/views/system/tenant.vue'),
-            },
-            {
-                path: '/system/param',
-                name: 'param',
-                meta: { title: '参数管理' },
-                component: () => import('~src/views/system/param.vue'),
-            },
-            {
-                path: '/system/menu',
-                name: 'menu',
-                meta: { title: '菜单管理' },
-                component: () => import('~src/views/system/menu.vue'),
-            },
-            {
-                path: '/system/menu-top',
-                name: 'topmenu',
-                meta: { title: '顶部菜单' },
-                component: () => import('~src/views/system/menu-top.vue'),
-            },
-            {
-                path: '/system/app',
-                name: 'app',
-                meta: { title: 'App管理' },
-                component: () => import('~src/views/system/app.vue'),
-            },
-            {
-                path: '/system/user',
-                name: 'user',
-                meta: { title: '用户管理' },
-                component: () => import('~src/views/system/user.vue'),
-            },
-            {
-                path: '/system/post',
-                name: 'post',
-                meta: { title: '岗位管理' },
-                component: () => import('~src/views/system/post.vue'),
-            },
-            {
-                path: '/system/dept',
-                name: 'dept',
-                meta: { title: '机构管理' },
-                component: () => import('~src/views/system/dept.vue'),
-            },
-            {
-                path: '/system/dict',
-                name: 'dict',
-                meta: { title: '系统字典' },
-                component: () => import('~src/views/system/dict.vue'),
-            },
-            {
-                path: '/system/dictbiz',
-                name: 'dictbiz',
-                meta: { title: '业务字典' },
-                component: () => import('~src/views/system/dictbiz.vue'),
-            },
-        ],
-    },
-    {
-        path: '/resource',
-        name: 'resource',
-        redirect: '/resource/oss',
-        meta: { title: '资源管理' },
-        component: Layout,
-        children: [
-            {
-                path: '/resource/oss',
-                name: 'oss',
-                meta: { title: '对象存储' },
-                component: () => import('~src/views/resource/oss.vue'),
-            },
-            {
-                path: '/resource/attach',
-                name: 'attach',
-                meta: { title: '附件管理' },
-                component: () => import('~src/views/resource/attach.vue'),
-            },
-            {
-                path: '/resource/sms',
-                name: 'sms',
-                meta: { title: '短信配置' },
-                component: () => import('~src/views/resource/sms.vue'),
+                component: () => import('~src/views/home/datav.vue'),
             },
         ],
     },

+ 1 - 3
src/router/modules/token.js

@@ -1,4 +1,2 @@
 //内置路由需要验证的
-export default [
-    'home', 'index', 'user-info',
-]
+export default ['home', 'index']

+ 2 - 2
src/router/routers.js

@@ -1,8 +1,8 @@
+import { getStore } from "hc-vue3-ui"
 import { getArrValue } from 'js-fast-way'
-import { getStoreValue } from '~src/utils/storage'
 
 //获取路由菜单
 export const getRouterData = async (toName) => {
-    const routes = getArrValue(getStoreValue('routes'))
+    const routes = getArrValue(getStore('routes'))
     return routes.indexOf(toName) !== -1
 }

+ 7 - 38
src/store/index.js

@@ -1,66 +1,35 @@
 import { defineStore } from 'pinia'
 import pinia from '~src/store/init'
-import { clearStoreAll } from 'hc-vue3-ui'
-import { getStoreValue, setStoreValue } from '~src/utils/storage'
-import { removeRefreshToken, removeToken, setRefreshToken, setToken } from '~src/api/auth'
+import { removeToken,removeRefreshToken, clearStoreAll,setStore,getStore } from 'hc-vue3-ui'
 
 export const useAppStore = defineStore('main', {
     state: () => ({
         //用户信息
-        token: getStoreValue('token') || '',
-        refreshToken: getStoreValue('refreshToken') || '',
-        userInfo: getStoreValue('userInfo') || {},
+        userInfo: getStore('userInfo') || {},
         //菜单信息
-        menus: getStoreValue('menus') || [],
-        buttons: getStoreValue('buttons') || {},
+        menus: getStore('menus') || [],
+        buttons: getStore('buttons') || {},
     }),
-    getters: {
-        //用户信息
-        getToken: state => state.token,
-        getRefreshToken: state => state.refreshToken,
-        getTenantId: state => state.tenantId,
-        getUserInfo: state => state.userInfo,
-        //菜单信息
-        getMenus: state => state.menus,
-        getButtons: state => state.buttons,
-    },
     actions: {
         //用户信息
-        setTokenVal(value) {
-            this.token = value
-            setToken(value)
-            setStoreValue('token', value)
-        },
-        setRefreshTokenVal(value) {
-            this.refreshToken = value
-            setRefreshToken(value)
-            setStoreValue('refreshToken', value)
-        },
-        setTenantId(value) {
-            this.tenantId = value
-            setStoreValue('tenantId', value)
-        },
         setUserInfo(value) {
             this.userInfo = value
-            setStoreValue('userInfo', value)
+            setStore('userInfo', value)
         },
         //菜单信息
         setMenus(value) {
             this.menus = value
-            setStoreValue('menus', value)
+            setStore('menus', value)
         },
         setButtons(value) {
             this.buttons = value
-            setStoreValue('buttons', value)
+            setStore('buttons', value)
         },
         getButtonsVal(value) {
             return this.buttons[value] || false
         },
         //清除缓存和token
         clearStoreData() {
-            this.token = null
-            this.refreshToken = null
-            this.tenantId = null
             this.userInfo = null
             this.menus = null
             this.buttons = null

+ 2 - 2
src/store/modules/app.js

@@ -1,14 +1,14 @@
 import pinia from '~src/store/init'
 import { useAppStore } from '~src/store'
 import { getButtons } from '~api/menu'
+import { getStore } from "hc-vue3-ui"
 import { ArrToOneObj, getArrValue } from 'js-fast-way'
-import { getStoreValue } from '~src/utils/storage'
 
 const store = useAppStore(pinia)
 
 //按钮初始化
 export const initButtons = async () => {
-    const value = getStoreValue('buttons')
+    const value = getStore('buttons')
     if (!value) {
         const { error, data } = await getButtons()
         if (error) return Promise.reject('error')

+ 14 - 43
src/store/modules/user.js

@@ -1,56 +1,30 @@
 import pinia from '~src/store/init'
-import website from '~src/config/index'
 import { useAppStore } from '~src/store'
 import { getRoutes } from '~api/menu'
-import { setStoreValue } from '~src/utils/storage'
+import { setToken, getRefreshToken, setRefreshToken, setStore } from "hc-vue3-ui"
 import tokenData from '~src/router/modules/token'
 import { ArrToOneObj, getArrValue, getObjValue } from 'js-fast-way'
-import { userConfigInfo, userConfigSave } from '~api/other'
-import { logout, refreshToken, userLogin } from '~api/user'
+//import { logout, refreshToken, userLogin } from '~api/user'
 
 //初始变量
 const store = useAppStore(pinia)
 
 //登录
 export const useAppLogin = async (form) => {
-    const { error, code, res } = await userLogin(form)
+    /*const { error, code, res } = await userLogin(form)
     if (!error && code === 200) {
-        store.setTokenVal(res['access_token'])
-        store.setRefreshTokenVal(res['refresh_token'])
-        store.setTenantId(res['tenant_id'])
+        setToken(res['access_token'])
+        setRefreshToken(res['refresh_token'])
         store.setUserInfo(res)
         //获取路由菜单
         const routerRes = await setRouterData()
         if (routerRes.length <= 0) {
             return { error: true, msg: '路由异常' }
         }
-        //获取配置数据
-        await initUserConfigInfo()
         return { error, code, res }
     } else {
         return { error, code, res }
-    }
-}
-
-//用户信息初始化
-export const initUserConfigInfo = async () => {
-    const { error, data } = await userConfigInfo()
-    if (error) return false
-    const res = getObjValue(data)
-    if (res?.theme) {
-        const { theme, color } = res
-        //设置主题
-        store.setTheme(theme ?? website.theme)
-        //设置主色调
-        store.setColor(color ?? website.color)
-        return true
-    } else {
-        await userConfigSave({
-            theme: website.theme,
-            color: website.color,
-        })
-        return true
-    }
+    }*/
 }
 
 //设置路由信息
@@ -66,23 +40,20 @@ export const setRouterData = async () => {
     const routes = [...tokenData, ...routesArr] //合并
     //数据缓存
     store.setMenus(resData)
-    setStoreValue('route', routesObj)
-    setStoreValue('routes', routes)
+    setStore('route', routesObj)
+    setStore('routes', routes)
     return resData
 }
 
 //刷新token
 export const RefreshToken = async () => {
-    try {
-        window.console.log('刷新 token')
+    /*try {
         const { dept_id, role_id } = store.getUserInfo
-        const refresh = store.getRefreshToken
-        const tenantId = store.getTenantId
-        const { error, code, res } = await refreshToken(refresh, tenantId, dept_id, role_id)
+        const refresh = getRefreshToken()
+        const { error, code, res } = await refreshToken(refresh, dept_id, role_id)
         if (!error && code === 200) {
-            store.setTokenVal(res['access_token'])
-            store.setRefreshTokenVal(res['refresh_token'])
-            store.setTenantId(res['tenant_id'])
+            setToken(res['access_token'])
+            setRefreshToken(res['refresh_token'])
             store.setUserInfo(res)
             return Promise.resolve(res)
         } else {
@@ -91,7 +62,7 @@ export const RefreshToken = async () => {
     } catch (e) {
         window.console.warn('token 刷新失败: ', e)
         return Promise.reject(e)
-    }
+    }*/
 }
 
 //登出

+ 0 - 131
src/styles/home/agent-charge.scss

@@ -1,131 +0,0 @@
-.hc-agent-charge {
-    position: relative;
-    .active-menus {
-        flex: 1;
-        height: 62px;
-        display: flex;
-        background-color: #F8F8F8;
-        border-radius: 10px 10px 0 0;
-    }
-    .active-item {
-        padding: 10px;
-        display: flex;
-        cursor: pointer;
-    }
-    .active-select {
-        background-color: #FFFFFF;
-        border-radius: 10px 0 0 0 ;
-    }
-    .triangle-bottomleft {
-        width: 0;
-        height: 0;
-        border-bottom: 64px solid #F8F8F8;
-        border-right: 30px solid transparent;
-    }
-    .b-b-b-w {
-        border-bottom-color: #FFFFFF;
-    }
-    .active-body {
-        overflow: hidden;
-    }
-    .info-item{
-        position: relative;
-        padding: 10px;
-        color: #50545E;
-        margin-bottom: 10px;
-        background-color: #F8FAFF;
-        border: 1px solid #EEEEEE;
-        border-radius: 10px;
-        .frame-warning {
-            position: absolute;
-            top: 0;
-            left: 10px;
-            bottom: 0;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-        }
-        .frame-content {
-            position: relative;
-            font-size: 14px;
-            padding-left: 24px;
-            width: calc(100% - 220px);
-            line-height: 1.5;
-            .title-common{
-                color: #838791;
-            }
-            .title-text{
-                color: #50545E;
-            }
-            .title-red{
-                margin-left: 6px;
-                color: #EB4D3D;
-            }
-        }
-        .frame-time {
-            position: absolute;
-            top: 0;
-            bottom: 0;
-            right: 10px;
-            color: #838791;
-            font-size: 14px;
-            display: flex;
-            align-items: center;
-        }
-        .frame-time.is-more {
-            margin-right: 20px;
-        }
-        .frame-more {
-            position: absolute;
-            top: 0;
-            bottom: 0;
-            right: 5px;
-            display: flex;
-            align-items: center;
-            .more-icon {
-                color: #838791;
-                font-size: 20px;
-            }
-        }
-    }
-    .border-bottom-10 {
-        border-radius: 0 0 10px 10px;
-    }
-}
-
-.hc-agent-charge .active-body {
-    .hc-no-data-box .no-data-c {
-        width: 200px;
-    }
-    .el-scrollbar__bar.is-vertical {
-        right: -9px;
-    }
-}
-
-.hc-agent-charge-new-table {
-    border-spacing: 0;
-    border-collapse: collapse;
-    border-color: #dddddd;
-    width: 100%;
-    .new-titile{
-        text-align:center;
-        width:120px;
-        padding: 10px;
-        background-color: #F8F8F8;
-        color: #838791;
-    }
-    .new-content{
-        text-align:left;
-        padding: 10px;
-        color: #50545E;
-    }
-    .new-content .new-img {
-        width: 100px;
-        height: 100px;
-        border-radius: 4px;
-        position: absolute;
-        background-color: rgba(0,0,0,0.3);
-        z-index:99;
-        pointer-events: none;
-    }
-}

+ 0 - 28
src/styles/home/home.scss

@@ -1,28 +0,0 @@
-.hc-home-chart-body {
-    .chart-title {
-        display: flex;
-        font-weight: 700;
-        font-size: 16px;
-        color: #1A1A1A;
-        img {
-            width: 44px;
-            height: 44px;
-        }
-        .title-body {
-            line-height: 2.1;
-            .text {
-                margin-left: 5px;
-                font-size: 14px;
-                color: #838791;
-            }
-        }
-    }
-    .chart-select {
-        margin-top: -10px;
-        width: 200px;
-        .el-input__wrapper {
-            background-color: #F7F9FD;
-            border-radius: 64px;
-        }
-    }
-}

+ 0 - 1
src/styles/index.scss

@@ -1,3 +1,2 @@
 @import './app/main';
 @import './app/element';
-@import './app/theme';

+ 0 - 0
src/styles/view/config.scss


+ 0 - 0
src/styles/user/index.scss → src/styles/view/datav.scss


+ 0 - 0
src/styles/view/home.scss


+ 0 - 81
src/styles/view/login.dark.scss

@@ -1,81 +0,0 @@
-html.dark {
-    .login-body {
-        color-scheme: light;
-        --el-input-text-color: #000000;
-        --el-color-white: #ffffff;
-        --el-color-black: #000000;
-        --el-color-success: #67c23a;
-        --el-color-success-light-3: #95d475;
-        --el-color-success-light-5: #b3e19d;
-        --el-color-success-light-7: #d1edc4;
-        --el-color-success-light-8: #e1f3d8;
-        --el-color-success-light-9: #f0f9eb;
-        --el-color-success-dark-2: #529b2e;
-        --el-color-warning: #e6a23c;
-        --el-color-warning-light-3: #eebe77;
-        --el-color-warning-light-5: #f3d19e;
-        --el-color-warning-light-7: #f8e3c5;
-        --el-color-warning-light-8: #faecd8;
-        --el-color-warning-light-9: #fdf6ec;
-        --el-color-warning-dark-2: #b88230;
-        --el-color-danger: #f56c6c;
-        --el-color-danger-light-3: #f89898;
-        --el-color-danger-light-5: #fab6b6;
-        --el-color-danger-light-7: #fcd3d3;
-        --el-color-danger-light-8: #fde2e2;
-        --el-color-danger-light-9: #fef0f0;
-        --el-color-danger-dark-2: #c45656;
-        --el-color-error: #f56c6c;
-        --el-color-error-light-3: #f89898;
-        --el-color-error-light-5: #fab6b6;
-        --el-color-error-light-7: #fcd3d3;
-        --el-color-error-light-8: #fde2e2;
-        --el-color-error-light-9: #fef0f0;
-        --el-color-error-dark-2: #c45656;
-        --el-color-info: #909399;
-        --el-color-info-light-3: #b1b3b8;
-        --el-color-info-light-5: #c8c9cc;
-        --el-color-info-light-7: #dedfe0;
-        --el-color-info-light-8: #e9e9eb;
-        --el-color-info-light-9: #f4f4f5;
-        --el-color-info-dark-2: #73767a;
-        --el-bg-color: #ffffff;
-        --el-bg-color-page: #f2f3f5;
-        --el-bg-color-overlay: #ffffff;
-        --el-text-color-primary: #303133;
-        --el-text-color-regular: #606266;
-        --el-text-color-secondary: #909399;
-        --el-text-color-placeholder: #a8abb2;
-        --el-text-color-disabled: #c0c4cc;
-        --el-border-color: #dcdfe6;
-        --el-border-color-light: #e4e7ed;
-        --el-border-color-lighter: #ebeef5;
-        --el-border-color-extra-light: #f2f6fc;
-        --el-border-color-dark: #d4d7de;
-        --el-border-color-darker: #cdd0d6;
-        --el-fill-color: #f0f2f5;
-        --el-fill-color-light: #f5f7fa;
-        --el-fill-color-lighter: #fafafa;
-        --el-fill-color-extra-light: #fafcff;
-        --el-fill-color-dark: #ebedf0;
-        --el-fill-color-darker: #e6e8eb;
-        --el-fill-color-blank: #ffffff;
-        --el-box-shadow: 0px 12px 32px 4px rgba(0, 0, 0, 0.04),0px 8px 20px rgba(0, 0, 0, 0.08);
-        --el-box-shadow-light: 0px 0px 12px rgba(0, 0, 0, 0.12);
-        --el-box-shadow-lighter: 0px 0px 6px rgba(0, 0, 0, 0.12);
-        --el-box-shadow-dark: 0px 16px 48px 16px rgba(0, 0, 0, 0.08),0px 12px 32px rgba(0, 0, 0, 0.12),0px 8px 16px -8px rgba(0, 0, 0, 0.16);
-        --el-disabled-bg-color: var(--el-fill-color-light);
-        --el-disabled-text-color: var(--el-text-color-placeholder);
-        --el-disabled-border-color: var(--el-border-color-light);
-        --el-overlay-color: rgba(0, 0, 0, 0.8);
-        --el-overlay-color-light: rgba(0, 0, 0, 0.7);
-        --el-overlay-color-lighter: rgba(0, 0, 0, 0.5);
-        --el-mask-color: rgba(255, 255, 255, 0.9);
-        --el-mask-color-extra-light: rgba(255, 255, 255, 0.3);
-        --el-border-width: 1px;
-        --el-border-style: solid;
-        --el-border-color-hover: var(--el-text-color-disabled);
-        --el-border: var(--el-border-width) var(--el-border-style) var(--el-border-color);
-        --el-svg-monochrome-grey: var(--el-border-color);
-    }
-}

+ 0 - 132
src/styles/view/login.scss

@@ -1,135 +1,3 @@
 .login-body {
-    position: relative;
-    background-color: #F0FBFF;
-    width: 100%;
-    height: 100vh;
-    padding: 50px 0;
-    min-height: 730px;
-    .left-logo {
-        position: absolute;
-        left: 30px;
-        top: 30px;
-        user-select: none;
-        color: #1ECC95;
-        text-decoration: none;
-        display: flex;
-        align-items: center;
-        img {
-            height: 40px;
-        }
-        #logo-icon {
-            height: 36px;
-        }
-        .logo-name {
-            font-size: 28px;
-            margin-left: 4px;
-        }
-    }
-    .left-pic-container {
-        position: absolute;
-        width: 750px;
-        left: 10%;
-        top: 50%;
-        height: 630px;
-        margin-top: -315px;
 
-    }
-    .right-container {
-        right: 18.667%;
-        position: absolute;
-        background: #ffffff;
-        border-radius: 16px;
-        transform: translateY(-50%);
-        padding: 50px;
-        width: 92%;
-        top: 54%;
-        max-width: 470px;
-        margin: 0 auto;
-        box-shadow: 0 21.2px 31.8px 0 rgba(26,26,26,0.12);
-        .right-app-title {
-            position: absolute;
-            top: -80px;
-            left: 18px;
-            font-size: 43px;
-            font-weight: 400;
-            color: #1ECC95;
-        }
-        .sign-list {
-            position: relative;
-            h1 {
-                font-size: 40px;
-                line-height: 48px;
-                margin-bottom: 32px;
-            }
-            .title-tab {
-                overflow: hidden;
-                padding-bottom: 16px;
-                div {
-                    float: left;
-                    line-height: 32px;
-                    font-size: 20px;
-                    color: #8C8889;
-                    transition: 0.3s;
-                    position: relative;
-                    padding-top: 16px;
-                    margin-left: 32px;
-                    user-select: none;
-                    &::before {
-                        content: '';
-                        width: 0;
-                        height: 2px;
-                        position: absolute;
-                        left: 50%;
-                        transform: translateX(-50%);
-                        bottom: 0;
-                        background: #1ECC95;
-                        border-radius: 3px;
-                        transition: 0.3s;
-                    }
-                    &:first-child {
-                        margin-left: 0;
-                    }
-                    &:not(.active) {
-                        cursor: pointer;
-                    }
-                    &.active {
-                        color: #353030;
-                        font-weight: bold;
-                        &::before {
-                            width: 100%;
-                        }
-                    }
-                }
-            }
-            .form-box {
-                position: relative;
-                .el-input--large {
-                    --el-input-height: 48px;
-                    --el-input-border-radius: 8px;
-                    font-size: 16px;
-                    .el-input__wrapper {
-                        padding: 1px 16px;
-                    }
-                }
-                .clickable-text {
-                    color: #686565;
-                    cursor: pointer;
-                    transition: 0.2s;
-                    font-size: 14px;
-                    &:hover {
-                        color: #1ECC95
-                    }
-                }
-                .el-button--large {
-                    --el-button-size: 48px;
-                    height: 48px;
-                    padding: 12px 19px;
-                    font-size: 16px;
-                    border: 0;
-                    border-radius: 6px;
-                    background: linear-gradient(90deg,#1fd4af, #1ecc95 100%);
-                }
-            }
-        }
-    }
 }

+ 0 - 133
src/views/authority/api.vue

@@ -1,133 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-40">
-                <el-select v-model="searchForm.sysId" filterable clearable block placeholder="选择所属系统">
-                    <el-option v-for="item in clinets" :key="item.id" :label="item.name" :value="item.id" />
-                </el-select>
-            </div>
-            <div class="ml-3 w-60">
-                <hc-search-input v-model="searchForm.name" placeholder="请输入菜单名称" @search="searchClick" />
-            </div>
-        </template>
-        <hc-table :column="tableColumn" :datas="tableData" :loading="tableLoading" :is-index="false"  lazy :load="tableLoad">
-            <template #sysId="{ row }">{{ getSystemNmae(row.sysId) }}</template>
-            <template #action="{ row }">
-                <el-link type="primary" @click="authRowClick(row)">权限配置</el-link>
-            </template>
-        </hc-table>
-
-        <!-- 权限配置 -->
-        <HcApiAuth v-model="isDataAuthShow" :mid="rowAuthInfo.id" :title="rowAuthInfo.name" @close="dataAuthClose" />
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { useRoute, useRouter } from 'vue-router'
-import { getArrValue, getObjValue } from 'js-fast-way'
-import HcApiAuth from './modules/api/auth.vue'
-import { getClinetAll } from '~api/other'
-import menuApi from '~api/system/menu'
-
-//初始组合式
-const router = useRouter()
-const useRoutes = useRoute()
-
-defineOptions({
-    name: 'ApiScope',
-})
-
-//激活
-onActivated(() => {
-//获取参数
-    const { sysId, name } = getObjValue(useRoutes.query)
-    searchForm.value = { sysId: sysId, name: name }
-    //获取数据
-    getClinetAllApi()
-    getTableData()
-})
-
-//获取所有系统
-const clinets = ref([])
-const getClinetAllApi = async () => {
-    const { data } = await getClinetAll()
-    clinets.value = getArrValue(data)
-}
-
-//获取系统名称
-const getSystemNmae = (id) => {
-    const item = clinets.value.find((item) => item.id === id)
-    return item ? item.name : ''
-}
-
-//搜索表单
-const searchForm = ref({ sysId: null, name: null })
-
-//搜索
-const searchClick = () => {
-    router.push({
-        name: 'api_scope',
-        query: searchForm.value,
-    })
-    getTableData()
-}
-
-//表格数据
-const tableColumn = ref([
-    { key: 'name', name: '菜单名称' },
-    { key: 'sysId', name: '所属系统' },
-    { key: 'path', name: '路由地址' },
-    { key: 'code', name: '菜单编号' },
-    { key: 'sort', name: '排序', width: 80, align: 'center' },
-    { key: 'action', name: '操作', width: 90, align: 'center' },
-])
-const tableData = ref([])
-
-//获取表格数据
-const tableLoading = ref(true)
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    tableData.value = await getLazyList(0)
-    tableLoading.value = false
-}
-
-//懒加载表格
-const tableLoad = async (row, node, resolve) => {
-    resolve(await getLazyList(row.id))
-}
-
-//获取表格数据
-const getLazyList = async (id) => {
-    let newArr = []
-    const { data } = await menuApi.getLazyList({
-        ...searchForm.value,
-        parentId: id,
-    })
-    //处理数据
-    const res = getArrValue(data)
-    for (let i = 0; i < res.length; i++) {
-        if (res[i].category === 1) {
-            newArr.push(res[i])
-        }
-    }
-    return newArr
-}
-
-//数据权限配置
-const isDataAuthShow = ref(false)
-const rowAuthInfo = ref({})
-const authRowClick = (row) => {
-    rowAuthInfo.value = row
-    nextTick(() => {
-        isDataAuthShow.value = true
-    })
-}
-
-//关闭权限配置弹窗
-const dataAuthClose = () => {
-    isDataAuthShow.value = false
-    rowAuthInfo.value = {}
-}
-</script>

+ 0 - 133
src/views/authority/data.vue

@@ -1,133 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-40">
-                <el-select v-model="searchForm.sysId" filterable clearable block placeholder="选择所属系统">
-                    <el-option v-for="item in clinets" :key="item.id" :label="item.name" :value="item.id" />
-                </el-select>
-            </div>
-            <div class="ml-3 w-60">
-                <hc-search-input v-model="searchForm.name" placeholder="请输入菜单名称" @search="searchClick" />
-            </div>
-        </template>
-        <hc-table :column="tableColumn" :datas="tableData" :loading="tableLoading" :is-index="false"  lazy :load="tableLoad">
-            <template #sysId="{ row }">{{ getSystemNmae(row.sysId) }}</template>
-            <template #action="{ row }">
-                <el-link type="primary" @click="authRowClick(row)">权限配置</el-link>
-            </template>
-        </hc-table>
-
-        <!-- 权限配置 -->
-        <HcDataAuth v-model="isDataAuthShow" :mid="rowAuthInfo.id" :title="rowAuthInfo.name" @close="dataAuthClose" />
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { useRoute, useRouter } from 'vue-router'
-import { getArrValue, getObjValue } from 'js-fast-way'
-import HcDataAuth from './modules/data/auth.vue'
-import { getClinetAll } from '~api/other'
-import menuApi from '~api/system/menu'
-
-//初始组合式
-const router = useRouter()
-const useRoutes = useRoute()
-
-defineOptions({
-    name: 'DataScope',
-})
-
-//激活
-onActivated(() => {
-//获取参数
-    const { sysId, name } = getObjValue(useRoutes.query)
-    searchForm.value = { sysId: sysId, name: name }
-    //获取数据
-    getClinetAllApi()
-    getTableData()
-})
-
-//获取所有系统
-const clinets = ref([])
-const getClinetAllApi = async () => {
-    const { data } = await getClinetAll()
-    clinets.value = getArrValue(data)
-}
-
-//获取系统名称
-const getSystemNmae = (id) => {
-    const item = clinets.value.find((item) => item.id === id)
-    return item ? item.name : ''
-}
-
-//搜索表单
-const searchForm = ref({ sysId: null, name: null })
-
-//搜索
-const searchClick = () => {
-    router.push({
-        name: 'data_scope',
-        query: searchForm.value,
-    })
-    getTableData()
-}
-
-//表格数据
-const tableColumn = ref([
-    { key: 'name', name: '菜单名称' },
-    { key: 'sysId', name: '所属系统' },
-    { key: 'path', name: '路由地址' },
-    { key: 'code', name: '菜单编号' },
-    { key: 'sort', name: '排序', width: 80, align: 'center' },
-    { key: 'action', name: '操作', width: 90, align: 'center' },
-])
-const tableData = ref([])
-
-//获取表格数据
-const tableLoading = ref(true)
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    tableData.value = await getLazyList(0)
-    tableLoading.value = false
-}
-
-//懒加载表格
-const tableLoad = async (row, node, resolve) => {
-    resolve(await getLazyList(row.id))
-}
-
-//获取表格数据
-const getLazyList = async (id) => {
-    let newArr = []
-    const { data } = await menuApi.getLazyList({
-        ...searchForm.value,
-        parentId: id,
-    })
-    //处理数据
-    const res = getArrValue(data)
-    for (let i = 0; i < res.length; i++) {
-        if (res[i].category === 1) {
-            newArr.push(res[i])
-        }
-    }
-    return newArr
-}
-
-//数据权限配置
-const isDataAuthShow = ref(false)
-const rowAuthInfo = ref({})
-const authRowClick = (row) => {
-    rowAuthInfo.value = row
-    nextTick(() => {
-        isDataAuthShow.value = true
-    })
-}
-
-//关闭权限配置弹窗
-const dataAuthClose = () => {
-    isDataAuthShow.value = false
-    rowAuthInfo.value = {}
-}
-</script>

+ 0 - 305
src/views/authority/modules/api/auth.vue

@@ -1,305 +0,0 @@
-<template>
-    <div>
-        <hc-dialog v-model="isShow" widths="90%" :padding="false" :title="`[${menuTitle}] 数据权限配置`" is-table :footer="false" @close="dialogClose">
-            <hc-card>
-                <template #header>
-                    <div class="w-60">
-                        <hc-search-input v-model="searchForm.scopeName" placeholder="请输入权限名称" @search="searchClick" />
-                    </div>
-                </template>
-                <template #extra>
-                    <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-                    <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-                </template>
-                <hc-table
-                    :column="tableColumn" :datas="tableData" :loading="tableLoading"
-                    :is-index="false"  is-check :check-style="{ width: 29 }"
-                    @selection-change="tableCheckChange"
-                >
-                    <template #scopeType="{ row }">{{ getScopeTypeName(row) }}</template>
-                    <template #action="{ row }">
-                        <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                        <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-                    </template>
-                </hc-table>
-                <template #action>
-                    <hc-pages :pages="searchForm" @change="pageChange" />
-                </template>
-            </hc-card>
-        </hc-dialog>
-        <!-- 新增/修改 -->
-        <hc-dialog v-model="isDialogShow" widths="50rem" is-footer-center :title="dialogTitle" @close="dialogFormClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-row :gutter="20">
-                    <el-col :span="12">
-                        <el-form-item label="权限名称:" prop="scopeName">
-                            <el-input v-model="formModel.scopeName" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="权限编号:" prop="resourceCode">
-                            <el-input v-model="formModel.resourceCode" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="权限路径:" prop="scopePath">
-                            <el-input v-model="formModel.scopePath" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="接口类型:" prop="scopeType">
-                            <el-select v-model="searchForm.scopeType" placeholder="选择规则类型" filterable clearable block>
-                                <el-option v-for="item in scopeTypeData" :key="item.value" :label="item.label" :value="item.value" />
-                            </el-select>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="24">
-                        <el-form-item label="备注说明:">
-                            <el-input v-model="formModel.remark" clearable />
-                        </el-form-item>
-                    </el-col>
-                </el-row>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-    </div>
-</template>
-
-<script setup>
-import { nextTick, ref, watch } from 'vue'
-import { arrToId, formValidate, getArrValue, isNullES } from 'js-fast-way'
-import { getDictionaryData } from '~uti/tools'
-import { HcDelMsg } from 'hc-vue3-ui'
-import mainApi from '~api/authority/api'
-
-const props = defineProps({
-    mid: {
-        type: [String, Number],
-        default: '',
-    },
-    title: {
-        type: [String, Number],
-        default: '',
-    },
-})
-
-//事件
-const emit = defineEmits(['close'])
-
-//双向绑定
-const isShow = defineModel('modelValue', {
-    default: false,
-})
-
-//监听内容
-const menuId = ref(props.mid)
-const menuTitle = ref(props.title)
-watch(() =>[props.mid, props.title], ([id, title]) => {
-    menuId.value = id
-    menuTitle.value = title
-}, { immediate: true, deep: true })
-
-//监听显示
-watch(isShow, (val) => {
-    if (val) {
-        getDataApi()
-    }
-})
-
-//获取数据
-const getDataApi = () => {
-    if (isNullES(menuId.value)) return
-    searchForm.value.menuId = menuId.value
-    getScopeTypeData()
-    searchClick()
-}
-
-//获取字典数据
-const scopeTypeData = ref([])
-const getScopeTypeData = async () => {
-    scopeTypeData.value = await getDictionaryData('api_scope_type')
-}
-const getScopeTypeName = ({ scopeType }) => {
-    if (isNullES(scopeType)) return '-'
-    const item = scopeTypeData.value.find((item) => item.value === scopeType)
-    if (isNullES(item)) return scopeType
-    return item.label ?? scopeType
-}
-
-//搜索表单
-const searchForm = ref({
-    scopeName: null, menuId: '',
-    current: 1, size: 30, total: 0,
-})
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableColumn = ref([
-    { key: 'scopeName', name: '权限名称' },
-    { key: 'resourceCode', name: '权限编号' },
-    { key: 'scopePath', name: '权限路径' },
-    { key: 'scopeType', name: '接口类型' },
-    { key: 'remark', name: '备注' },
-    { key: 'action', name: '操作', width: 90, align: 'center' },
-])
-const tableData = ref([])
-
-//获取表格数据
-const tableLoading = ref(true)
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { error, code, data } = await mainApi.page({
-        ...searchForm.value,
-        total: null,
-    })
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const dialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    scopeName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入权限名称',
-    },
-    resourceCode: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入权限编号',
-    },
-    scopePath: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入权限路径',
-    },
-    scopeType: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择接口类型',
-    },
-}
-
-
-//新增
-const addClick = () => {
-    dialogTitle.value = '新增接口权限'
-    formModel.value = { }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改菜单
-const editRowClick = (row) => {
-    formModel.value = {}
-    dialogTitle.value = '修改接口权限'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogFormClose()
-        window?.$message?.success('操作成功')
-        getTableData().then()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogFormClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-
-//删除
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的数据')
-        return false
-    }
-    //确认删除菜单
-    HcDelMsg(async (resolve) => {
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        resolve() //关闭弹窗的回调
-        if (code === 200) {
-            window.$message.success('删除成功')
-            getTableData().then()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isShow.value = false
-    emit('close')
-}
-</script>

+ 0 - 336
src/views/authority/modules/data/auth.vue

@@ -1,336 +0,0 @@
-<template>
-    <div>
-        <hc-dialog v-model="isShow" widths="90%" :padding="false" :title="`[${menuTitle}] 数据权限配置`" is-table :footer="false" @close="dialogClose">
-            <hc-card>
-                <template #header>
-                    <div class="w-60">
-                        <hc-search-input v-model="searchForm.scopeName" placeholder="请输入权限名称" @search="searchClick" />
-                    </div>
-                </template>
-                <template #extra>
-                    <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-                    <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-                </template>
-                <hc-table
-                    :column="tableColumn" :datas="tableData" :loading="tableLoading"
-                    :is-index="false"  is-check :check-style="{ width: 29 }"
-                    @selection-change="tableCheckChange"
-                >
-                    <template #scopeType="{ row }">{{ getScopeTypeName(row) }}</template>
-                    <template #action="{ row }">
-                        <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                        <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-                    </template>
-                </hc-table>
-                <template #action>
-                    <hc-pages :pages="searchForm" @change="pageChange" />
-                </template>
-            </hc-card>
-        </hc-dialog>
-        <!-- 新增/修改 -->
-        <hc-dialog v-model="isDialogShow" widths="50rem" is-footer-center :title="dialogTitle" @close="dialogFormClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-row :gutter="20">
-                    <el-col :span="12">
-                        <el-form-item label="权限名称:" prop="scopeName">
-                            <el-input v-model="formModel.scopeName" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="权限编号:" prop="resourceCode">
-                            <el-input v-model="formModel.resourceCode" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="权限字段:" prop="scopeColumn">
-                            <el-input v-model="formModel.scopeColumn" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="规则类型:" prop="scopeType">
-                            <el-select v-model="searchForm.scopeType" placeholder="选择规则类型" filterable clearable block>
-                                <el-option v-for="item in scopeTypeData" :key="item.value" :label="item.label" :value="item.value" />
-                            </el-select>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="可见字段:" prop="scopeField">
-                            <el-input v-model="formModel.scopeField" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="权限类名:" prop="scopeClass">
-                            <el-input v-model="formModel.scopeClass" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-if="searchForm.scopeType === 5" :span="24">
-                        <el-form-item label="规则值:">
-                            <el-input v-model="formModel.scopeValue" :autosize="{ minRows: 5, maxRows: 5 }" type="textarea" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="24">
-                        <el-form-item label="备注说明:">
-                            <el-input v-model="formModel.remark" clearable />
-                        </el-form-item>
-                    </el-col>
-                </el-row>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-    </div>
-</template>
-
-<script setup>
-import { nextTick, ref, watch } from 'vue'
-import { arrToId, formValidate, getArrValue, isNullES } from 'js-fast-way'
-import { getDictionaryData } from '~uti/tools'
-import { HcDelMsg } from 'hc-vue3-ui'
-import mainApi from '~api/authority/data'
-
-const props = defineProps({
-    mid: {
-        type: [String, Number],
-        default: '',
-    },
-    title: {
-        type: [String, Number],
-        default: '',
-    },
-})
-
-//事件
-const emit = defineEmits(['close'])
-
-//双向绑定
-const isShow = defineModel('modelValue', {
-    default: false,
-})
-
-//监听内容
-const menuId = ref(props.mid)
-const menuTitle = ref(props.title)
-watch(() =>[props.mid, props.title], ([id, title]) => {
-    menuId.value = id
-    menuTitle.value = title
-}, { immediate: true, deep: true })
-
-//监听显示
-watch(isShow, (val) => {
-    if (val) {
-        getDataApi()
-    }
-})
-
-//获取数据
-const getDataApi = () => {
-    if (isNullES(menuId.value)) return
-    searchForm.value.menuId = menuId.value
-    getScopeTypeData()
-    searchClick()
-}
-
-//获取字典数据
-const scopeTypeData = ref([])
-const getScopeTypeData = async () => {
-    scopeTypeData.value = await getDictionaryData('data_scope_type')
-}
-const getScopeTypeName = ({ scopeType }) => {
-    if (isNullES(scopeType)) return '-'
-    const item = scopeTypeData.value.find((item) => item.value === scopeType)
-    if (isNullES(item)) return scopeType
-    return item.label ?? scopeType
-}
-
-//搜索表单
-const searchForm = ref({
-    scopeName: null, menuId: '',
-    current: 1, size: 30, total: 0,
-})
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableColumn = ref([
-    { key: 'scopeName', name: '权限名称' },
-    { key: 'resourceCode', name: '权限编号' },
-    { key: 'scopeColumn', name: '权限字段' },
-    { key: 'scopeType', name: '规则类型' },
-    { key: 'scopeField', name: '可见字段' },
-    { key: 'scopeClass', name: '权限类名' },
-    { key: 'scopeValue', name: '规则值' },
-    { key: 'remark', name: '备注' },
-    { key: 'action', name: '操作', width: 90, align: 'center' },
-])
-const tableData = ref([])
-
-//获取表格数据
-const tableLoading = ref(true)
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { error, code, data } = await mainApi.page({
-        ...searchForm.value,
-        total: null,
-    })
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const dialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    scopeName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入权限名称',
-    },
-    resourceCode: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入数据权限编号',
-    },
-    scopeColumn: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入数据权限编号',
-    },
-    scopeType: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择规则类型',
-    },
-    scopeField: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入数据权限可见的字段',
-    },
-    scopeClass: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入MybatisMapper对应方法的完整类名路径',
-    },
-}
-
-
-//新增
-const addClick = () => {
-    dialogTitle.value = '新增数据权限'
-    formModel.value = {}
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改菜单
-const editRowClick = (row) => {
-    formModel.value = {}
-    dialogTitle.value = '修改数据权限'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogFormClose()
-        window?.$message?.success('操作成功')
-        getTableData().then()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogFormClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-
-//删除
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的数据')
-        return false
-    }
-    //确认删除菜单
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            getTableData().then()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isShow.value = false
-    emit('close')
-}
-</script>

+ 0 - 186
src/views/authority/modules/role/auth.vue

@@ -1,186 +0,0 @@
-<template>
-    <hc-dialog v-model="isShow" widths="800px" :padding="false" title="角色权限配置" is-table is-footer-center @close="dialogClose">
-        <el-tabs tab-position="left" class="hc-role-auth-dialog h-full w-full">
-            <template v-for="(item, index) in tabPaneData" :key="index">
-                <el-tab-pane :label="item.name">
-                    <hc-data-tree
-                        :ref="(el) => setTreeRefs(el, item)" tree-key="id" :h-props="treeProps"
-                        show-checkbox :datas="authTree[item.key]" :default-checked-keys="roleData[item.key]"
-                    />
-                </el-tab-pane>
-            </template>
-        </el-tabs>
-        <template #footer>
-            <el-button hc-btn @click="dialogClose">取消</el-button>
-            <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-        </template>
-    </hc-dialog>
-</template>
-
-<script setup>
-import { ref, watch } from 'vue'
-import { arrIndex, getArrValue, getObjValue, isNullES } from 'js-fast-way'
-import mainApi from '~api/authority/role'
-
-const props = defineProps({
-    info: {
-        type: Object,
-        default: () => ({}),
-    },
-})
-
-//事件
-const emit = defineEmits(['close'])
-
-//双向绑定
-const isShow = defineModel('modelValue', {
-    default: false,
-})
-
-//监听内容
-const rowInfo = ref(props.info)
-watch(() => props.info, (data) => {
-    rowInfo.value = data
-}, { immediate: true, deep: true })
-
-//监听显示
-watch(isShow, (val) => {
-    if (val) {
-        getDataApi()
-    }
-})
-
-//权限列表
-const tabPaneData = ref([
-    { key: 'menu', name: '后台管理', form: 'menuIds' },
-    { key: 'usermenu', name: '质检试验', form: 'menuClientIds' },
-    { key: 'archivesMenu', name: '档案管理', form: 'menuArchivesIds' },
-    { key: 'larMenu', name: '征拆管理', form: 'menularIds' },
-    { key: 'measureMenu', name: '计量支付', form: 'menuMeasureIds' },
-    { key: 'hacMenu', name: '内控系统', form: 'menuHacIds' },
-    { key: 'tableOwners', name: '表单权限', form: 'tableOwners' },
-    { key: 'dataScope', name: '数据权限', form: 'dataScopeIds' },
-    { key: 'apiScope', name: '接口权限', form: 'apiScopeIds' },
-])
-
-//获取数据
-const getDataApi = () => {
-    const { id } = rowInfo.value
-    if (isNullES(id)) return
-    getGrantTree()
-    getRoleData(id)
-}
-
-//设置权限树的属性
-const treeProps = {
-    label: 'title',
-    children: 'children',
-}
-const treeRefs = ref([])
-const setTreeRefs = (el, { key }) => {
-    if (!el) return
-    let index = arrIndex(treeRefs.value, 'id', key)
-    if (index !== -1) {
-        treeRefs.value[index].ref = el
-    } else {
-        treeRefs.value.push({ id: key, ref: el })
-    }
-}
-const getTreeRef = async (key) => {
-    const itemRef = getArrValue(treeRefs.value)
-    if (itemRef.length <= 0) return ''
-    const index = arrIndex(itemRef, 'id', key)
-    if (index === -1) return ''
-    const obj = getObjValue(itemRef[index])
-    return obj?.ref
-}
-
-
-//获取权限树的数据
-const authTree = ref({})
-const getGrantTree = async () => {
-    const { data } = await mainApi.grantTree()
-    authTree.value = getObjValue(data)
-}
-
-//获取选中的数据
-const roleData = ref({})
-const getRoleData = async (id) => {
-    const { data } = await mainApi.getRole(id)
-    const res = getObjValue(data)
-    let newObjData = {}
-    Object.keys(res).forEach((key) => {
-        newObjData[key] = []
-        const arr = getArrValue(res[key])
-        for (let i = 0; i < arr.length; i++) {
-            let strs = arr[i].split('---')
-            if (strs[1] === 'all') {
-                newObjData[key].push(strs[0])
-            }
-        }
-    })
-    roleData.value = newObjData
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    submitLoading.value = true
-    const paneData = tabPaneData.value
-    let newObjData = { roleIds: [rowInfo.value.id] }
-    for (let i = 0; i < paneData.length; i++) {
-        const item = paneData[i]
-        newObjData[item.form] = []
-        const refs = await getTreeRef(item.key)
-        const all = refs?.getRef()?.getCheckedKeys()
-        const half = refs?.getRef()?.getHalfCheckedKeys()
-        for (let j = 0; j < all.length; j++) {
-            newObjData[item.form].push(all[j] + '---all')
-        }
-        for (let j = 0; j < half.length; j++) {
-            newObjData[item.form].push(half[j] + '---all')
-        }
-    }
-    //发起请求
-    const { error, code, msg } = await mainApi.grant(newObjData)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        getDataApi()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isShow.value = false
-    submitLoading.value = false
-    emit('close')
-}
-</script>
-
-<style lang="scss">
-.el-tabs.el-tabs--left.hc-role-auth-dialog {
-    position: relative;
-    .el-tabs__header.is-left {
-        margin-right: 0;
-    }
-    .el-tabs__content {
-        position: relative;
-        height: 100%;
-        .el-tab-pane {
-            position: relative;
-            height: 100%;
-            width: 100%;
-            overflow: auto;
-            .el-tree.hc-tree-node-v2 .data-custom-tree-node .label.level-name,
-            .hc-tree-node .data-custom-tree-node .label.level-name {
-                font-size: 16px;
-                font-weight: initial;
-            }
-        }
-    }
-}
-</style>

+ 0 - 293
src/views/authority/role.vue

@@ -1,293 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-40">
-                <el-select v-model="searchForm.tenantId" placeholder="选择所属租户" filterable clearable block>
-                    <el-option v-for="item in tenantData" :key="item.tenantId" :label="item.name" :value="item.tenantId" />
-                </el-select>
-            </div>
-            <div class="ml-2 w-64">
-                <hc-search-input v-model="searchForm.roleName" placeholder="请输入角色名称关键词" @search="searchClick" />
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-            <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-        </template>
-        <hc-table
-            :column="tableColumn" :datas="tableData" :loading="tableLoading"
-            :is-index="false"  is-check :check-style="{ width: 29 }" is-children
-            @selection-change="tableCheckChange"
-        >
-            <template #tenantId="{ row }">{{ getTenantName(row) }}</template>
-            <template #action="{ row }">
-                <el-link type="primary" @click="authRowClick(row)">权限设置</el-link>
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link type="success" @click="addRowClick(row)">添加</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-
-        <!-- 新增/修改 -->
-        <hc-dialog v-model="isDialogShow" widths="400px" is-footer-center :title="iconDialogTitle" @close="dialogClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-form-item label="角色名称:" prop="roleName">
-                    <el-input v-model="formModel.roleName" clearable />
-                </el-form-item>
-                <el-form-item label="角色别名:" prop="roleAlias">
-                    <el-input v-model="formModel.roleAlias" clearable />
-                </el-form-item>
-                <el-form-item label="上级角色:">
-                    <el-tree-select
-                        v-model="formModel.parentId" :disabled="isChildForm" :data="levelData" :props="levelDataProps"
-                        clearable filterable check-strictly block :render-after-expand="false"
-                    />
-                </el-form-item>
-                <el-form-item label="角色排序:" prop="sort">
-                    <el-input-number v-model="formModel.sort" :min="1" block controls-position="right" />
-                </el-form-item>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-        <!-- 权限配置 -->
-        <HcRoleAuth v-model="isRoleAuthShow" :info="roleAuthRow" @close="roleAuthClose" />
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { arrToId, formValidate, getArrValue, isNullES } from 'js-fast-way'
-import { HcDelMsg } from 'hc-vue3-ui'
-import HcRoleAuth from './modules/role/auth.vue'
-import tenantApi from '~api/system/tenant'
-import mainApi from '~api/authority/role'
-
-defineOptions({
-    name: 'Role',
-})
-
-//激活
-onActivated(() => {
-    getDataApi()
-})
-
-const getDataApi = async () => {
-    await getTenantData()
-    searchClick()
-}
-
-//搜索表单
-const searchForm = ref({ tenantId: null, roleName: '' })
-
-//所属租户
-const tenantData = ref([])
-const getTenantData = async () => {
-    let newArr = []
-    const { data } = await tenantApi.getSelect()
-    const res = getArrValue(data)
-    for (let i = 0; i < res.length; i++) {
-        newArr.push({
-            id: res[i]['id'],
-            name: res[i]['tenantName'],
-            tenantId: res[i]['tenantId'],
-        })
-    }
-    tenantData.value = newArr
-}
-const getTenantName = ({ tenantId }) => {
-    if (isNullES(tenantId)) return '-'
-    const item = tenantData.value.find((item) => item.tenantId === tenantId)
-    if (isNullES(item)) return tenantId
-    return item.name ?? tenantId
-}
-
-//搜索
-const searchClick = () => {
-    getTableData()
-}
-
-//表格数据
-const tableColumn = ref([
-    { key: 'roleName', name: '角色名称' },
-    { key: 'tenantId', name: '所属租户' },
-    { key: 'roleAlias', name: '角色别名' },
-    { key: 'sort', name: '排序' },
-    { key: 'action', name: '操作', width: 200, align: 'center' },
-])
-const tableData = ref([])
-
-//获取表格数据
-const tableLoading = ref(true)
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { data } = await mainApi.page(searchForm.value)
-    tableData.value = getArrValue(data)
-    tableLoading.value = false
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//上级菜单
-const levelDataProps = { label: 'title' }
-const levelData = ref([])
-const getlevelData = async () => {
-    const { data } = await mainApi.getRoleTreeById()
-    levelData.value = getArrValue(data)
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const iconDialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    roleName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入角色名称',
-    },
-    roleAlias: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入角色别名',
-    },
-    sort: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入菜单排序',
-    },
-}
-
-
-//新增
-const addClick = () => {
-    isChildForm.value = false
-    iconDialogTitle.value = '新增角色'
-    formModel.value = { parentId: null, sort: 1 }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-        getlevelData()
-    })
-}
-
-//修改
-const editRowClick = (row) => {
-    isChildForm.value = false
-    formModel.value = {}
-    iconDialogTitle.value = '修改角色'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-        getlevelData()
-    })
-}
-
-//新增子项
-const isChildForm = ref(false)
-const addRowClick = (row) => {
-    isChildForm.value = true
-    iconDialogTitle.value = '新增子项'
-    formModel.value = { parentId: row.id, sort: 1 }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-        getlevelData()
-    })
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //处理数据
-    const form = formModel.value
-    form.parentId = form.parentId ?? '0'
-    form.tenantId = form.tenantId ?? ''
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(form)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        getTableData()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    isChildForm.value = false
-    formModel.value = {}
-}
-
-//删除
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-
-//批量删除
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的数据')
-        return false
-    }
-    //确认删除菜单
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            getTableData().then()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-
-//权限配置弹窗
-const isRoleAuthShow = ref(false)
-const roleAuthRow = ref({})
-const authRowClick = (row) => {
-    roleAuthRow.value = row
-    nextTick(() => {
-        isRoleAuthShow.value = true
-    })
-}
-
-//关闭权限配置弹窗
-const roleAuthClose = () => {
-    isRoleAuthShow.value = false
-    roleAuthRow.value = {}
-}
-</script>

+ 0 - 105
src/views/certificate/admin.vue

@@ -1,105 +0,0 @@
-<template>
-    <hc-card id-ref="hc-certificate-management" div-p="12px">
-        <template #header>
-            <div class="w-100">
-                <el-select v-model="searchForm.projectId" filterable clearable block placeholder="选择项目" @change="searchClick">
-                    <el-option v-for="item in projectData" :key="item.id" :label="item.projectName" :value="item.id" />
-                </el-select>
-            </div>
-        </template>
-        <hc-table :column="tableColumn" :datas="tableData" :loading="tableLoading" :is-index="false" >
-            <template #action="{ row }">
-                <el-link type="primary" @click="rowClick(row)">查看</el-link>
-            </template>
-        </hc-table>
-        <template #action>
-            <hc-pages :pages="searchForm" @change="pageChange" />
-        </template>
-        <!-- 查看 -->
-        <hc-drawer v-model="isRowDrawer" is-close to-id="hc-certificate-management">
-            <HcAdminSee v-if="isRowDrawer" :cid="tableRowItem.contractId" />
-        </hc-drawer>
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { getArrValue } from 'js-fast-way'
-import HcAdminSee from './modules/admin/see.vue'
-import mainApi from '~api/certificate/admin'
-
-defineOptions({
-    name: 'CertificateAdmin',
-})
-
-//激活
-onActivated(() => {
-    getDataApi()
-})
-
-const getDataApi = async () => {
-    await getProjectData()
-    searchClick()
-}
-
-//项目列表
-const projectData = ref([])
-const getProjectData = async () => {
-    const { data } = await mainApi.queryProjectList()
-    projectData.value = getArrValue(data)
-}
-
-//搜索条件
-const searchForm = ref({ projectId: '', current: 1, size: 20, total: 0 })
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableColumn = ref([
-    { key: 'projectName', name: '项目名称' },
-    { key: 'personalCount', name: '个人证书(个)', align: 'center' },
-    { key: 'enterpriseCount', name: '企业证书(个)', align: 'center' },
-    { key: 'action', name: '操作', width: 80, align: 'center' },
-])
-const tableData = ref([])
-
-//获取表格数据
-const tableLoading = ref(true)
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { error, code, data } = await mainApi.page({
-        ...searchForm.value,
-        total: null,
-    })
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//点击查看
-const isRowDrawer = ref(false)
-const tableRowItem = ref({})
-const rowClick = (row) => {
-    tableRowItem.value = row
-    nextTick(() => {
-        isRowDrawer.value = true
-    })
-}
-</script>

+ 0 - 153
src/views/certificate/list.vue

@@ -1,153 +0,0 @@
-<template>
-    <hc-card id-ref="hc-certificate-list" div-p="12px">
-        <template #header>
-            <div class="w-100">
-                <el-select v-model="searchForm.projectId" filterable block placeholder="选择项目" @change="searchClick">
-                    <el-option v-for="item in projectData" :key="item.id" :label="item.projectName" :value="item.id" />
-                </el-select>
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-        </template>
-        <hc-table :loading="tableLoading" :column="tableColumn" :datas="tableData" :index-style="{ width: 60 }" >
-            <template #certificateType="{ row }">{{ row.certificateType === 1 ? '个人证书' : '企业证书' }}</template>
-            <template #isRegister="{ row }">
-                <el-link v-if="row.isRegister === 0" type="primary" @click="registerRowClick(row)">注册</el-link>
-                <span v-else>已注册</span>
-            </template>
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-        <template #action>
-            <hc-pages :pages="searchForm" @change="pageChange" />
-        </template>
-        <!-- 查看 -->
-        <hc-drawer v-model="isRowDrawer" to-id="hc-certificate-list">
-            <HcListForm v-if="isRowDrawer" :info="tableRowItem" @close="isRowDrawer = false" />
-        </hc-drawer>
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { getArrValue } from 'js-fast-way'
-import HcListForm from './modules/list/form.vue'
-import adminApi from '~api/certificate/admin'
-import mainApi from '~api/certificate/list'
-
-defineOptions({
-    name: 'CertificateList',
-})
-
-//激活
-onActivated(() => {
-    getProjectData()
-})
-
-//项目列表
-const projectData = ref([])
-const getProjectData = async () => {
-    const { data } = await adminApi.queryProjectList()
-    const res = getArrValue(data)
-    if (res.length > 0) {
-        searchForm.value.projectId = res[0].id
-    } else {
-        searchForm.value.projectId = ''
-    }
-    projectData.value = res
-    searchClick()
-}
-
-//搜索条件
-const searchForm = ref({ projectId: '', current: 1, size: 20, total: 0 })
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableColumn = ref([
-    { key: 'certificateUserName', name: '证书所有者' },
-    { key: 'certificateId', name: '证书ID/企业统一社会信用代码' },
-    { key: 'certificateType', name: '证书类型' },
-    { key: 'isRegister', name: '注册' },
-    { key: 'action', name: '操作', width: 100, align: 'center' },
-])
-const tableData = ref([])
-
-//获取表格数据
-const tableLoading = ref(true)
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { error, code, data } = await mainApi.page({
-        ...searchForm.value,
-        total: null,
-    })
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-const isRowDrawer = ref(false)
-const tableRowItem = ref({})
-
-//新增
-const addClick = () => {
-    tableRowItem.value = {}
-    nextTick(() => {
-        isRowDrawer.value = true
-    })
-}
-
-//修改
-const editRowClick = (row) => {
-    tableRowItem.value = row
-    nextTick(() => {
-        isRowDrawer.value = true
-    })
-}
-
-//注册
-const registerRowClick = async (row) => {
-    const { error, code, msg } = await mainApi.goRegister({
-        key: row.id,
-    })
-    if (!error && code === 200) {
-        window.$message.success('操作成功')
-        getTableData()
-    } else {
-        window.$message.error(msg ?? '操作失败')
-    }
-}
-
-//删除
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-</script>

+ 0 - 136
src/views/certificate/modules/admin/see.vue

@@ -1,136 +0,0 @@
-<template>
-    <hc-body split>
-        <template #left>
-            <hc-card>
-                <div class="relative mb-3 w-full">
-                    <el-select v-model="currentId" filterable block placeholder="选择合同段" @change="getRoleList">
-                        <el-option v-for="item in contractData" :key="item.id" :label="item.contractName" :value="item.id" />
-                    </el-select>
-                </div>
-                <div v-loading="isRoleLoading" class="hc-sign-pfx-file-list">
-                    <el-scrollbar>
-                        <el-menu unique-opened style="border-right: 0;">
-                            <el-sub-menu v-for="(item, index) in roleListData" :key="index" :index="`${item.roleId.toString()}`">
-                                <template #title>
-                                    <i class="i-iconoir-settings-profiles" />
-                                    <span class="ml-2">{{ item.roleName }}</span>
-                                </template>
-                                <el-menu-item-group v-for="(items, indexs) in item.childRoleList" :key="indexs">
-                                    <el-menu-item :index="`${items.roleId.toString()}`" @click="signPfxClick(items)">
-                                        {{ items.roleName }}
-                                    </el-menu-item>
-                                </el-menu-item-group>
-                            </el-sub-menu>
-                        </el-menu>
-                    </el-scrollbar>
-                </div>
-            </hc-card>
-        </template>
-        <hc-card>
-            <hc-status v-if="tableData.length <= 0" text="暂无相关数据" />
-            <hc-table v-else :column="tableColumn" :datas="tableData" :is-index="false" >
-                <template #signatureFileUrl="{ row }">
-                    <el-image class="h-[30px] w-[70px]" :src="row.signatureFileUrl" :preview-src-list="[row.signatureFileUrl]" fit="cover" />
-                </template>
-                <template #certificateFileName="{ row }">
-                    <el-link type="primary" :href="row.certificateFileUrl" target="_blank">{{ row.certificateFileName }}</el-link>
-                </template>
-                <template #pfxType="{ row }">
-                    {{ row.pfxType != -1 ? row.pfxType : '-' }}
-                </template>
-                <template #action="{ row, index }">
-                    <el-link v-del-com:[delRowClick]="{ row, index }" type="danger">删除签名配置</el-link>
-                </template>
-            </hc-table>
-        </hc-card>
-    </hc-body>
-</template>
-
-<script setup>
-import { onMounted, ref } from 'vue'
-import { getArrValue, getObjValue, isNullES } from 'js-fast-way'
-import mainApi from '~api/certificate/admin'
-
-const props = defineProps({
-    cid: {
-        type: [String, Number],
-        default: '',
-    },
-})
-
-//监听内容
-const contractId = ref(props.cid)
-const currentId = ref(props.cid)
-
-//渲染完成
-onMounted(() => {
-    getDataApi()
-})
-
-//获取数据
-const getDataApi = () => {
-    if (isNullES(contractId.value)) return
-    getProjectData()
-    getRoleList()
-}
-
-//合同段列表
-const contractData = ref([])
-const getProjectData = async () => {
-    const { data } = await mainApi.queryContractList({
-        contractId: contractId.value,
-    })
-    contractData.value = getArrValue(data)
-}
-
-//获取证书列表
-const isRoleLoading = ref(false)
-const roleListData = ref([])
-const getRoleList = async () => {
-    isRoleLoading.value = true
-    const { data } = await mainApi.queryAllRoleList({
-        contractId: currentId.value,
-    })
-    roleListData.value = getArrValue(data)
-    isRoleLoading.value = false
-}
-
-//表格数据
-const tableColumn = ref([
-    { key: 'certificateUserName', name: '姓名' },
-    { key: 'signatureFileUrl', name: '签名图片' },
-    { key: 'certificateFileName', name: '证书' },
-    { key: 'pfxType', name: '签章类型' },
-    { key: 'action', name: '操作', width: 110, align: 'center' },
-])
-
-//证书点击
-const tableData = ref([])
-const signPfxClick = ({ signPfxFileList }) => {
-    tableData.value = getArrValue(signPfxFileList)
-}
-
-//删除签名配置
-const delRowClick = async ({ item }, resolve) => {
-    const { row, index } = getObjValue(item)
-    const { code, msg } = await mainApi.del(row.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getRoleList().then()
-        tableData.value.splice(index, 1)
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-</script>
-
-<style lang="scss" scoped>
-.hc-sign-pfx-file-list {
-    position: relative;
-    height: calc(100% - 42px);
-    border: 1px solid #dbdde5;
-    overflow: hidden;
-}
-</style>

+ 0 - 329
src/views/certificate/modules/list/form.vue

@@ -1,329 +0,0 @@
-<template>
-    <hc-card :title="rowItem.id ? '编辑证书' : '新增证书'" scrollbar>
-        <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-            <el-row :gutter="20">
-                <el-col :span="formModel.certificateType !== 1 && Number(formModel.company) === 3 ? 24 : 16 ">
-                    <el-row :gutter="20">
-                        <el-col :span="12">
-                            <el-form-item label="证书类型:" prop="certificateType">
-                                <div class="form-item-div">
-                                    <el-radio-group v-model="formModel.certificateType" @change="certificateTypeChange">
-                                        <el-radio :value="1">个人证书</el-radio>
-                                        <el-radio :value="2">企业证书</el-radio>
-                                    </el-radio-group>
-                                </div>
-                            </el-form-item>
-                        </el-col>
-                        <el-col v-if="formModel.certificateType === 2" :span="12">
-                            <el-form-item label="签字公司:" prop="company">
-                                <el-select v-model="formModel.company" filterable clearable block>
-                                    <el-option v-for="item in companyData" :key="item.value" :label="item.label" :value="item.value" />
-                                </el-select>
-                            </el-form-item>
-                        </el-col>
-                        <el-col v-if="formModel.certificateType === 1" :span="12">
-                            <el-form-item label="关联用户:" prop="certificateUserId">
-                                <el-select-v2 v-model="formModel.certificateUserId" :options="users" placeholder="选择关联用户" filterable block @change="usersChange" />
-                            </el-form-item>
-                        </el-col>
-                        <el-col :span="12">
-                            <el-form-item label="证书所有者:" prop="certificateUserName">
-                                <el-input v-model="formModel.certificateUserName" clearable />
-                            </el-form-item>
-                        </el-col>
-                        <el-col v-if="formModel.certificateType === 1 && Number(formModel.company) !== 3" :span="12">
-                            <el-form-item label="所持证书者身份证号码:" prop="certificateId">
-                                <el-input v-model="formModel.certificateId" clearable />
-                            </el-form-item>
-                        </el-col>
-                        <el-col v-if="formModel.certificateType === 2 && Number(formModel.company) !== 3" :span="12">
-                            <el-form-item label="企业统一社会信用代码:" prop="enterpriseUnifiedCode">
-                                <el-input v-model="formModel.enterpriseUnifiedCode" clearable />
-                            </el-form-item>
-                        </el-col>
-                        <el-col :span="12">
-                            <el-form-item label="证书编号:" prop="certificateNumber">
-                                <el-input v-model="formModel.certificateNumber" clearable />
-                            </el-form-item>
-                        </el-col>
-                        <el-col v-if="Number(formModel.company) !== 3" :span="12">
-                            <el-form-item label="证书密码:" prop="certificatePassword">
-                                <el-input v-model="formModel.certificatePassword" clearable />
-                            </el-form-item>
-                        </el-col>
-                        <el-col v-else :span="12">
-                            <el-form-item label="签章类型:" prop="pfxType">
-                                <el-select v-model="formModel.pfxType" filterable clearable block>
-                                    <el-option v-for="item in pfxTypeData" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
-                                </el-select>
-                            </el-form-item>
-                        </el-col>
-                    </el-row>
-                </el-col>
-                <el-col v-if="formModel.certificateType === 1 || (formModel.certificateType === 2 && Number(formModel.company) === 2)" :span="8">
-                    <el-form-item prop="certificateFileUrl">
-                        <template #label>
-                            <div class="hc-form-item-label">
-                                <div class="title-content">
-                                    <span class="title">证书文件:</span>
-                                    <span content="text">(支持上传文件格式为pfx文件)</span>
-                                </div>
-                                <div class="right-content">
-                                    <el-link type="warning" @click="formModel.certificateFileUrl = ''">清除</el-link>
-                                </div>
-                            </div>
-                        </template>
-                        <hc-form-upload v-model="formModel.certificateFileUrl" :upload="{ options: certificateOptions }" @success="certificateFileSuccess" />
-                    </el-form-item>
-                    <el-form-item label="签名体文件:" prop="signatureFileUrl">
-                        <template #label>
-                            <div class="hc-form-item-label">
-                                <div class="title-content">
-                                    <span class="title">签名体文件:</span>
-                                    <span content="text">(支持上传文件格式为JPG/PNG)</span>
-                                </div>
-                                <div class="right-content">
-                                    <el-link type="warning" @click="formModel.signatureFileUrl = ''">清除</el-link>
-                                </div>
-                            </div>
-                        </template>
-                        <hc-form-upload v-model="formModel.signatureFileUrl" :options="{ type: 'preview' }" :upload="{ options: signatureOptions }" @success="signatureFileSuccess" />
-                    </el-form-item>
-                </el-col>
-                <el-col v-if="formModel.certificateType === 2" :span="24">
-                    <el-form-item label="关联项目:" prop="projectContractRole">
-                        <hc-related-project v-model="formModel.projectContractRole" />
-                    </el-form-item>
-                </el-col>
-            </el-row>
-        </el-form>
-        <template #action>
-            <div class="hc-flex-center">
-                <el-button hc-btn class="mr-4" @click="cancelClick">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="submitClick">提交</el-button>
-            </div>
-        </template>
-    </hc-card>
-</template>
-
-<script setup>
-import { onMounted, ref } from 'vue'
-import { deepClone, formValidate, getArrValue, getObjValue, isNullES } from 'js-fast-way'
-import { getDictionaryData } from '~uti/tools'
-import mainApi from '~api/certificate/list'
-
-const props = defineProps({
-    info: {
-        type: Object,
-        default: () => ({}),
-    },
-})
-
-const emit = defineEmits(['close'])
-
-//监听内容
-const rowItem = ref(props.info)
-
-//渲染完成
-onMounted(() => {
-    getDataApi()
-})
-
-//获取数据 旧
-const getDataApi = () => {
-    const { id } = rowItem.value
-    if (!isNullES(id)) {
-        getDetailData(id)
-    }
-    findUserByName()
-    getCompanyData()
-    getPfxTypeData()
-}
-
-//获取数据详情
-const getDetailData = async (id) => {
-    const { data } = await mainApi.detail(id)
-    const res = getObjValue(data)
-    if (res.certificateType !== 1) {
-        res.company = res.certificateType === 2 ? 2 : res.certificateType === 3 ? 3 : 2
-        res.certificateType = 2
-    }
-    formModel.value = res
-}
-
-//获取当前系统下所有用户
-const users = ref([])
-const findUserByName = async () => {
-    const { data } = await mainApi.findUserByName()
-    const res = getArrValue(data)
-    let newArr = []
-    for (let i = 0; i < res.length; i++) {
-        newArr.push({
-            value: res[i].id,
-            label: res[i].name,
-            idNumber: res[i].idNumber,
-            plaintextPassword: res[i].plaintextPassword,
-        })
-    }
-    users.value = newArr
-}
-//获取用户数据
-const usersChange = (val) => {
-    const item = users.value.find((item) => item.value === val)
-    console.log('item:', item)
-    formModel.value.certificateUserName = item.label
-    formModel.value.certificateId = item.idNumber
-    formModel.value.certificatePassword = item.plaintextPassword
-}
-
-//签字公司
-const companyData = ref([])
-const getCompanyData = async () => {
-    companyData.value = await getDictionaryData('es_type_name', true)
-}
-
-
-//签章类型
-const pfxTypeData = ref([])
-const getPfxTypeData = async () => {
-    const { data } = await mainApi.findPfxType({
-        typeOrStatus: 'pfx_type',
-    })
-    pfxTypeData.value = getArrValue(data)
-}
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({
-    certificateType: 1,
-})
-const formRules = {
-    certificateType: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择证书类型',
-    },
-    certificateUserId: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择关联用户',
-    },
-    certificateUserName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入证书所有者',
-    },
-    certificateId: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入所持证书者身份证号码',
-    },
-    certificatePassword: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入证书密码',
-    },
-    certificateFileUrl: {
-        required: true,
-        trigger: 'blur',
-        message: '请上传证书文件',
-    },
-    signatureFileUrl: {
-        required: true,
-        trigger: 'blur',
-        message: '请上传签名体文件',
-    },
-    company: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择签字公司',
-    },
-    enterpriseUnifiedCode: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入企业统一社会信用代码',
-    },
-    pfxType: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择签章类型',
-    },
-    projectContractRole: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择关联项目',
-    },
-}
-
-//切换类型
-const certificateTypeChange = () => {
-    const { certificateType, company } = formModel.value
-    if (certificateType === 2) {
-        formModel.value.company = company ?? 2
-    }
-}
-
-//证书文件上传配置
-const certificateOptions = {
-    url: '/api/blade-resource/client/addFileInfo',
-    accept: '.pfx',
-    accept_tip: '支持上传文件格式为pfx文件',
-    multiple: false,
-    size: 200,
-}
-
-//证书文件上传成功
-const certificateFileSuccess = (val, file, res) => {
-    formModel.value.certificateFileName = res.originalName
-}
-
-
-//签名体文件上传配置
-const signatureOptions = {
-    url: '/api/blade-resource/client/addFileInfo',
-    accept: '.jpg,.png',
-    accept_tip: '支持上传文件格式为JPG/PNG',
-    multiple: false,
-    size: 200,
-}
-
-//签名体文件上传成功
-const signatureFileSuccess = (val, file, res) => {
-    formModel.value.signatureFileName = res.originalName
-}
-
-
-//提交数据
-const submitLoading = ref(false)
-const submitClick = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //处理数据
-    const form = deepClone(formModel.value)
-    form.enterpriseUnifiedCode = ''
-    if (form.certificateType === 2 && Number(form.company) === 3) {
-         form.certificateType = 3
-    }
-    //id不存在,则新增
-    let res = {}
-    if (isNullES(form.id)) {
-        res = await mainApi.add(form)
-    } else {
-        res = await mainApi.update(form)
-    }
-    const { error, code, msg } = res
-    submitLoading.value = false
-    if (!error && code === 200) {
-        cancelClick()
-        window?.$message?.success('操作成功')
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//取消关闭
-const cancelClick = () => {
-    emit('close')
-}
-</script>

+ 13 - 0
src/views/home/datav.vue

@@ -0,0 +1,13 @@
+<template>
+    <hc-body scrollbar padding="12px">
+        1111
+    </hc-body>
+</template>
+
+<script setup>
+
+</script>
+
+<style lang="scss">
+@import '~src/styles/view/datav';
+</style>

+ 0 - 203
src/views/home/index.vue

@@ -1,203 +0,0 @@
-<template>
-    <hc-body scrollbar padding="12px">
-        <HcAgentCharge :active="agentChargeIndex" @load="agentChargeLoad" />
-        <div class="hc-home-chart-body relative mb-5 mt-5 h-[500px]">
-            <el-row :gutter="20" class="h-full">
-                <el-col :span="8" class="h-full">
-                    <hc-card>
-                        <template #header>
-                            <div class="chart-title">
-                                <img :src="frame001" alt="">
-                                <div class="title-body">
-                                    <span class="title">证书统计</span>
-                                    <span class="text">(总计{{ pfxAmountVal }}个)</span>
-                                </div>
-                            </div>
-                        </template>
-                        <HcChartPfx :datas="pfxLists" />
-                    </hc-card>
-                </el-col>
-                <el-col :span="8" class="h-full">
-                    <hc-card>
-                        <template #header>
-                            <div class="chart-title">
-                                <img :src="frame002" alt="">
-                                <div class="title-body">
-                                    <span class="title">人员账户统计</span>
-                                    <span class="text">(总计{{ personAmount }}个)</span>
-                                </div>
-                            </div>
-                        </template>
-                        <HcChartPerson :datas="personUsers" />
-                    </hc-card>
-                </el-col>
-                <el-col :span="8" class="h-full">
-                    <hc-card>
-                        <template #header>
-                            <div class="chart-title">
-                                <img :src="frame003" alt="">
-                                <div class="title-body">维护类型统计汇总</div>
-                            </div>
-                        </template>
-                        <template #extra>
-                            <el-select v-model="projectId" placeholder="请选择项目" size="small" class="chart-select" @change="selectProjectOpinion">
-                                <el-option v-for="item in projectList" :key="item.id" :label="item.projectName" :value="item.id" />
-                            </el-select>
-                        </template>
-                        <HcChartType :datas="userTypeList" />
-                    </hc-card>
-                </el-col>
-            </el-row>
-        </div>
-    </hc-body>
-</template>
-
-<script setup>
-import { onActivated, ref } from 'vue'
-import HcAgentCharge from './modules/agent-charge.vue'
-import frame001 from '~src/assets/home/Frame001.png'
-import frame002 from '~src/assets/home/Frame002.png'
-import frame003 from '~src/assets/home/Frame003.png'
-import HcChartPfx from './modules/chart-pfx.vue'
-import HcChartPerson from './modules/chart-person.vue'
-import HcChartType from './modules/chart-type.vue'
-import { getArrValue, getObjValue } from 'js-fast-way'
-import mainApi from '~api/home/index'
-
-defineOptions({
-    name: 'Index',
-})
-
-//激活
-onActivated(() => {
-    getChartData()
-})
-
-//工单类型
-const agentChargeIndex = ref(1)
-const agentChargeLoad = async (index, first, resolve) => {
-    if (first) {
-        await getAgentChargeData()
-    } else {
-        if (index === 1) {
-            await queryBusinessUserOpinion()
-        } else {
-            await queryBusinessUserOpinionAll()
-        }
-        agentChargeIndex.value = index
-    }
-    resolve({
-        tag: agentChargeTags.value,
-        data: agentChargeData.value,
-    })
-}
-
-//工单数据
-const agentChargeTags = ref({ tag1: 0, tag2: 0 })
-const agentChargeData = ref([])
-
-const getAgentChargeData = async () => {
-    const isRes = await queryBusinessUserOpinion()
-    if (isRes) return
-    agentChargeIndex.value = 2
-    await queryBusinessUserOpinionAll()
-}
-
-//获取我的消息
-const queryBusinessUserOpinion = async () => {
-    const { data } = await mainApi.queryBusinessUserOpinion({
-        current: 1,
-        size: 999999,
-    })
-    //处理数据
-    const { userOpinionFlowList, personToDoNumber } = getObjValue(data)
-    agentChargeTags.value.tag1 = personToDoNumber ?? 0
-    agentChargeData.value = getArrValue(userOpinionFlowList)
-    return agentChargeData.value.length >= 1
-}
-
-//获取我的消息
-const queryBusinessUserOpinionAll = async () => {
-    const { data } = await mainApi.queryBusinessUserOpinionAll({
-        current: 1,
-        size: 999999,
-    })
-    //处理数据
-    const { userOpinionFlowList, allToDoNumber } = getObjValue(data)
-    agentChargeTags.value.tag2 = allToDoNumber ?? 0
-    agentChargeData.value = getArrValue(userOpinionFlowList)
-}
-
-//获取图表数据
-const getChartData = () => {
-    queryProjectPfx()
-    queryProjectUserAmount()
-    queryOpinionTypeAmount()
-}
-
-//证书统计
-const pfxAmountVal = ref('0')
-const pfxLists = ref([])
-const queryProjectPfx = async () => {
-    const { data } = await mainApi.queryProjectPfx()
-    const { pfxList, pfxAmount } = getObjValue(data)
-    pfxAmountVal.value = pfxAmount ?? '0'
-    pfxLists.value = getArrValue(pfxList)
-}
-
-//人员账户统计
-const personAmount = ref('0')
-const personUsers = ref([])
-const queryProjectUserAmount = async () => {
-    const { data } = await mainApi.queryProjectUserAmount()
-    const { projectUserAmountVOList, projectUserAmount } = getObjValue(data)
-    pfxAmountVal.value = projectUserAmount ?? '0'
-    personUsers.value = getArrValue(projectUserAmountVOList)
-}
-
-//项目ID
-const projectId = ref(null)
-const projectList = ref([])
-const queryOpinionTypeAmount = async () => {
-    const { data } = await mainApi.queryOpinionTypeAmount()
-    const { userOpinionList, projectInfos } = getObjValue(data)
-    const userOpinionTypeList = getArrValue(userOpinionList)
-    projectList.value = getArrValue(projectInfos)
-    userOpinionTypeLists.value = getArrValue(userOpinionTypeList)
-    //处理数据
-    if (userOpinionTypeList.length > 0) {
-        setUserTypeList(userOpinionTypeList[0])
-        projectId.value = userOpinionTypeList[0].projectId ?? null
-    } else {
-        projectId.value = null
-    }
-}
-
-//项目被选择
-const userOpinionTypeLists = ref([])
-const selectProjectOpinion = () => {
-    const list = userOpinionTypeLists.value
-    for (let i = 0; i < list.length; i++) {
-        if (list[i].projectId === projectId.value) {
-            setUserTypeList(list[i])
-        }
-    }
-}
-
-//设置项目图表
-const userTypeList = ref([])
-const setUserTypeList = ({ problemType, problemTypeAmount }) => {
-    let newArr = []
-    for (let i = 0; i < problemType.length; i++) {
-        newArr.push({
-            value: problemTypeAmount[i],
-            name: problemType[i],
-        })
-    }
-    userTypeList.value = newArr
-}
-</script>
-
-<style lang="scss">
-@import '~src/styles/home/home';
-</style>

+ 0 - 281
src/views/home/modules/agent-charge.vue

@@ -1,281 +0,0 @@
-<template>
-    <div class="hc-agent-charge border-10">
-        <div class="active-menus">
-            <div class="active-item" :class="{ 'active-select': activeIndex === 1 }" @click="handleSelect(1)">
-                <img :src="activeIndex === 1 ? frame254 : frame257" alt="">
-                <div style="margin-top:5px;">
-                    <el-badge :value="tags1" :hidden="!tags1" class="item">
-                        <span class="font-bold">我的代办工单&nbsp; </span>
-                    </el-badge>
-                </div>
-            </div>
-            <div class="triangle-bottomleft" :class="{ 'b-b-b-w': activeIndex === 1 }" />
-            <div class="active-item" :class="{ 'active-select': activeIndex === 2 }" @click="handleSelect(2)">
-                <img :src="activeIndex === 2 ? frame256 : frame255" alt="">
-                <div style="margin-top:5px;">
-                    <el-badge :value="tags2" :hidden="!tags2" class="item">
-                        <span class="font-bold">所有代办工单&nbsp; </span>
-                    </el-badge>
-                </div>
-            </div>
-            <div class="triangle-bottomleft" :class="{ 'b-b-b-w': activeIndex === 2 }" />
-        </div>
-        <div v-loading="isLoading" class="active-body border-bottom-10 relative h-[250px] bg-white p-3">
-            <el-scrollbar>
-                <div class="border-bottom-10">
-                    <div v-if="tableData.length <= 0">
-                        <hc-empty title="没有找到代办工单" />
-                    </div>
-                    <div v-for="(item, index) in tableData" v-else :key="index" class="info-item">
-                        <div class="frame-warning">
-                            <img class="h-[14px] w-[14px]" :src="frameWarning" alt="">
-                        </div>
-                        <div class="frame-content">
-                            <span class="title-common">来自</span>
-                            <span class="title-text">{{ item.projectContract }}</span>
-                            <span class="title-common">的</span>
-                            <span class="title-text">{{ item.roleUser }}</span>
-                            <span class="title-common">向</span>
-                            <span v-if="item.manageUser === '您'" class="title-common">您</span>
-                            <span v-else class="title-text">{{ item.manageUser }}</span>
-                            <span class="title-common">反馈</span>
-                            <span class="title-red">{{ item.title }}</span>
-                        </div>
-                        <div class="frame-time" :class="(activeIndex === 2 && item.operation) || activeIndex === 1 ? 'is-more' : ''">{{ item.time }}</div>
-                        <div v-if="(activeIndex === 2 && item.operation) || activeIndex === 1" class="frame-more">
-                            <el-dropdown class="outline: none;">
-                                <span class="el-dropdown-more">
-                                    <el-link :underline="false">
-                                        <hc-icon name="more-2" class="more-icon" />
-                                    </el-link>
-                                </span>
-                                <template #dropdown>
-                                    <el-dropdown-menu>
-                                        <el-dropdown-item @click="openPreview(item)">立即处理</el-dropdown-item>
-                                        <el-dropdown-item v-yes-com:[ignore]="{ index }">忽略</el-dropdown-item>
-                                    </el-dropdown-menu>
-                                </template>
-                            </el-dropdown>
-                        </div>
-                    </div>
-                    <div v-if="tableData.length === 1" class="text-align-c" style="color:#CCD0DE;line-height:200px">没有更多数据了~</div>
-                </div>
-            </el-scrollbar>
-        </div>
-
-        <!-- 工单详情 -->
-        <hc-dialog v-model="isAgentChargeShow" widths="720px" title="工单详情" save-text="处理" @save="agentChargeSave">
-            <table border="1" class="hc-agent-charge-new-table">
-                <tbody>
-                    <tr>
-                        <td class="new-titile">合同名称</td>
-                        <td class="new-content">{{ agentChargeData.projectName }}——{{ agentChargeData.contractName }}</td>
-                    </tr>
-                    <tr>
-                        <td class="new-titile">问题描述</td>
-                        <td class="new-content" style="color:#EB4D3D">{{ agentChargeData.opinionContent }}</td>
-                    </tr>
-                    <tr>
-                        <td class="new-titile">反馈人员</td>
-                        <td class="new-content">{{ agentChargeData.submitUserName }}</td>
-                    </tr>
-                    <tr>
-                        <td class="new-titile">电话</td>
-                        <td class="new-content">{{ agentChargeData.submitPhone }}</td>
-                    </tr>
-                    <tr>
-                        <td class="new-titile">岗位</td>
-                        <td class="new-content">{{ agentChargeData.submitUserRole }}</td>
-                    </tr>
-                    <tr>
-                        <td class="new-titile">反馈时间</td>
-                        <td class="new-content">{{ agentChargeData.manageTime }}</td>
-                    </tr>
-                    <tr>
-                        <td class="new-titile">图片补充</td>
-                        <td class="new-content">
-                            <div v-if="agentChargeData.fileUrl && agentChargeData.fileUrl.length" class="flex">
-                                <div v-for="item in agentChargeData.fileUrl" :key="item">
-                                    <div class="new-img">
-                                        <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAQhJREFUOE+lkzFOAzEURN8cASkSoUqOETroOAI3oEgBHekiOuiggxtwBDrSwS2AiiBRcIOJHNmrv85KVsRWu9/2+/4zs+Kfj+rztl+Bk6r+Lul4qFcHsD0BPoGFpLu42fYlcA9MJX3FtQgwcCRpPdTJ9hj4ltS79fbD9hvwLOmhHLZ9mN4l/YTaNXAm6bTUCsA12fYyA26qcXp7dwC2R8A8CLkCHstNbDcBadaLCvBUtGkCwrx7jZC8f4n2ZdWTiJ0r2c7zmInaxnFUvRIvubIetDFbOQU+gKtoZ15L9t1mYK/JUJRTJmZVmFbJ+xImoIPsAFr/VoAcSPrbG5BHGkn63Qat1bG1vgHcfowRy9YlxwAAAABJRU5ErkJggg==" style="margin: 40px 0 0 40px;" alt="">
-                                    </div>
-                                    <el-image class="h-[100px] w-[100px] border-4" :src="item" :preview-src-list="agentChargeData.fileUrl" />
-                                </div>
-                            </div>
-                            <span v-else>无</span>
-                        </td>
-                    </tr>
-                </tbody>
-            </table>
-        </hc-dialog>
-
-        <!-- 处理工单 -->
-        <hc-dialog v-model="isAgentDisposeShow" widths="400px" title="处理工单" @save="agentDisposeSave">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top">
-                <el-form-item label="计量期:">
-                    <el-select v-model="formModel.currentLink" placeholder="选择提交进度" block>
-                        <el-option label="进入人工预处理环节" :value="2" />
-                        <el-option label="已解决" :value="3" />
-                    </el-select>
-                </el-form-item>
-                <el-form-item v-show="formModel.currentLink === 2" label="预计处理截止日期:" prop="manageTime">
-                    <el-date-picker v-model="formModel.manageTime" class="block" format="YYYY-MM-DD" type="date" value-format="YYYY-MM-DD" />
-                </el-form-item>
-            </el-form>
-        </hc-dialog>
-    </div>
-</template>
-
-<script setup>
-import { onMounted, ref, watch } from 'vue'
-import frame254 from '~ass/home/Frame254.png'
-import frame257 from '~ass/home/Frame257.png'
-import frame256 from '~ass/home/Frame256.png'
-import frame255 from '~ass/home/Frame255.png'
-import frameWarning from '~ass/home/warning.png'
-import { formValidate, getArrValue, getObjValue } from 'js-fast-way'
-import mainApi from '~api/home/index'
-
-const props = defineProps({
-    active: {
-        type: [Number, String],
-        default: 1,
-    },
-})
-
-//事件
-const emit = defineEmits(['load'])
-
-//工单数量
-const tags1 = ref(0)
-const tags2 = ref(0)
-
-//代办工单
-const activeIndex = ref(1)
-
-//工单数据
-const tableData = ref([])
-
-//监听数据
-watch(() => props.active, (active) => {
-    activeIndex.value = active ?? 1
-}, { immediate: true, deep: true })
-
-//渲染完成
-onMounted(() => {
-    getLoadData()
-})
-
-//工单类型被切换
-const handleSelect = (val) => {
-    if (activeIndex.value === val) return
-    activeIndex.value = val
-    getLoadData(false)
-}
-
-//获取数据
-const isLoading = ref(false)
-const getLoadData = (first = true) => {
-    isLoading.value = true
-    emit('load', activeIndex.value, first, async ({ tag, data }) => {
-        tableData.value = getArrValue(data)
-        const { tag1, tag2 } = getObjValue(tag)
-        tags1.value = tag1 ?? 0
-        tags2.value = tag2 ?? 0
-        isLoading.value = false
-    })
-}
-
-//立即处理
-const isAgentChargeShow = ref(false)
-const agentChargeData = ref({})
-const agentChargeRow = ref({})
-const openPreview = async (row) => {
-    const { data } = await mainApi.queryOpinionDetails({
-        userOpinionId : row.userOpinionId,
-    })
-    agentChargeRow.value = row
-    agentChargeData.value = getObjValue(data)
-    isAgentChargeShow.value = true
-}
-
-//处理工单
-const isAgentDisposeShow = ref(false)
-const agentChargeSave = () => {
-    formModel.value = { currentLink: 2 }
-    isAgentDisposeShow.value = true
-}
-
-//基础表单
-const formRef = ref(null)
-const formModel = ref({ currentLink: 2 })
-const formRules = {
-    manageTime: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择预计处理截止日期',
-    },
-}
-
-//确认处理工单
-const isCancel = ref(true)
-const agentDisposeSave = async () => {
-    const isForm = await formValidate(formRef.value)
-    if (!isForm) return
-    //业务人员提交环节操作
-    const { manageTime } = formModel.value
-    const { currentLinkId, currentLink, newNumber, userOpinionId } = agentChargeRow.value
-    const { error, code, msg } = await mainApi.manageUserOperationStatus({
-        currentLinkId: currentLinkId,
-        currentLink: currentLink,
-        newNumber: newNumber,
-        userOpinionId: userOpinionId,
-        manageTime: manageTime ?? null,
-    })
-    if (!error && code === 200) {
-        window.$message.success('提交成功')
-        isAgentDisposeShow.value = false
-        isAgentChargeShow.value = false
-        //重新刷新列表
-        getLoadData(false)
-    } else {
-        window.$message.error(msg ?? '操作失败')
-    }
-    //是否前往消息区继续处理
-    if (isCancel.value) {
-        window?.$messageBox?.alert('是否前往消息区继续处理?', '提示', {
-            showCancelButton: true,
-            confirmButtonText: '确认',
-            cancelButtonText: '取消',
-            type: 'warning',
-            callback: (action) => {
-                if (action === 'confirm') {
-                    console.log('前往消息区继续处理')
-                } else {
-                    isCancel.value = false
-                }
-            },
-        })
-    }
-}
-
-//忽略
-const ignore = async ({ item }, resolve) => {
-    const { index } = getObjValue(item)
-    const { userOpinionId } = tableData.value[index]
-    const { error, code, msg } = await mainApi.isIgnore({
-        userOpinionId : userOpinionId,
-    })
-    resolve()
-    if (!error && code === 200) {
-        //重新刷新列表
-        getLoadData(false)
-    } else {
-        window.$message.error(msg ?? '操作失败')
-    }
-}
-</script>
-
-<style lang="scss">
-@import '~src/styles/home/agent-charge';
-</style>

+ 0 - 83
src/views/home/modules/chart-person.vue

@@ -1,83 +0,0 @@
-<template>
-    <hc-charts :option="setOption" />
-</template>
-
-<script setup>
-import { nextTick, onMounted, ref, watch } from 'vue'
-
-const props = defineProps({
-    datas: {
-        type: Array,
-        default: () => ([]),
-    },
-})
-
-//初始变量
-const setOption = ref({})
-
-//深度监听数据变化
-const datas = ref(props.datas)
-watch(() => props.datas, (data) => {
-    datas.value = data
-    setDataFormat()
-}, { deep: true })
-
-//处理数据
-const setDataFormat = () => {
-    let data = datas.value, names = []
-    for (let i = 0; i < data.length; i++) {
-        const { projectName, contractor, supervision, owner } = data[i]
-        if (projectName) {
-            names.push([projectName, contractor ? contractor : 0, supervision ? supervision : 0, owner ? owner : 0])
-        }
-    }
-    setOptions(names)
-}
-
-//设置图表
-const setOptions = (datas = []) => {
-    setOption.value = {
-        color: ['#5B8FF9', '#5AD8A6', '#5D7092'],
-        legend: {},
-        tooltip: {
-            trigger: 'axis',
-            axisPointer: {
-                type: 'cross',
-            },
-        },
-        dataset: {
-            source: [
-                ['product', '施工方', '监理方', '指挥部'],
-                ...datas,
-            ],
-        },
-        grid: {
-            top: '20px',
-            left: '0',
-            right: '4px',
-            bottom: '0',
-            containLabel: true,
-        },
-        xAxis: {
-            type: 'category',
-            axisLabel: {
-                overflow: 'breakAll',
-                interval: 0,
-                rotate: -50,
-                formatter: function (value) {
-                    return value.length > 5 ? value.slice(0, 3) + '...' : value
-                },
-            },
-        },
-        yAxis: {},
-        series: [{ type: 'bar' }, { type: 'bar' }, { type: 'bar' }],
-    }
-}
-
-//渲染完成
-onMounted(() => {
-    nextTick(() => {
-        setDataFormat()
-    })
-})
-</script>

+ 0 - 104
src/views/home/modules/chart-pfx.vue

@@ -1,104 +0,0 @@
-<template>
-    <hc-charts :option="setOption" />
-</template>
-
-<script setup>
-import { nextTick, onMounted, ref, watch } from 'vue'
-
-const props = defineProps({
-    datas: {
-        type: Array,
-        default: () => ([]),
-    },
-})
-
-//初始变量
-const setOption = ref({})
-
-//深度监听数据变化
-const datas = ref(props.datas)
-watch(() => props.datas, (data) => {
-    datas.value = data
-    setDataFormat()
-}, { deep: true })
-
-//处理数据
-const setDataFormat = () => {
-    const data = datas.value
-    let names = [], personalCount = [], enterpriseCount = []
-    for (let i = 0; i < data.length; i++) {
-        const item = data[i]
-        if (item.projectName) {
-            names.push(item.projectName)
-            personalCount.push(item.personalCount ? item.personalCount : '0')
-            enterpriseCount.push(item.enterpriseCount ? item.enterpriseCount : '0')
-        }
-    }
-    setOptions(names, personalCount, enterpriseCount)
-}
-
-//设置图表
-const setOptions = (names = [], personalCount = [], enterpriseCount = []) => {
-    setOption.value = {
-        color: ['#5B8FF9', '#5AD8A6'],
-        tooltip: {
-            trigger: 'axis',
-            axisPointer: {
-                type: 'cross',
-            },
-        },
-        legend: {
-            data: ['个人证书', '企业证书'],
-        },
-        grid: {
-            top: '40px',
-            left: '0',
-            right: '10px',
-            bottom: '0',
-            containLabel: true,
-        },
-        xAxis: [
-            {
-                type: 'category',
-                axisLabel: {
-                    overflow: 'breakAll',
-                    interval: 0,
-                    rotate: -50,
-                    formatter: function (value) {
-                        return value.length > 5 ? value.slice(0, 3) + '...' : value
-                    },
-                },
-                boundaryGap: false,
-                data: names,
-            },
-        ],
-        yAxis: [
-            {
-                type: 'value',
-                interval: 30,
-            },
-        ],
-        series: [
-            {
-                name: '个人证书',
-                type: 'line',
-                areaStyle: {},
-                data: personalCount,
-            },
-            {
-                name: '企业证书',
-                type: 'line',
-                areaStyle: {},
-                data: enterpriseCount,
-            },
-        ],
-    }
-}
-
-//渲染完成
-onMounted(() => {
-    nextTick(() => {
-        setDataFormat()
-    })
-})
-</script>

+ 0 - 61
src/views/home/modules/chart-type.vue

@@ -1,61 +0,0 @@
-<template>
-    <hc-charts :option="setOption" />
-</template>
-
-<script setup>
-import { nextTick, onMounted, ref, watch } from 'vue'
-
-const props = defineProps({
-    datas: {
-        type: Array,
-        default: () => ([]),
-    },
-})
-
-//初始变量
-const setOption = ref({})
-
-//深度监听数据变化
-const datas = ref(props.datas)
-watch(() => props.datas, (data) => {
-    datas.value = data
-    setDataFormat()
-}, { deep: true })
-
-//处理数据
-const setDataFormat = () => {
-    setOptions(datas.value)
-}
-
-//设置图表
-const setOptions = (datas = []) => {
-    setOption.value = {
-        color: ['#5B8FF9', '#5AD8A6', '#5D7092'],
-        tooltip: {
-            trigger: 'item',
-        },
-        grid: {
-            top: '20px',
-            left: '0',
-            right: '4px',
-            bottom: '0',
-            containLabel: true,
-        },
-        legend: {},
-        series: [
-            {
-                type: 'pie',
-                radius: '60%',
-                data: datas,
-            },
-        ],
-    }
-}
-
-//渲染完成
-onMounted(() => {
-    nextTick(() => {
-        setDataFormat()
-    })
-})
-</script>

+ 0 - 260
src/views/login/components/pic.vue

@@ -1,260 +0,0 @@
-<template>
-    <div v-if="isBody" class="left-pic-content">
-        <div class="dt small-logo">
-            <div class="cons">
-                <img src="../../../assets/login/bim.png" alt="" class="logos">
-                <img src="../../../assets/login/s1.png" alt="" class="shadow1">
-            </div>
-        </div>
-        <div class="ds small-logo">
-            <div class="cons">
-                <img src="../../../assets/login/gis.png" alt="" class="logos">
-                <img src="../../../assets/login/s1.png" alt="" class="shadow1">
-            </div>
-        </div>
-        <div class="cc small-logo">
-            <div class="cons">
-                <img src="../../../assets/login/bd.png" alt="" class="logos">
-                <img src="../../../assets/login/s1.png" alt="" class="shadow1">
-            </div>
-        </div>
-        <div class="rp small-logo">
-            <div class="cons">
-                <img src="../../../assets/login/ca.png" alt="" class="logos">
-                <img src="../../../assets/login/s1.png" alt="" class="shadow1">
-            </div>
-        </div>
-        <div class="cube1">
-            <div class="cons">
-                <img src="../../../assets/login/cube1.png" alt="" class="cubes">
-                <img src="../../../assets/login/s2.png" alt="" class="shadow2">
-            </div>
-        </div>
-        <div class="cube2">
-            <div class="cons">
-                <img src="../../../assets/login/cube2.png" alt="" class="cubes">
-                <img src="../../../assets/login/s3.png" alt="" class="shadow3">
-            </div>
-        </div>
-        <div class="logo">
-            <a href="http://hczc.hcxxy.com/" target="_blank">
-                <div class="a-cons" />
-            </a>
-        </div>
-    </div>
-</template>
-
-<script setup>
-import { nextTick, ref } from 'vue'
-
-const isBody = ref(false)
-
-//渲染完成
-nextTick(()=> {
-    isBody.value = true
-})
-</script>
-
-<style lang="scss" scoped>
-.left-pic-content {
-    width: 100%;
-    height: 100%;
-    position: relative;
-    background-image: url(/src/assets/login/bg.png);
-    background-repeat: no-repeat;
-    background-size: 100%;
-    background-position: center;
-    .small-logo {
-        width: 110px;
-        position: absolute;
-        .cons {
-            height: 160px;
-            overflow: hidden;
-        }
-        .logos {
-            width: 100%;
-            margin-top: 30px;
-        }
-        .shadow1 {
-            width: 64px;
-            position: absolute;
-            left: 44%;
-            transform: translateX(-50%);
-            bottom: -16px;
-        }
-    }
-    .cons {
-        position: relative;
-    }
-    .dt {
-        left: 166px;
-        top: 86px;
-        .logos {
-            animation: logoAnimate 4s 0.2s infinite alternate forwards;
-        }
-        .shadow1 {
-            animation: logoShadowAnimate 4s 0.2s infinite alternate forwards;
-        }
-    }
-    .ds {
-        right: 176px;
-        top: 54px;
-        .logos {
-            animation: logoAnimate 2.2s infinite alternate;
-        }
-        .shadow1 {
-            animation: logoShadowAnimate 2.2s infinite alternate;
-        }
-    }
-    .cc {
-        right: 72px;
-        bottom: 160px;
-        .logos {
-            animation: logoAnimate 2.5s 0.5s infinite alternate;
-        }
-        .shadow1 {
-            animation: logoShadowAnimate 2.5s 0.5s infinite alternate;
-        }
-    }
-    .rp {
-        left: 290px;
-        bottom: 76px;
-        .logos {
-            animation: logoAnimate 3s 0.9s infinite alternate;
-        }
-        .shadow1 {
-            animation: logoShadowAnimate 3s 0.9s infinite alternate;
-        }
-    }
-    .cubes {
-        display: block;
-        width: 100%;
-    }
-    .cube1 {
-        width: 48px;
-        right: 60px;
-        top: 180px;
-        position: absolute;
-        .cons {
-            height: 108px;
-            position: relative;
-            overflow: hidden;
-            .cubes {
-                animation: cube1LogoAnimate 2s infinite alternate;
-            }
-            .shadow2 {
-                position: absolute;
-                width: 56px;
-                left: 48%;
-                transform: translateX(-50%);
-                bottom: -16px;
-                animation: cube1ShadowAnimate 2s infinite alternate;
-            }
-        }
-    }
-    .cube2 {
-        position: absolute;
-        width: 56px;
-        left: 130px;
-        bottom: 190px;
-        .cons {
-            position: relative;
-            height: 126px;
-            overflow: hidden;
-            .cubes {
-                animation: cube2LogoAnimate 2s 0.3s infinite alternate;
-            }
-            .shadow3 {
-                position: absolute;
-                width: 64px;
-                left: 48%;
-                transform: translateX(-50%);
-                bottom: -16px;
-                animation: cube2ShadowAnimate 2s 0.3s infinite alternate;
-            }
-        }
-    }
-    .logo {
-        right: 260px;
-        top: 190px;
-        width: 150px;
-        position: absolute;
-        height: 160px;
-        cursor: pointer;
-        .a-cons {
-            width: 100%;
-            height: 100%;
-        }
-    }
-}
-
-//动画效果
-@keyframes logoAnimate {
-    25% {
-        -webkit-transform: translateY(0);
-        -moz-transform: translateY(0);
-        -ms-transform: translateY(0);
-        -o-transform: translateY(0);
-        transform: translateY(0);
-    }
-    100% {
-        -webkit-transform: translateY(-30px);
-        -moz-transform: translateY(-30px);
-        -ms-transform: translateY(-30px);
-        -o-transform: translateY(-30px);
-        transform: translateY(-30px);
-    }
-}
-@keyframes logoShadowAnimate {
-    25% {
-        width: 64px;
-        margin-bottom: 0;
-    }
-    100% {
-        width: 30px;
-        margin-bottom: 20px;
-    }
-}
-@keyframes cube1LogoAnimate {
-    0% {
-        -webkit-transform: translateY(0);
-        -moz-transform: translateY(0);
-        -ms-transform: translateY(0);
-        -o-transform: translateY(0);
-        transform: translateY(0);
-    }
-    100% {
-        -webkit-transform: translateY(30px);
-        -moz-transform: translateY(30px);
-        -ms-transform: translateY(30px);
-        -o-transform: translateY(30px);
-        transform: translateY(30px);
-    }
-}
-@keyframes cube1ShadowAnimate {
-    0% {
-        width: 20px;
-        margin-bottom: 20px;
-    }
-    100% {
-        width: 56px;
-    }
-}
-@keyframes cube2LogoAnimate {
-    0% {
-        margin-top: 30px;
-    }
-    100% {
-        margin-top: 0;
-    }
-}
-@keyframes cube2ShadowAnimate {
-    0% {
-        width: 64px;
-    }
-    100% {
-        width: 30px;
-        margin-bottom: 20px;
-    }
-}
-</style>

+ 20 - 157
src/views/login/index.vue

@@ -1,62 +1,31 @@
 <template>
     <div class="login-body">
-        <a v-if="appLogoIcon" class="left-logo" href="http://hczc.hcxxy.com/" target="_blank">
-            <img id="logo-icon" alt="" :src="appLogoIcon">
-            <span class="logo-name">{{ config.name }}</span>
-        </a>
-        <div class="left-pic-container">
-            <HcPicVue v-if="defer(10)" />
-        </div>
-        <div class="right-container">
-            <div class="right-app-title">{{ config.name }}</div>
-            <div class="sign-list">
-                <h1 class="font-lg">登录</h1>
-                <div class="form-box mt-4">
-                    <el-form ref="formRef" :model="formValue" :rules="formRules" label-position="left" label-width="0px" size="large">
-                        <el-form-item prop="username">
-                            <el-input v-model="formValue.username" clearable placeholder="账号" />
-                        </el-form-item>
-                        <el-form-item class="mt-8" prop="password">
-                            <el-input v-model="formValue.password" clearable placeholder="密码" show-password type="password" @keyup="passwordKeyUp">
-                                <template #suffix>
-                                    <span class="clickable-text" @click="clickableClick">忘记密码</span>
-                                </template>
-                            </el-input>
-                        </el-form-item>
-                        <el-form-item v-if="tenantMode" prop="tenantId">
-                            <el-input v-model="formValue.tenantId" clearable placeholder="租户ID" />
-                        </el-form-item>
-                        <el-form-item>
-                            <el-checkbox v-model="checkbox" label="记住密码" />
-                        </el-form-item>
-                        <el-form-item class="mt-8">
-                            <el-button :loading="loading" block type="primary" @click="formValidateClick">登 录</el-button>
-                        </el-form-item>
-                        <div class="form-protocol" @click="protocolClick">《软件产品用户使用服务协议》</div>
-                    </el-form>
-                </div>
-            </div>
-        </div>
+        <el-form ref="formRef" :model="formValue" :rules="formRules" label-position="left" label-width="0px" size="large">
+            <el-form-item prop="username">
+                <el-input v-model="formValue.username" clearable placeholder="账号" />
+            </el-form-item>
+            <el-form-item class="mt-8" prop="password">
+                <el-input v-model="formValue.password" clearable placeholder="密码" show-password type="password" @keyup="passwordKeyUp"/>
+            </el-form-item>
+            <el-form-item>
+                <el-checkbox v-model="checkbox" label="记住密码" />
+            </el-form-item>
+            <el-form-item class="mt-8">
+                <el-button :loading="loading" block type="primary" @click="formValidateClick">登 录</el-button>
+            </el-form-item>
+        </el-form>
     </div>
 </template>
 
 <script setup>
-import { nextTick, onMounted, ref } from 'vue'
+import { onMounted, ref } from 'vue'
 import { useRouter } from 'vue-router'
 import { useAppStore } from '~src/store'
-import { useAppLogin } from '~sto/user'
-import { getTenantID } from '~api/user'
-import config from '~src/config/index'
-import { getTopUrl, setAppName } from '~uti/tools'
-import HcPicVue from './components/pic.vue'
-import logoIcon from '~src/assets/logo/icon.png'
-import { formValidate, getObjVal, isNullES, setImageColorStyle } from 'js-fast-way'
-import { useDefer } from 'hc-vue3-ui'
-const defer = useDefer()
+import { formValidate } from 'js-fast-way'
 
 //初始化
 const router = useRouter()
-const userStore = useAppStore()
+const store = useAppStore()
 
 //系统信息
 const appLogoIcon = ref('')
@@ -65,25 +34,14 @@ const appLogoIcon = ref('')
 const tenantMode = ref(true)
 
 onMounted(() => {
-    userStore.clearStoreData() //先清理下缓存
-    getTenantIdApi()
-    setAppImageColor()
+    store.clearStoreData() //先清理下缓存
 })
 
-const setAppImageColor = () => {
-    setImageColorStyle('logo-icon', '#1ECC95')
-}
-
 //表单
 const formRef = ref(null)
 const checkbox = ref(false)
-const formValue = ref({ tenantId: '000000', username: '', password: '', type: 'account' })
+const formValue = ref({ username: '', password: '' })
 const formRules = {
-    tenantId: {
-        required: true,
-        message: '请输入租户ID',
-        trigger: 'blur',
-    },
     username: {
         required: true,
         message: '请输入账号',
@@ -101,109 +59,14 @@ const passwordKeyUp = (e) => {
     }
 }
 
-//获取租户id
-const getTenantIdApi = async () => {
-    const { error, code, data } = await getTenantID(getTopUrl())
-    const res = getObjVal(data)
-    if (!error && code === 200 && res) {
-        const { tenantAvatar, tenantAvatarText, tenantTitle, tenantId } = res
-        tenantMode.value = false
-        //设置标题
-        userStore.setTitle(tenantTitle)
-        setAppName(tenantTitle)
-
-        //设置logo图标
-        const logoIconValue = tenantAvatar ? tenantAvatar : logoIcon
-        appLogoIcon.value = logoIconValue
-        userStore.setLogoIcon(logoIconValue)
-
-        //设置logo文字
-        const logoNameValue = tenantAvatarText ? tenantAvatarText : config.name
-        userStore.setLogoName(logoNameValue)
-
-        //设置租户ID
-        formValue.value.tenantId = tenantId
-        userStore.setTenantId(tenantId)
-    } else {
-        tenantMode.value = true
-        //设置标题
-        userStore.setTitle(config.title)
-        setAppName(config.title)
-
-        //设置logo图标
-        appLogoIcon.value = logoIcon
-        userStore.setLogoIcon(logoIcon)
-
-        //设置logo文字
-        userStore.setLogoName(config.name)
-
-        //设置租户ID
-        formValue.value.tenantId = '000000'
-        userStore.setTenantId('000000')
-    }
-    nextTick(() => {
-        setAppImageColor()
-    }).then()
-}
-
 //登录
 const loading = ref(false)
 const formValidateClick = async () => {
     const formRes = await formValidate(formRef.value)
     if (!formRes) return false
-    //登录请求
-    loading.value = true
-    const { error, msg } = await useAppLogin(formValue.value)
-    loading.value = false
-    //登录失败
-    if (error && isNullES(msg)) return false
-    if (error && !isNullES(msg)) {
-        window?.$message?.error(msg)
-        return false
-    }
-    //登录成功
-    window?.$message?.success('登录成功')
-    setTimeout(() => {
-        router.push({ name: 'index' })
-    }, 1500)
-}
-
-//忘记密码
-const clickableClick = () => {
-    const val = '<div style="font-size: 16px;">忘记密码请不要紧张,联系您项目上的专属客服人员电话 <span style="color:#1ECC95;">18423665354</span> ,提供身份证明信息即可初始化密码,建议初始化之后由您单独去更改密码</div>'
-    window?.$messageBox?.alert(val, '联系项目客服', {
-        confirmButtonText: '确定',
-        dangerouslyUseHTMLString: true,
-    })
-}
-
-//协议
-const protocolClick = () => {
-    window.open('https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20231213/73025c8aba72e1165e0731942f6e66c9.pdf', '_blank')
 }
 </script>
 
-<style lang="scss" scoped>
-@import "../../styles/view/login.scss";
-</style>
-
 <style lang="scss">
-@import "../../styles/view/login.dark.scss";
-.form-box {
-    .el-input__wrapper.is-focus {
-        box-shadow: 0 0 0 2px var(--el-input-focus-border-color) inset;
-    }
-    .el-form-item.is-error .el-input__wrapper {
-        box-shadow: 0 0 0 2px var(--el-color-danger) inset;
-    }
-}
-.form-protocol {
-    color: #8C8889;
-    font-size: 13px;
-    cursor: pointer;
-    transition: color 0.3s;
-    &:hover {
-        color: var(--el-color-primary);
-    }
-}
+@import "~src/styles/view/login.scss";
 </style>

+ 0 - 223
src/views/project/list.vue

@@ -1,223 +0,0 @@
-<template>
-    <hc-card v-loading="tableLoading" id-ref="hc-project-list" div-p="12px" body-ui="hc-project-list" scrollbar>
-        <template #header>
-            <div class="w-[354px]">
-                <el-select v-model="projectId" filterable clearable block placeholder="选择项目" @change="projectClick">
-                    <el-option v-for="item in projectData" :key="item.id" :label="item.projectAlias" :value="item.id" />
-                </el-select>
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addProjectClick">创建项目</el-button>
-        </template>
-        <hc-card-item v-for="item in tableData" :key="item.id" class="hc-project-list-card" @click="projectClick(item.id)">
-            <div class="alias">{{ item.projectAlias }}</div>
-            <div class="name">{{ item.projectName }}</div>
-            <div class="footer">
-                <div class="id">{{ item.id }}</div>
-                <div class="time">{{ item.updateTime }}</div>
-            </div>
-        </hc-card-item>
-        <template #action>
-            <hc-pages :pages="searchForm" @change="pageChange" />
-        </template>
-
-        <!-- 查看项目信息 -->
-        <InfoDialog v-model="isProjectInfoDialog" :ids="projectInfoId" @change="projectInfoChange" @check="projectInfoCheck" @close="projectInfoClose" />
-
-        <!-- wbs树管理 -->
-        <HcWbsTree v-model="isWbsTreeDrawer" :type="wbsTreeType" :info="wbsTreeInfo" @change="wbsTreeChange" @close="wbsTreeClose" />
-
-        <!-- 创建或编辑项目信息 -->
-        <hc-drawer v-model="isProjectDrawer" is-close to-id="hc-project-list">
-            创建或编辑项目信息
-        </hc-drawer>
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { getArrValue, getObjValue } from 'js-fast-way'
-import InfoDialog from './modules/list/info-dialog.vue'
-import HcWbsTree from './modules/list/wbs-tree.vue'
-import mainApi from '~api/project/project'
-
-defineOptions({
-    name: 'ProjectList',
-})
-
-//激活
-onActivated(() => {
-    getDataApi()
-})
-
-const getDataApi = async () => {
-    await getProjectData()
-    searchClick()
-}
-
-//项目列表
-const projectData = ref([])
-const projectId = ref('')
-const getProjectData = async () => {
-    const { data } = await mainApi.page({
-        current: 1,
-        size: 999,
-    })
-    projectData.value = getArrValue(data?.records)
-}
-
-//搜索条件
-const searchForm = ref({ current: 1, size: 20, total: 0 })
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//项目数据
-const tableData = ref([])
-//获取表格数据
-const tableLoading = ref(true)
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { error, code, data } = await mainApi.page({
-        ...searchForm.value,
-        total: null,
-    })
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//查看项目信息
-const isProjectInfoDialog = ref(false)
-const projectInfoId = ref('')
-
-//项目被选择
-const projectClick = (id) => {
-    projectInfoId.value = id
-    nextTick(() => {
-        isProjectInfoDialog.value = true
-    })
-}
-const projectInfoChange = () => {
-    searchClick()
-}
-//关闭项目信息
-const projectInfoClose = () => {
-    projectInfoId.value = ''
-    isProjectInfoDialog.value = false
-}
-
-//wbs树管理
-const isWbsTreeDrawer = ref(false)
-const wbsTreeType = ref('')
-const wbsTreeInfo = ref({})
-const wbsTreeChange = () => {
-    searchClick()
-}
-//关闭wbs树关联
-const wbsTreeClose = () => {
-    isWbsTreeDrawer.value = false
-    wbsTreeType.value = ''
-    wbsTreeInfo.value = {}
-}
-
-//功能事件回调
-const projectInfoCheck = ({ type, info, item }) => {
-    //measure, lar, test, wbsTree, logTree, editProject, addContract, editContract, wbsContract
-    //计量管理,征拆划分,实验划分,WBS树管理,日志树管理,编辑项目,创建合同段,编辑合同段信息,分配WBS
-    const wbsArr = ['wbsTree', 'test', 'measure', 'logTree', 'lar']
-    const index = wbsArr.indexOf(type)
-    if (index !== -1) {
-        wbsTreeInfo.value = getObjValue(info)
-        wbsTreeType.value = (index + 1) + ''
-        isWbsTreeDrawer.value = true
-    } else if (type === 'editProject') {
-        console.log('编辑项目')
-    } else if (type === 'addContract') {
-        console.log('创建合同段')
-    } else if (type === 'editContract') {
-        console.log('创建合同段')
-    } else if (type === 'wbsContract') {
-        console.log('分配WBS')
-    }
-    //console.log(type, info, item)
-}
-
-//创建项目或修改项目
-const isProjectDrawer = ref(false)
-const projectDrawerId = ref('')
-
-//创建项目
-const addProjectClick = () => {
-    projectDrawerId.value = ''
-    nextTick(() => {
-        isProjectDrawer.value = true
-    })
-}
-</script>
-
-<style lang="scss">
-.hc-card-item-box.hc-project-list-card {
-    width: 354px;
-    height: 120px;
-    display: inline-block;
-    border-radius: 4px;
-    margin-right: 14px;
-    margin-bottom: 14px;
-    cursor: pointer;
-    background: #f3f3f3 !important;
-    transition: all 0.3s;
-    .alias {
-        font-size: 16px;
-        white-space:nowrap;
-        overflow:hidden;
-        text-overflow:ellipsis;
-        text-align: left;
-    }
-    .name {
-        text-align: left;
-        font-size: 14px;
-        color: #747474;
-        margin-top: 10px;
-        overflow: hidden;
-        text-overflow: ellipsis;  /* 超出部分省略号 */
-        word-break: break-all;  /* 设置省略字母数字 */
-        display: -webkit-box;
-        -webkit-box-orient: vertical;
-        -webkit-line-clamp: 2; /* 显示的行数 */
-    }
-    .footer {
-        position: absolute;
-        color: #747474;
-        display: flex;
-        align-items: center;
-        font-size: 14px;
-        justify-content: space-between;
-        bottom: 0;
-        width: 100%;
-    }
-    &:hover {
-        box-shadow: 2px 2px var(--el-color-primary-light-7);
-    }
-}
-.hc-card-main.hc-project-list {
-    text-align: center;
-}
-</style>

+ 0 - 252
src/views/project/modules/list/info-dialog.vue

@@ -1,252 +0,0 @@
-<template>
-    <hc-dialog v-model="isShow" widths="64rem" is-table title="项目信息" :footer="false" :padding="false" @close="dialogClose">
-        <el-container class="hc-project-info-dialog">
-            <el-header>
-                <div class="left">
-                    <el-button hc-btn color="#626aef" style="color: white" @click="toCheck('measure')">计量管理</el-button>
-                    <el-button hc-btn color="#e233fb" style="color: white" @click="toCheck('lar')">征拆划分</el-button>
-                    <el-button hc-btn color="#ac54ff" style="color: white" @click="toCheck('test')">实验划分</el-button>
-                    <el-button hc-btn type="success" style="color: white" @click="toCheck('wbsTree')">WBS树管理</el-button>
-                    <el-button hc-btn color="#2bbeed" style="color: white" @click="toCheck('logTree')">日志树管理</el-button>
-                </div>
-                <div class="right">
-                    <el-button hc-btn type="warning" @click="toCheck('editProject')">编辑项目</el-button>
-                    <el-button hc-btn type="primary" @click="toCheck('addContract')">创建合同段</el-button>
-                    <el-button v-del-com:[delProject] hc-btn type="danger">删除项目</el-button>
-                </div>
-            </el-header>
-            <el-container>
-                <el-aside width="300px">
-                    <hc-body scrollbar padding="0px">
-                        <hc-list-item title="项目ID:" :content="projectInfo.id" />
-                        <hc-list-item title="项目简称:" :content="projectInfo.projectAlias" />
-                        <hc-list-item title="项目全名:" :content="projectInfo.projectName" />
-                        <hc-list-item title="创建时间:" :content="projectInfo.createTime" />
-                        <hc-list-item title="更新时间:" :content="projectInfo.updateTime" />
-                    </hc-body>
-                </el-aside>
-                <el-main>
-                    <hc-body :scrollbar="contractList.length > 0" padding="0px">
-                        <hc-empty v-if="contractList.length <= 0" />
-                        <hc-card-item v-for="item in contractList" v-else :key="item.id" class="hc-contract-list-card">
-                            <div class="contract-type">
-                                <div v-if="item.contractType === 1" class="name bg-1">施工</div>
-                                <div v-if="item.contractType === 2" class="name bg-2">监理</div>
-                                <div v-if="item.contractType === 3" class="name bg-3">业主</div>
-                            </div>
-                            <div class="contract-content">
-                                <div class="name">{{ item.contractName }}</div>
-                                <div class="footer">
-                                    <div class="time">{{ item.updateTime }}</div>
-                                    <div class="action">
-                                        <el-link type="warning" @click="toCheck('editContract', item)">编辑合同段信息</el-link>
-                                        <el-link v-if="item.contractType === 1" type="success" @click="toCheck('wbsContract', item)">分配WBS</el-link>
-                                        <el-link v-del-com:[delContract]="item" type="danger">删除</el-link>
-                                    </div>
-                                </div>
-                            </div>
-                        </hc-card-item>
-                    </hc-body>
-                </el-main>
-            </el-container>
-        </el-container>
-    </hc-dialog>
-</template>
-
-<script setup>
-import { ref, watch } from 'vue'
-import { deepClone, getArrValue, getObjValue, isNullES } from 'js-fast-way'
-import mainApi from '~api/project/project'
-import contractApi from '~api/project/contract'
-
-const props = defineProps({
-    ids: {
-        type: [String, Number],
-        default: '',
-    },
-})
-
-//事件
-const emit = defineEmits(['change', 'check', 'close'])
-
-//双向绑定
-// eslint-disable-next-line no-undef
-const isShow = defineModel('modelValue', {
-    default: false,
-})
-
-//监听数据
-const projectId = ref(props.ids)
-watch(() => props.ids, (id) => {
-    projectId.value = id
-}, { deep: true })
-
-//监听显示
-watch(isShow, (val) => {
-    if (val) {
-        getProjectInfo()
-    } else {
-        projectInfo.value = {}
-        projectId.value = ''
-        emit('close')
-    }
-})
-
-//获取项目信息
-const projectInfo = ref({})
-const getProjectInfo = async () => {
-    if (isNullES(projectId.value)) return
-    const { data } = await mainApi.detail(projectId.value)
-    projectInfo.value = getObjValue(data)
-    await getContractList(projectId.value)
-}
-
-//获取合同段信息
-const contractList = ref([])
-const getContractList = async (id) => {
-    if (isNullES(id)) return
-    const { data } = await contractApi.getList(id)
-    contractList.value = getArrValue(data)
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    projectId.value = ''
-    projectInfo.value = {}
-    isShow.value = false
-    emit('close')
-}
-
-//删除项目
-const delProject = async (_, resolve) => {
-    if (isNullES(projectId.value)) return
-    const { error, code, msg } = await mainApi.del(projectId.value)
-    if (!error && code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        dialogClose()
-        emit('change')
-    } else {
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//删除合同段
-const delContract = async ({ item }, resolve) => {
-    const { error, code, msg } = await contractApi.del(item.id)
-    resolve()
-    if (!error && code === 200) {
-        window.$message.success('删除成功')
-        getContractList(projectId.value).then()
-    } else {
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//功能事件回调
-const toCheck = (type, item = {}) => {
-    //measure, lar, test, wbsTree, logTree, editProject, addContract, editContract, wbsContract
-    //计量管理,征拆划分,实验划分,WBS树管理,日志树管理,编辑项目,创建合同段,编辑合同段信息,分配WBS
-    const info = deepClone(projectInfo.value)
-    dialogClose()
-    emit('check', { type, info, item })
-}
-</script>
-
-<style lang="scss">
-.el-container.hc-project-info-dialog {
-    position: relative;
-    height: 100%;
-    .el-header {
-        position: relative;
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        --el-header-padding: 0;
-        --el-header-height: 50px;
-        border-bottom: 1px solid #f4f4f4;
-    }
-    .el-aside, .el-main {
-        position: relative;
-        --el-main-padding: 0;
-        .hc-new-main-body {
-            top: 10px;
-        }
-    }
-    .el-aside {
-        border-right: 1px solid #f4f4f4;
-        .hc-new-main-body {
-            right: 10px;
-        }
-    }
-    .el-main .hc-new-main-body {
-        left: 10px;
-    }
-    .hc-list-item .title {
-        width: 70px;
-    }
-    .hc-list-item .content {
-        flex: 1;
-    }
-    .hc-contract-list-card {
-        border-radius: 4px;
-        margin-bottom: 14px;
-        cursor: pointer;
-        padding: 8px 14px;
-        background: #f3f3f3 !important;
-        transition: all 0.3s;
-        .hc-card-item-body {
-            display: flex;
-            align-items: center;
-        }
-        .contract-type {
-            position: relative;
-            margin-right: 14px;
-            .name {
-                position: relative;
-                height: 43px;
-                width: 43px;
-                border-radius: 50px;
-                display: flex;
-                justify-content: center;
-                align-items: center;
-                color: white;
-            }
-            .name.bg-1 {
-                background-color: #2a9b79;
-            }
-            .name.bg-2 {
-                background-color: #9b6c2a;
-            }
-            .name.bg-3 {
-                background-color: #2a359b;
-            }
-        }
-        .contract-content {
-            position: relative;
-            flex: 1;
-            .name {
-                color: #101010;
-                font-weight: bold;
-            }
-            .footer {
-                margin-top: 10px;
-                position: relative;
-                display: flex;
-                align-items: center;
-                justify-content: space-between;
-                .time {
-                    color: #747474;
-                    font-size: 14px;
-                }
-                .el-link  + .el-link{
-                    margin-left: 10px;
-                }
-            }
-        }
-        &:hover {
-            box-shadow: 2px 2px var(--el-color-primary-light-7);
-        }
-    }
-}
-</style>

+ 0 - 324
src/views/project/modules/list/tree-node-edit.vue

@@ -1,324 +0,0 @@
-<template>
-    <hc-dialog v-model="isShow" widths="26rem" title="编辑节点" is-footer-center @close="dialogClose">
-        <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-            <el-form-item label="节点名称:" prop="nodeName">
-                <el-input v-model="formModel.nodeName" clearable class="is-right-btn">
-                    <template #append>
-                        <el-button hc-btn type="primary" @click="aliasShowClick">添加别名</el-button>
-                    </template>
-                </el-input>
-            </el-form-item>
-            <el-form-item label="上级节点:">
-                <el-input v-model="formModel.parentName" disabled />
-            </el-form-item>
-            <el-form-item label="节点类型:" prop="nodeType">
-                <el-select v-model="formModel.nodeType" placeholder="选择节点类型" filterable block>
-                    <el-option v-for="item in nodeTypelist" :key="item.value" :label="item.label" :value="item.value" />
-                </el-select>
-            </el-form-item>
-            <el-form-item v-if="wbsType !== 2 && wbsType !== 5" label="划分编号:">
-                <el-input v-model="formModel.partitionCode" clearable />
-            </el-form-item>
-            <el-form-item v-if="wbsType !== 5" label="唯一编码:">
-                <el-input v-model="formModel.uniqueCode" clearable />
-            </el-form-item>
-            <el-form-item v-if="wbsType === 6" label="是否有混凝土:">
-                <div class="form-item-div">
-                    <el-radio-group v-model="formModel.isConcrete">
-                        <el-radio :value="0">否</el-radio>
-                        <el-radio :value="1">有</el-radio>
-                    </el-radio-group>
-                </div>
-            </el-form-item>
-            <el-form-item v-if="wbsType === 6" label="是否试验节点:">
-                <div class="form-item-div">
-                    <el-radio-group v-model="formModel.isExpernode">
-                        <el-radio :value="0">否</el-radio>
-                        <el-radio :value="1">是</el-radio>
-                    </el-radio-group>
-                </div>
-            </el-form-item>
-            <el-form-item v-if="wbsType !== 2 && wbsType !== 5" label="内业资料类型:" prop="majorDataType">
-                <el-select v-model="formModel.majorDataType" placeholder="选择内业资料类型" filterable block>
-                    <el-option v-for="item in majorDataType" :key="item.value" :label="item.label" :value="item.value" />
-                </el-select>
-            </el-form-item>
-            <el-form-item v-if="wbsType === 2 && formModel.nodeType === 53" label="勾选相关联试验:" prop="mixRatioTestIds" :f="getTestTreeData()">
-                <el-tree-select
-                    v-model="mixRatioTestIds" placeholder="选择勾选相关联试验" show-checkbox clearable filterable multiple block
-                    node-key="id" :data="testData" :props="testProps" :render-after-expand="false" @check="testTreeCheckChange"
-                />
-            </el-form-item>
-        </el-form>
-        <template #footer>
-            <el-button hc-btn @click="dialogClose">取消</el-button>
-            <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-        </template>
-    </hc-dialog>
-
-    <!-- 节点别名 -->
-    <hc-dialog v-model="isAliasShow" widths="26rem" title="节点别名" is-footer-center @close="aliasDialogClose">
-        <el-form ref="formAliasRef" :model="formAliasModel" :rules="formAliasRules" label-position="top" label-width="auto">
-            <el-form-item prop="aliasName">
-                <el-input v-model="formAliasModel.aliasName" placeholder="请输入节点别名" clearable class="is-right-btn">
-                    <template v-if="formModel.pKeyId" #append>
-                        <el-button hc-btn type="primary" @click="addAliasName">添加</el-button>
-                    </template>
-                </el-input>
-            </el-form-item>
-        </el-form>
-        <div v-if="aliasArr.length > 0" class="hc-tree-node-edit-form-alias-name">
-            <template v-for="(item, index) in aliasArr" :key="index">
-                <el-tag closable type="primary" @close="aliasNameClose(index)">{{ item }}</el-tag>
-            </template>
-        </div>
-        <template #footer>
-            <el-button hc-btn @click="aliasDialogClose">取消</el-button>
-            <el-button hc-btn type="primary" :loading="submitAliasLoading" @click="aliasSubmit">提交</el-button>
-        </template>
-    </hc-dialog>
-</template>
-
-<script setup>
-import { ref, watch } from 'vue'
-import { deepClone, formValidate, getArrValue, isNullES } from 'js-fast-way'
-import projectApi from '~api/project/project'
-import privateApi from '~api/wbs/private'
-
-const props = defineProps({
-    node: {
-        type: Object,
-        default: () => ({}),
-    },
-    type: {
-        type: Number,
-        default: 1,
-    },
-    wid: {
-        type: [String, Number],
-        default: '',
-    },
-    pid: {
-        type: [String, Number],
-        default: '',
-    },
-    treeProps: {
-        type: Object,
-        default: () => ({}),
-    },
-    nodeType: {
-        type: Array,
-        default: () => ([]),
-    },
-    majorType: {
-        type: Array,
-        default: () => ([]),
-    },
-})
-
-//事件
-const emit = defineEmits(['change', 'close'])
-
-//双向绑定
-// eslint-disable-next-line no-undef
-const isShow = defineModel('modelValue', {
-    default: false,
-})
-
-//数据变量
-const formModel = ref(props.node)
-const wbsType = ref(props.type)
-const wbsId = ref(props.wid)
-const projectId = ref(props.pid)
-const nodeTypelist = ref(props.nodeType)
-const majorDataType = ref(props.majorType)
-const testProps = ref(props.treeProps)
-
-//监听数据
-watch(() => [
-    props.node,
-    props.type,
-    props.wid,
-    props.pid,
-    props.nodeType,
-    props.majorType,
-    props.treeProps,
-], ([node, type, wid, pid, nodeType, majorType, treeProps]) => {
-    formModel.value = node
-    wbsType.value = type
-    wbsId.value = wid
-    projectId.value = pid
-    nodeTypelist.value = nodeType
-    majorDataType.value = majorType
-    testProps.value = treeProps
-}, { deep: true })
-
-//监听显示
-watch(isShow, (val) => {
-    if (val) {
-        getDataInfo()
-    } else {
-        emit('close')
-    }
-})
-
-//获取数据
-const getDataInfo = () => {
-    const { nodeType } = formModel.value
-    if (nodeType === 53) {
-        getTestTreeData()
-    }
-}
-
-//节点别名
-const isAliasShow = ref(false)
-
-//节点别名
-const formAliasRef = ref(null)
-const formAliasModel = ref({})
-const formAliasRules = {
-    aliasName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入节点别名',
-    },
-}
-
-//显示节点别名弹窗
-const aliasArr = ref([])
-const aliasShowClick = () => {
-    isAliasShow.value = true
-    aliasArr.value = []
-    const { fullName } = deepClone(formModel.value)
-    if (isNullES(fullName)) return
-    aliasArr.value = fullName.split(',')
-}
-
-//添加别名
-const addAliasName = async () => {
-    const formRes = await formValidate(formAliasRef.value)
-    if (!formRes) return false
-    const { aliasName } = deepClone(formAliasModel.value)
-    if (aliasArr.value.indexOf(aliasName) !== -1) {
-        window.$message.warning('请不要重复别名')
-        return
-    }
-    aliasArr.value.push(aliasName)
-    formAliasModel.value.aliasName = ''
-}
-
-//移除别名
-const aliasNameClose = (index) => {
-    aliasArr.value.splice(index, 1)
-}
-
-//提交别名
-const submitAliasLoading = ref(false)
-const aliasSubmit = async () => {
-    submitAliasLoading.value = true
-    const { pKeyId } = formModel.value
-    const fullName = aliasArr.value.join(',')
-    const { error, code, msg } = await privateApi.privateSubmitFullName({
-        pKeyId, fullNames: fullName,
-    })
-    submitAliasLoading.value = false
-    if (!error && code === 200) {
-        aliasDialogClose()
-        window?.$message?.success('操作成功')
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭节点别名弹窗
-const aliasDialogClose = () => {
-    isAliasShow.value = false
-    formAliasModel.value = {}
-}
-
-//获取实验树的数据
-const testData = ref([])
-const mixRatioTestIds = ref([])
-const getTestTreeData = async () => {
-    testData.value = []
-    const { primaryKeyId, pKeyId, mixRatioTestIds: testIds } = formModel.value
-    let pid = primaryKeyId ?? pKeyId
-    const { data } = await projectApi.findProjectTree({
-        projectId: projectId.value,
-        wbsId: wbsId.value,
-        parentId: pid,
-    })
-    testData.value = getArrValue(data)
-    if (!isNullES(testIds)) {
-        mixRatioTestIds.value = testIds?.split(',') ?? []
-    } else {
-        mixRatioTestIds.value = []
-    }
-}
-//监听实验树的勾选
-const testTreeCheckChange = (_, { checkedKeys, halfCheckedKeys }) => {
-    formModel.value.mixRatioTestIds = checkedKeys.join(',')
-}
-
-//菜单表单
-const formRef = ref(null)
-const formRules = {
-    nodeName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入节点名称',
-    },
-    nodeType: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择节点类型',
-    },
-    majorDataType: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择内业资料类型',
-    },
-    mixRatioTestIds: {
-        required: true,
-        trigger: 'blur',
-        message: '请勾选相关联试验',
-    },
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //发起请求
-    const { error, code, msg } = await privateApi.submit(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        emit('change')
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isShow.value = false
-    emit('close')
-}
-</script>
-
-<style lang="scss">
-.hc-tree-node-edit-form-alias-name {
-    position: relative;
-    border: 1px dashed #dcdfe6;
-    border-radius: 4px;
-    padding: 5px 5px 0;
-    .el-tag {
-        margin-right: 5px;
-        margin-bottom: 5px;
-    }
-}
-</style>

+ 0 - 487
src/views/project/modules/list/wbs-tree.vue

@@ -1,487 +0,0 @@
-<template>
-    <hc-drawer v-model="isShow" is-close to-id="hc-project-list">
-        <div class="hc-project-wbs-tree flex">
-            <div class="header hc-flex">
-                <div class="name flex-1">{{ typeLable }} - {{ projectInfo.projectName }}</div>
-                <div class="hc-flex">
-                    <el-dropdown trigger="click">
-                        <el-button hc-btn type="success">
-                            <span>数据同步</span>
-                            <hc-icon name="arrow-down-s" />
-                        </el-button>
-                        <template #dropdown>
-                            <el-dropdown-menu>
-                                <template v-for="item in dataSyncMenu" :key="item.key">
-                                    <el-dropdown-item @click="dataSyncMenuClick(item)">{{ item.name }}</el-dropdown-item>
-                                </template>
-                            </el-dropdown-menu>
-                        </template>
-                    </el-dropdown>
-                    <el-button v-if="isFormSet" class="ml-3" hc-btn type="primary" @click="setIsFormSetValue">表单设置</el-button>
-                    <el-button v-else class="ml-3" hc-btn type="primary" @click="setIsFormSetValue">元素设置</el-button>
-                    <el-button hc-btn type="danger">节点参数</el-button>
-                    <el-button hc-btn color="#626aef">独立表单库</el-button>
-                    <el-button hc-btn type="warning">归档文件时间</el-button>
-                </div>
-            </div>
-            <div class="body">
-                <hc-body split padding="8px">
-                    <template #left>
-                        <hc-card v-loading="isTreeLoading" title="工程节点信息" scrollbar class="is-tree">
-                            <template #search>
-                                <hc-search-input v-model="searchTree.queryValue" @search="searchTreeClick">
-                                    <template #prepend>
-                                        <el-select v-model="searchTree.type" placeholder="类型" style="width: 75px">
-                                            <el-option label="节点" value="1" />
-                                            <el-option label="表名" value="2" />
-                                        </el-select>
-                                    </template>
-                                </hc-search-input>
-                            </template>
-                            <hc-data-tree
-                                v-if="isSearchTree" :h-props="treeProps" :datas="treeLoadData" tree-key="id" :auto-expand-keys="treeExpandKeys"
-                                :menus="treeMenus" @menu-tap="treeMenuClick" @node-tap="treeNodeClick"
-                            />
-                            <hc-lazy-tree
-                                v-else :h-props="treeProps" tree-key="id" :auto-expand-keys="treeExpandKeys"
-                                :menus="treeMenus" @load="treeLoadNode" @menu-tap="treeMenuClick" @node-tap="treeNodeClick"
-                            />
-                        </hc-card>
-                    </template>
-                    <template v-if="isFormSet">
-                        <div class="body-top">
-                            <hc-card title="节点信息">
-                                <hc-table  :is-index="false" :column="nodeTableColumn" :datas="nodeTableData">
-                                    <template #nodeType="{ row }">{{ getDictionaryName(nodeTypelist, row.nodeType, true) }}</template>
-                                </hc-table>
-                            </hc-card>
-                        </div>
-                        <div class="body-content">
-                            <hc-card title="当前项目信息表">
-                                <template #extra>
-                                    <el-button hc-btn type="primary" :disabled="infoTableData.length <= 0">编辑</el-button>
-                                    <el-button hc-btn type="success" :disabled="infoTableData.length <= 0">排序</el-button>
-                                </template>
-                                <hc-table v-loading="infoTableLoading"  :is-index="false" :column="infoTableColumn" :datas="infoTableData">
-                                    <template #tableType="{ row }">{{ getDictionaryName(tableTypelist, row.tableType, true) }}</template>
-                                    <template #tableOwner="{ row }">{{ getDictionaryName(ownerTypeList, row.tableOwner, true) }}</template>
-                                    <template #action="{ row }">
-                                        <el-link type="primary">预览</el-link>
-                                        <el-link v-if="row.status === 1" type="warning">隐藏表单</el-link>
-                                        <el-link v-if="row.status === 0" type="success">取消隐藏</el-link>
-                                        <el-link v-del-com:[delInfoTableRow]="row" type="danger">删除</el-link>
-                                    </template>
-                                </hc-table>
-                            </hc-card>
-                        </div>
-                    </template>
-                    <template v-else>
-                        <hc-card>
-                            <hc-table v-loading="infoTableLoading"  :is-index="false" :column="infoTableColumn1" :datas="infoTableData">
-                                <template #tableType="{ row }">{{ getDictionaryName(tableTypelist, row.tableType, true) }}</template>
-                                <template #isLinkTable="{ row }">{{ row.isLinkTable === 2 ? '是' : '否' }}</template>
-                                <template #tableOwner="{ row }">{{ getDictionaryName(ownerTypeList, row.tableOwner, true) }}</template>
-                                <template #action="{ row }">
-                                    <el-link type="success">关联清表</el-link>
-                                    <el-link type="primary" :disabled="row.excelId === -1 || isNullES(row.excelId)">编辑元素</el-link>
-                                    <el-link type="warning" :disabled="row.excelId === -1 || isNullES(row.excelId)">调整表单</el-link>
-                                    <el-link type="primary">编辑元素公式</el-link>
-                                    <el-link type="warning">表单同步</el-link>
-                                    <el-link v-del-com:[delInfoTableRow]="row" type="danger">删除表单</el-link>
-                                </template>
-                            </hc-table>
-                        </hc-card>
-                    </template>
-                </hc-body>
-            </div>
-        </div>
-        <!-- 编辑节点 -->
-        <TreeNodeEditDialog
-            v-model="isTreeNodeEditShow" :node="treeInfo" :type="Number(isType)" :wid="wbsId" :pid="projectInfo.id" :tree-props="treeProps"
-            :node-type="nodeTypelist" :major-type="majorDataTypeList" @close="treeNodeEditClose" @change="treeNodeEditChange"
-        />
-    </hc-drawer>
-</template>
-
-<script setup>
-import { nextTick, ref, watch } from 'vue'
-import { useAppStore } from '~src/store'
-import { getStore, setStore } from 'hc-vue3-ui'
-import { getArrValue, getObjValue, isNullES } from 'js-fast-way'
-import { getDictionaryData } from '~uti/tools'
-import wbsTreeApi from '~api/wbs/tree'
-import mainApi from '~api/wbs/private'
-import TreeNodeEditDialog from './tree-node-edit.vue'
-
-const props = defineProps({
-    type: {
-        type: [String, Number],
-        default: '1',
-    },
-    info: {
-        type: Object,
-        default: () => ({}),
-    },
-})
-
-//事件
-const emit = defineEmits(['change', 'close'])
-
-//双向绑定
-// eslint-disable-next-line no-undef
-const isShow = defineModel('modelValue', {
-    default: false,
-})
-
-const store = useAppStore()
-
-//监听数据
-const isType = ref(props.type)
-const projectInfo = ref(props.info)
-watch(() => [
-    props.type,
-    props.info,
-], ([type, info]) => {
-    isType.value = type
-    projectInfo.value = info
-}, { deep: true })
-
-//监听显示
-watch(isShow, (val) => {
-    if (val) {
-        getProjectData()
-    } else {
-        projectInfo.value = {}
-        isType.value = ''
-        emit('close')
-    }
-})
-
-//获取项目信息
-const typeLable = ref('')
-const wbsId = ref('')
-const getProjectData = () => {
-    const type = isType.value ?? 1
-    const wbsArr = ['WBS树管理', '实验划分', '计量管理', '日志树管理', '征拆划分']
-    typeLable.value = wbsArr[Number(type) - 1]
-    const wbsIds = [
-        'referenceWbsTemplateId', 'referenceWbsTemplateIdTrial',
-        'referenceWbsTemplateIdMeter', 'referenceLogWbsTemplateId',
-        'referenceWbsTemplateIdLar',
-    ]
-    wbsId.value = projectInfo.value[wbsIds[Number(type) - 1]]
-    console.log('info: ', projectInfo.value)
-    getNodeTypelist(Number(type) - 1)
-    getTableTypelist(Number(type) - 1)
-    getDataTypelist()
-    getOwnerTypelist()
-    getMajorDataTypeList()
-}
-
-//获取节点类型
-const nodeTypelist = ref([])
-const getNodeTypelist = async (type) => {
-    //计量管理,征拆划分,实验划分,WBS树管理,日志树管理
-    const types = ['wbs_node_type', 'trial_node_type', 'meter_node_type', 'wbs_node_type', 'lar_node_type']
-    const data = await getDictionaryData(types[type])
-    nodeTypelist.value = getArrValue(data)
-}
-
-//获取表单类型
-const tableTypelist = ref([])
-const getTableTypelist = async (type) => {
-    //计量管理,征拆划分,实验划分,WBS树管理,日志树管理
-    const types = ['table_type', 'trial_table_type', 'table_type', 'table_type', 'table_type']
-    const data = await getDictionaryData(types[type])
-    tableTypelist.value = getArrValue(data)
-}
-
-//获取数据类型
-const dataTypeList = ref([])
-const getDataTypelist = async () => {
-    const data = await getDictionaryData('data_type')
-    dataTypeList.value = getArrValue(data)
-}
-
-//获取业主类型
-const ownerTypeList = ref([])
-const getOwnerTypelist = async () => {
-    const data = await getDictionaryData('owner_type')
-    ownerTypeList.value = getArrValue(data)
-}
-
-//获取类型字典
-const majorDataTypeList = ref([])
-const getMajorDataTypeList = async () => {
-    const data = await getDictionaryData('major_data_type')
-    majorDataTypeList.value = getArrValue(data)
-}
-
-//获取字典里的数据
-const getDictionaryName = (arr, id, name) => {
-    if (isNullES(id)) return name ? '' : {}
-    const item = arr.find((item) => item.value === Number(id))
-    return name ? item?.label : getObjValue(item)
-}
-
-//树节点搜索
-const isSearchTree = ref(false)
-const isTreeLoading = ref(false)
-const searchTree = ref({ queryValue: '', type: '1' })
-const searchTreeClick = () => {
-    const { queryValue } = searchTree.value
-    isSearchTree.value = !isNullES(queryValue)
-    getTreeLoadData()
-}
-
-//获取搜索树的数据
-const treeLoadData = ref([])
-const getTreeLoadData = async () => {
-    isTreeLoading.value = true
-    const { data } = await wbsTreeApi.getQueryValueByType({
-        ...searchTree.value,
-        wbsId: wbsId.value,
-        projectId: projectInfo.value.id,
-    })
-    treeLoadData.value = getArrValue(data)
-    isTreeLoading.value = false
-}
-
-//树属性
-const treeExpandKeys = ref(getStore('project-wbs-tree-expand-keys') || [])
-const treeProps = {
-    children: 'children',
-    label: 'title',
-    isLeaf: ({ hasChildren, isExistForm, majorDataType, nodeType }) => {
-        let tag = false
-        if (!hasChildren) {
-            tag = true
-        }
-        if (isExistForm === 1) {
-            tag = true
-        }
-        if (nodeType >= 6 && nodeType <= 13) {
-            tag = true
-        }
-        //中间交工。开工报告、质量评定)
-        if (majorDataType >= 1 && majorDataType <= 3) {
-            tag = true
-        }
-        return tag
-    },
-}
-
-//树的右键菜单
-const treeMenus = [
-    { icon: 'draft', label: '编辑节点', key: 'edit' },
-    { icon: 'refresh', label: '同步新增元素表单', key: 'sync1' },
-    { icon: 'loop-left', label: '同步元素表单排序到合同段', key: 'sync3' },
-    { icon: 'loop-right', label: '同步节点基础信息及表单URL', key: 'sync2' },
-    { icon: 'sort-asc', label: '调整排序', key: 'sort' },
-    { icon: 'delete-bin', label: '删除节点', key: 'del' },
-]
-//菜单被点击
-const treeMenuItem = ref({})
-const treeMenuClick = async ({ key, node, data }) => {
-    if (key === 'edit') { //编辑节点
-        data.parentName = node?.parent?.data?.title ?? '' //获取父节点名称
-        treeItem.value = data
-        await getTreeDetail()
-        await nextTick()
-        isTreeNodeEditShow.value = true
-    } else if (key === 'sync1') {
-        //同步新增元素表单
-    } else if (key === 'sync3') {
-        //同步元素表单排序到合同段
-    } else if (key === 'sync2') {
-        //同步节点基础信息及表单URL
-    } else if (key === 'sort') {
-        //调整排序
-    } else if (key === 'del') {
-        //删除节点
-    }
-}
-
-//编辑节点
-const isTreeNodeEditShow = ref(false)
-//编辑节点被关闭
-const treeNodeEditClose = () => {
-    isTreeNodeEditShow.value = false
-    treeMenuItem.value = {}
-}
-//编辑节点被修改
-const treeNodeEditChange = () => {
-    isTreeNodeEditShow.value = false
-    treeMenuItem.value = {}
-    console.log('编辑节点被修改')
-}
-
-//懒加载树
-const treeLoadNode = async ({ item, level }, resolve) => {
-    let pid = level !== 0 ? item.id : 0
-    const { data } = await mainApi.getLazytree({
-        wbsId: wbsId.value,
-        parentId: pid,
-        tenantId: store.tenantId,
-        projectId: projectInfo.value.id,
-        wbsType: isType.value,
-    })
-    resolve(getArrValue(data))
-}
-
-//节点信息
-const nodeTableColumn = ref([
-    { key: 'nodeName', name: '当前节点', align: 'center' },
-    { key: 'nodeType', name: '节点类型', align: 'center' },
-    { key: 'parentName', name: '上级节点', align: 'center' },
-])
-const nodeTableData = ref([])
-
-//节点被点击
-const treeItem = ref({})
-const treeNodeClick = ({ node, data, keys }) => {
-    //获取父节点名称
-    let parentName = ''
-    if (node?.parent?.data) {
-        parentName = node.parent.data.title ?? ''
-    }
-    data.parentName = parentName
-    //设置相关数据
-    treeItem.value = getObjValue(data)
-    setStore('project-wbs-tree-expand-keys', keys)
-    treeExpandKeys.value = getArrValue(keys)
-    //获取节点详情
-    getTreeDetail()
-    getInfoTableData()
-}
-
-//获取节点详情
-const treeInfo = ref({})
-const getTreeDetail = async () => {
-    const { id, parentName } = treeItem.value
-    const { data } = await mainApi.detail({
-        id,
-        wbsId: wbsId.value,
-        projectId: projectInfo.value.id,
-    })
-    const res = getObjValue(data)
-    res.parentName = parentName
-    treeInfo.value = res
-    nodeTableData.value = [res]
-}
-
-//当前项目信息表
-const infoTableLoading = ref(false)
-const infoTableColumn = ref([
-    { key: 'tableName', name: '表单名称', align: 'center' },
-    { key: 'elementTotal', name: '字段总量', align: 'center' },
-    { key: 'fillRate', name: '填报率', align: 'center' },
-    { key: 'tableType', name: '表单类型', align: 'center' },
-    { key: 'tableOwner', name: '所属方', align: 'center' },
-    { key: 'action', name: '操作', width: 160, align: 'center' },
-])
-const infoTableData = ref([])
-const getInfoTableData = async () => {
-    const { id } = treeItem.value
-    infoTableLoading.value = true
-    const { data } = await mainApi.findNodeTableByCondition({
-        parentId: id,
-        wbsId: wbsId.value,
-        projectId: projectInfo.value.id,
-    })
-    infoTableData.value = getArrValue(data)
-    infoTableLoading.value = false
-}
-
-//当前项目信息表删除
-const delInfoTableRow = async ({ item }, resolve) => {
-    const { error, code, msg } = await mainApi.removeTableByCondition({
-        id: item.id,
-        wbsId: wbsId.value,
-        projectId: projectInfo.value.id,
-    })
-    resolve()
-    if (!error && code === 200) {
-        window.$message.success('删除成功')
-        getInfoTableData().then()
-    } else {
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//表单设置
-const isFormSet = ref(true)
-const infoTableColumn1 = ref([
-    { key: 'tableName', name: '表单名称', align: 'center' },
-    { key: 'tableType', name: '表单类型', align: 'center' },
-    { key: 'fillRate', name: '填报率', align: 'center' },
-    { key: 'isLinkTable', name: '是否关联清表', align: 'center' },
-    { key: 'tableOwner', name: '所属方', align: 'center' },
-    { key: 'action', name: '操作', width: 430, align: 'center' },
-])
-const setIsFormSetValue = () => {
-    isFormSet.value = !isFormSet.value
-    if (isFormSet.value) {
-        getTreeDetail()
-    }
-    getInfoTableData()
-}
-
-//数据同步按钮菜单
-const dataSyncMenu = [
-    { key: 'jdSync', name: '节点参数同步', load:false },
-    { key: 'dqSync', name: '电签同步', load:false },
-    { key: 'gsSync', name: '公式同步', load:false },
-]
-const dataSyncMenuClick = (item) => {
-    console.log( item)
-}
-</script>
-
-<style scoped lang="scss">
-.hc-project-wbs-tree {
-    position: relative;
-    background: #ececec;
-    border-radius: 4px;
-    height: 100%;
-    flex-direction: column;
-    overflow: hidden;
-    .header {
-        color: white;
-        background: #54565A;
-        padding: 10px 14px;
-        flex-shrink: 0;
-        .name {
-            white-space:nowrap;
-            overflow:hidden;
-            text-overflow:ellipsis;
-        }
-    }
-    .body {
-        flex: 1;
-        flex-basis: auto;
-        position: relative;
-    }
-}
-</style>
-
-<style lang="scss">
-.hc-project-wbs-tree .body {
-    .el-card.hc-card-box {
-        --el-card-padding: 12px;
-        --el-card-border-radius: 5px;
-    }
-    .hc-page-split-content {
-        position: relative;
-        .body-top {
-            position: relative;
-            height: 119.5px;
-        }
-        .body-content {
-            position: relative;
-            margin-top: 10px;
-            height: calc(100% - 129.5px);
-        }
-    }
-}
-</style>

+ 0 - 13
src/views/project/tree.vue

@@ -1,13 +0,0 @@
-<template>
-    <div>项目树</div>
-</template>
-
-<script setup>
-defineOptions({
-    name: 'ProjectTree',
-})
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 179
src/views/resource/attach.vue

@@ -1,179 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-32">
-                <el-select v-model="searchType" placeholder="选择搜索类型" filterable block>
-                    <el-option label="附件域名" value="domainUrl" />
-                    <el-option label="附件名称" value="name" />
-                    <el-option label="附件原名" value="originalName" />
-                </el-select>
-            </div>
-            <div class="ml-2 w-60">
-                <hc-search-input v-model="searchName" placeholder="请输入关键词" @search="searchClick" />
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addUploadClick">
-                <hc-icon name="upload" />
-                <span>上传</span>
-            </el-button>
-            <el-button hc-btn type="danger" @click="delClick">
-                <hc-icon name="delete-bin" />
-                <span>删除</span>
-            </el-button>
-        </template>
-        <hc-table
-            :column="tableColumn" :datas="tableData" :loading="tableLoading"
-            :is-index="false" is-check :check-style="{ width: 29 }"
-            @selection-change="tableCheckChange"
-        >
-            <template #attachSize="{ row }">{{ getRowFilterSize(row) }}</template>
-            <template #action="{ row }">
-                <el-link type="primary" :href="row.link">下载</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-        <template #action>
-            <hc-pages :pages="searchForm" @change="pageChange" />
-        </template>
-
-        <!-- 上传文件 -->
-        <hc-dialog v-model="isUploadShow" widths="460px" :footer="false" title="上传文件" @close="uploadClose">
-            <hc-form-upload v-model="uploadFileSrc" :options="{ type: 'list' }" :upload="{ options: uploadFileConfig }" />
-        </hc-dialog>
-    </hc-card>
-</template>
-
-<script setup>
-import { onActivated, ref } from 'vue'
-import { HcDelMsg } from 'hc-vue3-ui'
-import { arrToId, filterSize, getArrValue } from 'js-fast-way'
-import mainApi from '~api/resource/attach'
-
-defineOptions({
-    name: 'Attach',
-})
-
-//激活
-onActivated(() => {
-    searchClick()
-})
-
-//搜索表单
-const searchType = ref('originalName')
-const searchName = ref('')
-const searchForm = ref({ current: 1, size: 30, total: 0 })
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableColumn = ref([
-    { key: 'originalName', name: '原名', width: 240 },
-    { key: 'extension', name: '拓展名', width: 80 },
-    { key: 'attachSize', name: '大小', width: 100 },
-    { key: 'link', name: '资源地址' },
-    { key: 'updateTime', name: '上传日期', width: 160 },
-    { key: 'action', name: '操作', width: 90, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { error, code, data } = await mainApi.page({
-        ...searchForm.value,
-        total: null,
-    })
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//获取过滤后的大小
-const getRowFilterSize = ({ attachSize }) => {
-    return attachSize ? filterSize(attachSize) : attachSize + 'B'
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//上传文件
-const uploadFileSrc = ref('')
-const uploadFileConfig = {
-    url: '/api/blade-resource/oss/endpoint/put-file-attach',
-    accept: '*',
-    accept_tip: '不限制',
-    size: 1024,
-    num: 0,
-    multiple: true,
-}
-
-//新增
-const isUploadShow = ref(false)
-const addUploadClick = () => {
-    isUploadShow.value = true
-}
-
-//关闭上传
-const uploadClose = () => {
-    isUploadShow.value = false
-}
-
-//删除
-const delRowClick = async ({ item }, resolve)=> {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的数据')
-        return false
-    }
-    //确认删除菜单
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            getTableData().then()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-</script>

+ 0 - 401
src/views/resource/oss.vue

@@ -1,401 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-40">
-                <el-select v-model="searchForm.category" placeholder="请选择分类" filterable clearable block>
-                    <el-option v-for="item in categoryData" :key="item.value" :label="item.label" :value="item.value" />
-                </el-select>
-            </div>
-            <div class="ml-2 w-32">
-                <el-select v-model="searchType" placeholder="选择搜索类型" filterable block>
-                    <el-option label="资源编号" value="ossCode" />
-                    <el-option label="accessKey" value="accessKey" />
-                </el-select>
-            </div>
-            <div class="ml-2 w-60">
-                <hc-search-input v-model="searchName" placeholder="请输入关键词" @search="searchClick" />
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-            <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-        </template>
-        <hc-table
-            :column="tableColumn" :datas="tableData" :loading="tableLoading"
-            :is-index="false"  is-check :check-style="{ width: 29 }"
-            @selection-change="tableCheckChange"
-        >
-            <template #category="{ row }">{{ getCategoryName(row) }}</template>
-            <template #status="{ row }">{{ row.statusName ?? '否' }}</template>
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-                <el-link type="success" @click="debugRowClick(row)">调试</el-link>
-                <el-link v-yes-com:[enableRowClick]="row" type="primary">启用</el-link>
-            </template>
-        </hc-table>
-        <template #action>
-            <hc-pages :pages="searchForm" @change="pageChange" />
-        </template>
-
-        <!-- 新增/修改 -->
-        <hc-dialog v-model="isDialogShow" widths="60rem" is-footer-center :title="dialogTitle" @close="dialogClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-row :gutter="20">
-                    <el-col :span="12">
-                        <el-form-item label="存储分类:" prop="category">
-                            <div class="form-item-div">
-                                <el-radio-group v-model="formModel.category">
-                                    <el-radio v-for="item in categoryData" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
-                                </el-radio-group>
-                            </div>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="资源编号:" prop="ossCode">
-                            <el-input v-model="formModel.ossCode" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="资源地址:" prop="endpoint">
-                            <el-input v-model="formModel.endpoint" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="空间名:" prop="bucketName">
-                            <el-input v-model="formModel.bucketName" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="accessKey:" prop="accessKey">
-                            <el-input v-model="formModel.accessKey" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="secretKey:" prop="secretKey">
-                            <el-input v-model="formModel.secretKey" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-if="formModel.category === 4" :span="12">
-                        <el-form-item label="appId:">
-                            <el-input v-model="formModel.appId" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-if="formModel.category === 4" :span="12">
-                        <el-form-item label="region:">
-                            <el-input v-model="formModel.region" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="备注说明:">
-                            <el-input v-model="formModel.remark" clearable />
-                        </el-form-item>
-                    </el-col>
-                </el-row>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-
-        <!-- 上传调试 -->
-        <hc-dialog v-model="isDebugShow" widths="400px" :footer="false" title="上传调试" @close="debugClose">
-            <el-form :model="debugForm" label-position="top" label-width="auto">
-                <el-form-item label="资源编号:">
-                    <el-input v-model="debugForm.ossCode" disabled />
-                </el-form-item>
-                <el-form-item label="上传图片:">
-                    <el-upload class="avatar-uploader" :headers="getHeader()" :action="actionUrl" accept="image/*" :show-file-list="false" :on-success="handleAvatarSuccess">
-                        <img v-if="debugForm.url" :src="debugForm.url" class="avatar" alt="">
-                        <hc-icon v-else class="avatar-uploader-icon" name="add-large" />
-                    </el-upload>
-                </el-form-item>
-                <el-form-item label="回调地址:">
-                    <el-input v-model="debugForm.url" />
-                </el-form-item>
-            </el-form>
-        </hc-dialog>
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { HcDelMsg, getHeader } from 'hc-vue3-ui'
-import { getDictionaryData } from '~uti/tools'
-import { arrToId, formValidate, getArrValue, isNullES } from 'js-fast-way'
-import mainApi from '~api/resource/oss'
-
-defineOptions({
-    name: 'Oss',
-})
-
-//激活
-onActivated(() => {
-    getDataApi()
-})
-
-const getDataApi = async () => {
-    await getCategoryData()
-    searchClick()
-}
-
-//搜索表单
-const searchType = ref('ossCode')
-const searchName = ref('')
-const searchForm = ref({ category: null, current: 1, size: 30, total: 0 })
-
-//获取字典数据
-const categoryData = ref([])
-const getCategoryData = async () => {
-    categoryData.value = await getDictionaryData('oss')
-}
-const getCategoryName = ({ category }) => {
-    if (isNullES(category)) return '-'
-    const item = categoryData.value.find((item) => item.value === category)
-    if (isNullES(item)) return category
-    return item.label ?? category
-}
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableColumn = ref([
-    { key: 'category', name: '分类', width: 80, align: 'center' },
-    { key: 'ossCode', name: '资源编号', width: 120 },
-    { key: 'endpoint', name: '资源地址' },
-    { key: 'bucketName', name: '空间名' },
-    { key: 'accessKey', name: 'accessKey' },
-    { key: 'secretKey', name: 'secretKey' },
-    { key: 'remark', name: '备注' },
-    { key: 'status', name: '是否启用', width: 80, align: 'center' },
-    { key: 'action', name: '操作', width: 160, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { error, code, data } = await mainApi.page({
-        ...searchForm.value,
-        total: null,
-    })
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const dialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    category: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择存储分类',
-    },
-    ossCode: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入资源编号',
-    },
-    endpoint: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入资源地址',
-    },
-    bucketName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入空间名',
-    },
-    accessKey: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入accessKey',
-    },
-    secretKey: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入secretKey',
-    },
-}
-
-
-//新增
-const addClick = () => {
-    dialogTitle.value = '新增对象存储'
-    formModel.value = { category: 1 }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改菜单
-const editRowClick = (row) => {
-    formModel.value = {}
-    dialogTitle.value = '修改对象存储'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        getTableData().then()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-
-//上传调试
-const isDebugShow = ref(false)
-const debugForm = ref({})
-const actionUrl = ref('')
-const debugRowClick = (row) => {
-    debugForm.value = { ossCode: row.ossCode, url: '' }
-    actionUrl.value = '/api/blade-resource/oss/endpoint/put-file?code=' + row.ossCode
-    isDebugShow.value = true
-}
-const handleAvatarSuccess = ({ code, data, msg }) => {
-    if (code !== 200 || isNullES(data.link)) {
-        window.$message.error(msg ?? '上传失败')
-        return false
-    }
-    window.$message.success('上传成功')
-    debugForm.value.url = data.link
-}
-const debugClose = () => {
-    isDebugShow.value = false
-    debugForm.value = {}
-}
-
-
-//启用
-const enableRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.enable(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('启用成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '启用失败')
-    }
-}
-
-//删除
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的数据')
-        return false
-    }
-    //确认删除菜单
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            getTableData().then()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-</script>
-
-<style lang="scss">
-.avatar-uploader {
-    width: 100%;
-    height: 178px;
-    .el-upload {
-        width: 100%;
-        height: 178px;
-        border: 1px dashed #dcdfe6;
-        border-radius: 6px;
-        cursor: pointer;
-        position: relative;
-        overflow: hidden;
-        transition: var(--el-transition-duration-fast);
-    }
-    .el-upload:hover {
-        border-color: var(--el-color-primary);
-    }
-    .avatar {
-        width: 100%;
-        height: 100%;
-        border-radius: 6px;
-        display: block;
-    }
-    .avatar-uploader-icon {
-        font-size: 28px;
-        color: #8c939d;
-    }
-}
-</style>

+ 0 - 442
src/views/resource/sms.vue

@@ -1,442 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-40">
-                <el-select v-model="searchForm.category" placeholder="请选择分类" filterable clearable block>
-                    <el-option v-for="item in categoryData" :key="item.value" :label="item.label" :value="item.value" />
-                </el-select>
-            </div>
-            <div class="ml-2 w-32">
-                <el-select v-model="searchType" placeholder="选择搜索类型" filterable block>
-                    <el-option label="资源编号" value="smsCode" />
-                    <el-option label="模版ID" value="templateId" />
-                </el-select>
-            </div>
-            <div class="ml-2 w-60">
-                <hc-search-input v-model="searchName" placeholder="请输入关键词" @search="searchClick" />
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-            <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-        </template>
-        <hc-table
-            :column="tableColumn" :datas="tableData" :loading="tableLoading"
-            :is-index="false"  is-check :check-style="{ width: 29 }"
-            @selection-change="tableCheckChange"
-        >
-            <template #category="{ row }">{{ getCategoryName(row) }}</template>
-            <template #status="{ row }">{{ row.statusName ?? '否' }}</template>
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-                <el-link type="success" @click="debugRowClick(row)">调试</el-link>
-                <el-link v-yes-com:[enableRowClick]="row" type="primary">启用</el-link>
-            </template>
-        </hc-table>
-        <template #action>
-            <hc-pages :pages="searchForm" @change="pageChange" />
-        </template>
-
-        <!-- 新增/修改 -->
-        <hc-dialog v-model="isDialogShow" widths="55rem" is-footer-center :title="dialogTitle" @close="dialogClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-row :gutter="20">
-                    <el-col :span="12">
-                        <el-form-item label="短信分类:" prop="category">
-                            <div class="form-item-div">
-                                <el-radio-group v-model="formModel.category">
-                                    <el-radio v-for="item in categoryData" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
-                                </el-radio-group>
-                            </div>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="资源编号:" prop="smsCode">
-                            <el-input v-model="formModel.smsCode" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-if="formModel.category !== 1" :span="12">
-                        <el-form-item label="模版ID:" prop="templateId">
-                            <el-input v-model="formModel.templateId" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-else :span="12">
-                        <el-form-item label="模版内容:" prop="templateContent">
-                            <el-input v-model="formModel.templateId" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-if="formModel.category > 1" :span="12">
-                        <el-form-item label="短信签名:" prop="signName">
-                            <el-input v-model="formModel.signName" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-if="formModel.category === 1" :span="12">
-                        <el-form-item label="apiKey:" prop="apiKey">
-                            <el-input v-model="formModel.accessKey" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-else-if="formModel.category === 4" :span="12">
-                        <el-form-item label="appId:" prop="appId">
-                            <el-input v-model="formModel.accessKey" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-else :span="12">
-                        <el-form-item label="accessKey:" prop="accessKey">
-                            <el-input v-model="formModel.accessKey" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-if="formModel.category === 4" :span="12">
-                        <el-form-item label="appKey:" prop="appKey">
-                            <el-input v-model="formModel.secretKey" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-else-if="formModel.category !== 1" :span="12">
-                        <el-form-item label="secretKey:" prop="secretKey">
-                            <el-input v-model="formModel.secretKey" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-if="formModel.category === 3" :span="12">
-                        <el-form-item label="regionId:">
-                            <el-input v-model="formModel.regionId" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-if="formModel.category === 1" :span="12">
-                        <el-form-item label="短信签名:" prop="signName">
-                            <el-input v-model="formModel.signName" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="备注说明:">
-                            <el-input v-model="formModel.remark" clearable />
-                        </el-form-item>
-                    </el-col>
-                </el-row>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-
-        <!-- 短信发送调试 -->
-        <hc-dialog v-model="isDebugShow" widths="400px" is-footer-center title="短信发送调试" @close="debugClose">
-            <el-form ref="debugFormRef" :model="debugForm" :rules="debugFormRules" label-position="top" label-width="auto">
-                <el-form-item label="资源编号:" prop="code">
-                    <el-input v-model="debugForm.code" disabled />
-                </el-form-item>
-                <el-form-item label="发送手机:" prop="phones">
-                    <el-input v-model="debugForm.phones" />
-                </el-form-item>
-                <el-form-item label="发送参数:" prop="params">
-                    <el-input v-model="debugForm.params" placeholder="例: {'code':2333,'title':'通知标题'}" />
-                </el-form-item>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="debugClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="debugLoading" @click="debugSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { getDictionaryData } from '~uti/tools'
-import { arrToId, formValidate, getArrValue, isNullES } from 'js-fast-way'
-import { HcDelMsg } from 'hc-vue3-ui'
-import mainApi from '~api/resource/sms'
-
-defineOptions({
-    name: 'Sms',
-})
-
-//激活
-onActivated(() => {
-    getDataApi()
-})
-
-const getDataApi = async () => {
-    await getCategoryData()
-    searchClick()
-}
-
-//搜索表单
-const searchType = ref('smsCode')
-const searchName = ref('')
-const searchForm = ref({ category: null, current: 1, size: 30, total: 0 })
-
-//获取字典数据
-const categoryData = ref([])
-const getCategoryData = async () => {
-    categoryData.value = await getDictionaryData('sms')
-}
-const getCategoryName = ({ category }) => {
-    if (isNullES(category)) return '-'
-    const item = categoryData.value.find((item) => item.value === category)
-    if (isNullES(item)) return category
-    return item.label ?? category
-}
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableColumn = ref([
-    { key: 'category', name: '分类', width: 80, align: 'center' },
-    { key: 'smsCode', name: '资源编号', width: 120 },
-    { key: 'templateId', name: '模版ID' },
-    { key: 'accessKey', name: 'accessKey' },
-    { key: 'secretKey', name: 'secretKey' },
-    { key: 'regionId', name: 'regionId' },
-    { key: 'signName', name: '短信签名' },
-    { key: 'remark', name: '备注' },
-    { key: 'status', name: '是否启用', width: 80, align: 'center' },
-    { key: 'action', name: '操作', width: 160, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { error, code, data } = await mainApi.page({
-        ...searchForm.value,
-        total: null,
-    })
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const dialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    category: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择短信分类',
-    },
-    smsCode: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入资源编号',
-    },
-    templateId: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入模版ID',
-    },
-    templateContent: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入模版内容',
-    },
-    signName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入短信签名',
-    },
-    apiKey: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入apiKey',
-    },
-    appId: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入appId',
-    },
-    accessKey: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入accessKey',
-    },
-    appKey: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入appKey',
-    },
-    secretKey: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入secretKey',
-    },
-}
-
-//新增
-const addClick = () => {
-    dialogTitle.value = '新增短信配置'
-    formModel.value = { category: 1, regionId: 'cn-hangzhou' }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改
-const editRowClick = (row) => {
-    formModel.value = {}
-    dialogTitle.value = '修改短信配置'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        getTableData().then()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-
-//短信发送调试
-const isDebugShow = ref(false)
-const debugFormRef = ref(null)
-const debugForm = ref({})
-const debugFormRules = {
-    code: {
-        required: true,
-        trigger: 'blur',
-        message: '资源编号不能为空',
-    },
-    phones: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入手机号',
-    },
-    params: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入发送参数',
-    },
-}
-const debugRowClick = (row) => {
-    debugForm.value = {
-        code: row.smsCode,
-        phones: '',
-        params: '',
-    }
-    isDebugShow.value = true
-}
-
-//提交调试
-const debugLoading = ref(false)
-const debugSubmit = async () => {
-    const formRes = await formValidate(debugFormRef.value)
-    if (!formRes) return false
-    debugLoading.value = true
-    //发起请求
-    const { error, code, msg } = await mainApi.send(debugForm.value)
-    if (!error && code === 200) {
-        debugClose()
-        window?.$message?.success(msg)
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-const debugClose = () => {
-    isDebugShow.value = false
-    debugLoading.value = false
-    debugForm.value = {}
-}
-
-
-//启用
-const enableRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.enable(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('启用成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '启用失败')
-    }
-}
-
-//删除
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的数据')
-        return false
-    }
-    //确认删除菜单
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            getTableData().then()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-</script>

+ 0 - 478
src/views/system/app.vue

@@ -1,478 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-60">
-                <hc-search-input v-model="searchForm.name" placeholder="请输入名称关键词" @search="searchClick" />
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-        </template>
-        <hc-table :column="tableColumn" :datas="tableData" :loading="tableLoading" :index-style="{ width: 60 }">
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link type="primary" @click="updateRowClick(row)">升级</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-        <template #action>
-            <hc-pages :pages="searchForm" @change="pageChange" />
-        </template>
-        <!-- 新增/修改 -->
-        <hc-dialog v-model="isDialogShow" widths="44rem" is-footer-center :title="dialogTitle" @close="dialogClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-row :gutter="20">
-                    <el-col :span="12">
-                        <el-form-item label="应用平台:" prop="platform">
-                            <el-input v-model="formModel.platform" clearable placeholder="请输入应用平台" />
-                        </el-form-item>
-                        <el-form-item label="应用名称:" prop="name">
-                            <el-input v-model="formModel.name" clearable placeholder="请输入应用名称" />
-                        </el-form-item>
-                        <el-form-item label="当前版本:" prop="currentVersion">
-                            <el-input v-model="formModel.currentVersion" clearable placeholder="请输入当前版本号" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="应用说明:">
-                            <el-input v-model="formModel.appExplain" :autosize="{ minRows: 9, maxRows: 9 }" type="textarea" placeholder="请输入应用说明" />
-                        </el-form-item>
-                    </el-col>
-                </el-row>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-
-        <!-- APP升级列表 -->
-        <hc-dialog v-model="isUpdateDialog" ui="hc-app-update-dialog" widths="700px" is-table @close="updateDialogClose">
-            <template #header>
-                <el-button hc-btn type="primary" @click="addUpdateClick">新增版本</el-button>
-                <div class="hc-update-dialog-title">{{ updateDialogTitle }}</div>
-            </template>
-            <hc-table :column="tableUpdateColumn" :datas="tableUpdateData" :loading="tableUpdateLoading" :index-style="{ width: 60 }">
-                <template #softwareType="{ row }">
-                    {{ row.softwareType === 1 ? '安卓' : 'IOS' }}
-                </template>
-                <template #fileType="{ row }">
-                    {{ row.fileType === 0 ? '完整' : 'wgt' }}
-                </template>
-                <template #constraintUpdate="{ row }">
-                    {{ row.fileType === 1 ? '是' : '否' }}
-                </template>
-                <template #action="{ row }">
-                    <el-link type="warning" @click="editUpdateRow(row)">修改</el-link>
-                    <el-link v-del-com:[delUpdateRow]="row" type="danger">删除</el-link>
-                </template>
-            </hc-table>
-            <template #footer>
-                <hc-pages :pages="searchUpdateForm" @change="pageUpdateChange" />
-            </template>
-        </hc-dialog>
-
-        <!-- 新增/修改 APP升级 -->
-        <hc-dialog v-model="isUpdateFormDialog" widths="550px" is-footer-center :title="updateFormTitle" @close="updateFormDialogClose">
-            <el-form ref="formUpdateRef" :model="formUpdateModel" :rules="formUpdateRules" label-position="left" label-width="auto">
-                <el-form-item label="当前版本:" prop="versionNumber">
-                    <el-input v-model="formUpdateModel.versionNumber" clearable placeholder="请输入当前版本号" />
-                </el-form-item>
-                <el-form-item label="软件类型:" prop="softwareType">
-                    <el-radio-group v-model="formUpdateModel.softwareType">
-                        <el-radio :value="1">安卓</el-radio>
-                        <el-radio :value="2">ios</el-radio>
-                        <el-radio :value="3">win</el-radio>
-                        <el-radio :value="4">mac</el-radio>
-                    </el-radio-group>
-                </el-form-item>
-                <el-form-item v-if="formUpdateModel.softwareType <= 2" label="文件类型:" prop="fileType">
-                    <el-radio-group v-model="formUpdateModel.fileType">
-                        <el-radio :value="0">完整安装包</el-radio>
-                        <el-radio :value="1">wgt热更新包</el-radio>
-                    </el-radio-group>
-                </el-form-item>
-                <el-form-item v-if="formUpdateModel.softwareType === 3" label="文件类型:" prop="fileType">
-                    <el-radio-group v-model="formUpdateModel.fileType">
-                        <el-radio :value="0">win</el-radio>
-                        <el-radio :value="1">arm</el-radio>
-                    </el-radio-group>
-                </el-form-item>
-                <el-form-item v-if="formUpdateModel.softwareType === 4" label="文件类型:" prop="fileType">
-                    <el-radio-group v-model="formUpdateModel.fileType">
-                        <el-radio :value="0">intel</el-radio>
-                        <el-radio :value="1">M系列</el-radio>
-                    </el-radio-group>
-                </el-form-item>
-                <el-form-item label="更新内容:" prop="updateContent">
-                    <el-input v-model="formUpdateModel.updateContent" :autosize="{ minRows: 4, maxRows: 8 }" type="textarea" placeholder="请输入更新内容" />
-                </el-form-item>
-                <el-form-item label="文件地址:" prop="fileUrl">
-                    <hc-form-upload v-model="formUpdateModel.fileUrl" :upload="{ options: uploadOptions }" />
-                </el-form-item>
-                <el-form-item label="强制更新:" prop="constraintUpdate">
-                    <el-radio-group v-model="formUpdateModel.constraintUpdate">
-                        <el-radio :value="1">是</el-radio>
-                        <el-radio :value="0">否</el-radio>
-                    </el-radio-group>
-                </el-form-item>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="updateFormDialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitUpdateLoading" @click="dialogUpdateSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { formValidate, getArrValue } from 'js-fast-way'
-import mainApi from '~api/system/app'
-
-defineOptions({
-    name: 'App',
-})
-
-
-//激活
-onActivated(() => {
-    searchForm.value.current = 1
-    getTableData()
-})
-
-//搜索表单
-const searchForm = ref({ current: 1, size: 30, total: 0 })
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableColumn = ref([
-    { key: 'platform', name: '应用平台' },
-    { key: 'name', name: '应用名称' },
-    { key: 'currentVersion', name: '当前版本' },
-    { key: 'updateTime', name: '更新时间' },
-    { key: 'action', name: '操作', width: 120, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { error, code, data } = await mainApi.page({
-        ...searchForm.value,
-        total: null,
-    })
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const dialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    platform: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入应用平台',
-    },
-    name: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入应用名称',
-    },
-    currentVersion: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入当前版本号',
-    },
-}
-
-//新增
-const addClick = () => {
-    dialogTitle.value = '新增APP'
-    formModel.value = {}
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改
-const editRowClick = (row) => {
-    formModel.value = {}
-    dialogTitle.value = '修改APP'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//删除
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        dialogClose()
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //发起请求
-    let res = {}
-    if (formModel.value.id) {
-        res = await mainApi.update(formModel.value)
-    } else {
-        res = await mainApi.add(formModel.value)
-    }
-    //处理结果
-    const { error, code, msg } = res
-    if (!error && code === 200) {
-        submitLoading.value = false
-        window?.$message?.success('操作成功')
-        dialogClose()
-        getTableData().then()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-
-//升级APP
-const isUpdateDialog = ref(false)
-const updateDialogTitle = ref('')
-const appRowInfo = ref({})
-
-//显示升级弹窗
-const updateRowClick = (row) => {
-    updateDialogTitle.value = `升级 - ${row.name}`
-    appRowInfo.value = { ...row }
-    searchUpdateForm.value.current = 1
-    searchUpdateForm.value.versionId = row.id
-    nextTick(() => {
-        isUpdateDialog.value = true
-        getUpdateTableData()
-    })
-}
-
-//搜索表单
-const searchUpdateForm = ref({
-    current: 1, size: 30, total: 0,
-})
-
-//分页
-const pageUpdateChange = ({ current, size }) => {
-    searchUpdateForm.value.current = current
-    searchUpdateForm.value.size = size
-    getUpdateTableData()
-}
-
-//表格数据
-const tableUpdateColumn = ref([
-    { key: 'softwareType', name: '软件类型', width: 80 },
-    { key: 'versionNumber', name: '当前版本', width: 100 },
-    { key: 'fileType', name: '文件类型', width: 80 },
-    { key: 'constraintUpdate', name: '强制更新', width: 80 },
-    { key: 'updateDate', name: '更新时间' },
-    { key: 'action', name: '操作', width: 100, align: 'center' },
-])
-
-//获取表格数据
-const tableUpdateLoading = ref(false)
-const tableUpdateData = ref([{}])
-const getUpdateTableData = async () => {
-    tableUpdateData.value = []
-    tableUpdateLoading.value = true
-    const { error, code, data } = await mainApi.getDetailList({
-        ...searchUpdateForm.value,
-        total: null,
-    })
-    tableUpdateLoading.value = false
-    if (!error && code === 200) {
-        tableUpdateData.value = getArrValue(data['records'])
-        searchUpdateForm.value.total = data['total']
-    } else {
-        tableUpdateData.value = []
-        searchUpdateForm.value.total = 0
-    }
-}
-
-
-//新增/修改 弹窗
-const isUpdateFormDialog = ref(false)
-const updateFormTitle = ref('')
-
-//菜单表单
-const formUpdateRef = ref(null)
-const formUpdateModel = ref({})
-const formUpdateRules = {
-    versionNumber: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入当前版本号',
-    },
-    softwareType: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择软件类型',
-    },
-    fileType: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择文件类型',
-    },
-    updateContent: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入更新内容',
-    },
-    fileUrl: {
-        required: true,
-        trigger: 'blur',
-        message: '请上传文件',
-    },
-    constraintUpdate: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择强制更新',
-    },
-}
-
-//新增
-const addUpdateClick = () => {
-    updateFormTitle.value = '新增 - ' + updateDialogTitle.value
-    formUpdateModel.value = { softwareType: 1, fileType: 0, constraintUpdate: 0, versionId: appRowInfo.value.id }
-    //显示表单弹窗
-    nextTick(() => {
-        isUpdateFormDialog.value = true
-    })
-}
-
-//修改
-const editUpdateRow = (row) => {
-    formUpdateModel.value = {}
-    updateFormTitle.value = '修改 - ' + updateDialogTitle.value
-    formUpdateModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isUpdateFormDialog.value = true
-    })
-}
-
-//删除
-const delUpdateRow = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.removeDetail(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        updateDialogClose()
-        getUpdateTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//关闭升级弹窗
-const updateDialogClose = () => {
-    isUpdateDialog.value = false
-    tableUpdateLoading.value = false
-    tableUpdateData.value = []
-    getTableData()
-}
-
-//上传文件
-const uploadOptions = {
-    url: '/api/blade-resource/oss/endpoint/put-file2',
-    accept: '.apk,.wgt,.exe,.dmg',
-    accept_tip: '只能上传apk、wgt、exe、dmg文件',
-    multiple: false,
-}
-
-//提交APP升级表单
-const submitUpdateLoading = ref(false)
-const dialogUpdateSubmit = async () => {
-    const formRes = await formValidate(formUpdateRef.value)
-    if (!formRes) return false
-    submitUpdateLoading.value = true
-    //发起请求
-    let res = {}
-    if (formUpdateModel.value.id) {
-        res = await mainApi.updateDetail(formUpdateModel.value)
-    } else {
-        res = await mainApi.addDetail(formUpdateModel.value)
-    }
-    submitUpdateLoading.value = false
-    //处理结果
-    const { error, code, msg } = res
-    if (!error && code === 200) {
-        window?.$message?.success('操作成功')
-        updateFormDialogClose()
-        getUpdateTableData().then()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭升级表单弹窗
-const updateFormDialogClose = () => {
-    isUpdateFormDialog.value = false
-    submitUpdateLoading.value = false
-    formUpdateModel.value = {}
-}
-</script>
-
-<style lang="scss">
-.hc-app-update-dialog .el-dialog__headerbtn {
-    top: 0;
-    width: 48px;
-    height: 48px;
-}
-.hc-update-dialog-title {
-    position: absolute;
-    top: 15px;
-    left: 200px;
-    right: 200px;
-    text-align: center;
-}
-</style>

+ 0 - 309
src/views/system/client.vue

@@ -1,309 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-60">
-                <hc-search-input v-model="searchForm.clientId" placeholder="请输入应用id关键词" @search="searchClick" />
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-            <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-        </template>
-        <hc-table
-            ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading"
-             is-check :check-style="{ width: 29 }" :index-style="{ width: 60 }"
-            @selection-change="tableCheckChange"
-        >
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-        <template #action>
-            <hc-pages :pages="searchForm" @change="pageChange" />
-        </template>
-
-        <!-- 新增/修改 -->
-        <hc-dialog v-model="isDialogShow" widths="800px" is-footer-center :title="dialogTitle" @close="dialogClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-row :gutter="20">
-                    <el-col :span="8">
-                        <el-form-item label="应用名称:" prop="name">
-                            <el-input v-model="formModel.name" clearable placeholder="请输入应用名称" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="应用id:" prop="clientId">
-                            <el-input v-model="formModel.clientId" clearable placeholder="请输入应用id" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="应用密钥:" prop="clientSecret">
-                            <el-input v-model="formModel.clientSecret" clearable placeholder="请输入应用密钥" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="24">
-                        <el-form-item label="授权类型:" prop="authorizedGrantTypes">
-                            <div class="form-item-div">
-                                <el-checkbox-group v-model="formModel.authorizedGrantTypes" size="large">
-                                    <el-checkbox label="refresh_token" />
-                                    <el-checkbox label="password" />
-                                    <el-checkbox label="authorization_code" />
-                                    <el-checkbox label="captcha" />
-                                    <el-checkbox label="social" />
-                                </el-checkbox-group>
-                            </div>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="授权范围:" prop="scope">
-                            <el-input v-model="formModel.scope" clearable placeholder="请输入授权范围" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="令牌秒数:" prop="accessTokenValidity">
-                            <el-input-number v-model="formModel.accessTokenValidity" :min="1" block controls-position="right" placeholder="请输入令牌秒数" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="刷新秒数:" prop="refreshTokenValidity">
-                            <el-input-number v-model="formModel.refreshTokenValidity" :min="1" block controls-position="right" placeholder="请输入刷新秒数" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="资源集合:">
-                            <el-input v-model="formModel.resourceIds" clearable placeholder="请输入资源集合" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="权限:">
-                            <el-input v-model="formModel.authorities" clearable placeholder="请输入权限" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="自动授权:">
-                            <el-input v-model="formModel.autoapprove" clearable placeholder="请输入自动授权" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="24">
-                        <el-form-item label="回调地址:" prop="webServerRedirectUri">
-                            <el-input v-model="formModel.webServerRedirectUri" clearable placeholder="请输入回调地址" />
-                        </el-form-item>
-                    </el-col>
-                </el-row>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { arrToId, formValidate, getArrValue } from 'js-fast-way'
-import { reloadPage } from '~uti/tools'
-import { HcDelMsg } from 'hc-vue3-ui'
-import mainApi from '~api/system/client'
-
-defineOptions({
-    name: 'Client',
-})
-
-//激活
-onActivated(() => {
-    searchForm.value.current = 1
-    getTableData()
-})
-
-//搜索表单
-const searchForm = ref({ clientId: null, current: 1, size: 30, total: 0 })
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableRef = ref(null)
-const tableColumn = ref([
-    { key: 'name', name: '应用名称' },
-    { key: 'clientId', name: '应用ID' },
-    { key: 'clientSecret', name: '应用密钥' },
-    { key: 'scope', name: '授权范围' },
-    { key: 'accessTokenValidity', name: '令牌秒数' },
-    { key: 'refreshTokenValidity', name: '刷新秒数' },
-    { key: 'action', name: '操作', width: 100, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { error, code, data } = await mainApi.page(searchForm.value)
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const dialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    name: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入应用名称',
-    },
-    clientId: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入应用id',
-    },
-    clientSecret: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入应用密钥',
-    },
-    authorizedGrantTypes: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择授权类型',
-    },
-    scope: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入授权范围',
-    },
-    accessTokenValidity: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入令牌秒数',
-    },
-    refreshTokenValidity: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入刷新秒数',
-    },
-    webServerRedirectUri: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入回调地址',
-    },
-}
-
-//新增
-const addClick = () => {
-    dialogTitle.value = '新增应用'
-    formModel.value = {
-        category: 1, isOpen: 1, isLayout: 1, isShowButton: 1,
-        sort: 1,
-    }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改菜单
-const editRowClick = (row) => {
-    formModel.value = {}
-    dialogTitle.value = '修改应用'
-    formModel.value = { ...row }
-    formModel.value.authorizedGrantTypes = row.authorizedGrantTypes.split(',')
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//删除菜单
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        reloadPage()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除菜单
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的菜单')
-        return false
-    }
-    //确认删除
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            reloadPage()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //处理数据
-    const form = formModel.value
-    form.authorizedGrantTypes = form.authorizedGrantTypes.join(',')
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(form)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        window?.$message?.success('操作成功')
-        reloadPage()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-</script>

+ 0 - 343
src/views/system/dept.vue

@@ -1,343 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-40">
-                <el-select v-model="searchForm.tenantId" placeholder="选择所属租户" filterable clearable block>
-                    <el-option v-for="item in tenantData" :key="item.tenantId" :label="item.name" :value="item.tenantId" />
-                </el-select>
-            </div>
-            <div class="ml-2 w-32">
-                <el-select v-model="searchType" placeholder="选择搜索类型" filterable block>
-                    <el-option label="机构名称" value="deptName" />
-                    <el-option label="机构全称" value="fullName" />
-                </el-select>
-            </div>
-            <div class="ml-2 w-60">
-                <hc-search-input v-model="searchName" placeholder="请输入关键词" @search="searchClick" />
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-            <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-        </template>
-        <hc-table
-            ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading"
-            :is-index="false"  is-check :check-style="{ width: 29 }" lazy :load="tableLoad"
-            @selection-change="tableCheckChange"
-        >
-            <template #tenantId="{ row }">{{ getTenantName(row) }}</template>
-            <template #deptCategory="{ row }">{{ getDeptCategoryName(row) }}</template>
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link type="success" @click="addRowClick(row)">新增子项</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-
-        <!-- 新增/修改 -->
-        <hc-dialog v-model="isDialogShow" widths="620px" is-footer-center :title="iconDialogTitle" @close="dialogClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-row :gutter="20">
-                    <el-col :span="12">
-                        <el-form-item label="机构名称:" prop="deptName">
-                            <el-input v-model="formModel.deptName" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="机构全称:" prop="fullName">
-                            <el-input v-model="formModel.fullName" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="上级机构:">
-                            <el-tree-select
-                                v-model="formModel.parentId" :disabled="isChildForm" :data="levelData" :props="levelDataProps"
-                                clearable filterable check-strictly block :render-after-expand="false"
-                            />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="机构类型:" prop="deptCategory">
-                            <el-select v-model="formModel.deptCategory" filterable clearable block>
-                                <el-option v-for="item in deptCategoryData" :key="item.value" :label="item.label" :value="item.value" />
-                            </el-select>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="机构排序:" prop="sort">
-                            <el-input-number v-model="formModel.sort" :min="1" block controls-position="right" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="机构备注:">
-                            <el-input v-model="formModel.remark" clearable />
-                        </el-form-item>
-                    </el-col>
-                </el-row>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { getDictionaryData, reloadPage } from '~uti/tools'
-import { arrToId, formValidate, getArrValue, isNullES } from 'js-fast-way'
-import { HcDelMsg } from 'hc-vue3-ui'
-import mainApi from '~api/system/dept'
-import tenantApi from '~api/system/tenant'
-
-defineOptions({
-    name: 'Dept',
-})
-
-//激活
-onActivated(() => {
-    getDataApi()
-})
-
-const getDataApi = async () => {
-    await getTenantData()
-    await getDeptCategory()
-    searchClick()
-}
-
-//搜索表单
-const searchType = ref('deptName')
-const searchName = ref('')
-const searchForm = ref({ tenantId: null })
-
-//所属租户
-const tenantData = ref([])
-const getTenantData = async () => {
-    let newArr = []
-    const { data } = await tenantApi.getSelect()
-    const res = getArrValue(data)
-    for (let i = 0; i < res.length; i++) {
-        newArr.push({
-            id: res[i]['id'],
-            name: res[i]['tenantName'],
-            tenantId: res[i]['tenantId'],
-        })
-    }
-    tenantData.value = newArr
-}
-const getTenantName = ({ tenantId }) => {
-    if (isNullES(tenantId)) return '-'
-    const item = tenantData.value.find((item) => item.tenantId === tenantId)
-    if (isNullES(item)) return tenantId
-    return item.name ?? tenantId
-}
-
-//获取机构类型
-const deptCategoryData = ref([])
-const getDeptCategory = async () => {
-    deptCategoryData.value = await getDictionaryData('org_category')
-}
-const getDeptCategoryName = ({ deptCategory }) => {
-    if (isNullES(deptCategory)) return '-'
-    const item = deptCategoryData.value.find((item) => item.value === deptCategory)
-    if (isNullES(item)) return deptCategory
-    return item.label ?? deptCategory
-}
-
-//搜索
-const searchClick = () => {
-    getTableData()
-}
-
-//表格数据
-const tableRef = ref(null)
-const tableColumn = ref([
-    { key: 'deptName', name: '机构名称' },
-    { key: 'tenantId', name: '所属租户', width: 160 },
-    { key: 'fullName', name: '机构全称' },
-    { key: 'deptCategory', name: '机构类型', width: 100 },
-    { key: 'sort', name: '排序', width: 80, align: 'center' },
-    { key: 'action', name: '操作', width: 200, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const form = searchForm.value
-    if (searchName.value) {
-        form[searchType.value] = searchName.value
-    }
-    const { data } = await mainApi.getLazyList({
-        ...form,
-        parentId: 0,
-    })
-    tableData.value = getArrValue(data)
-    tableLoading.value = false
-}
-
-//懒加载表格
-const tableLoad = async (row, node, resolve) => {
-    const form = searchForm.value
-    if (searchName.value) {
-        form[searchType.value] = searchName.value
-    }
-    const { data } = await mainApi.getLazyList({
-        ...form,
-        parentId: row.id,
-    })
-    resolve(getArrValue(data))
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//上级菜单
-const levelDataProps = { label: 'deptName' }
-const levelData = ref([])
-const getlevelData = async () => {
-    const { data } = await mainApi.getDeptTree()
-    levelData.value = getArrValue(data)
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const iconDialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    deptName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入机构名称',
-    },
-    fullName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入机构全称',
-    },
-    deptCategory: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择机构类型',
-    },
-    sort: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入菜单排序',
-    },
-}
-
-//新增机构
-const addClick = () => {
-    isChildForm.value = false
-    iconDialogTitle.value = '新增机构'
-    formModel.value = { parentId: null, deptCategory: null, sort: 1 }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-        getlevelData()
-    })
-}
-
-//修改机构
-const editRowClick = (row) => {
-    formModel.value = {}
-    isChildForm.value = false
-    iconDialogTitle.value = '修改机构'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-        getlevelData()
-    })
-}
-
-//新增子项
-const isChildForm = ref(false)
-const addRowClick = (row) => {
-    isChildForm.value = true
-    iconDialogTitle.value = '新增子机构'
-    formModel.value = { parentId: row.id, deptCategory: null, sort: 1 }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-        getlevelData()
-    })
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //处理数据
-    const form = formModel.value
-    form.parentId = form.parentId ?? '0'
-    form.tenantId = form.tenantId ?? ''
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(form)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        reloadPage()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    isChildForm.value = false
-    formModel.value = {}
-}
-
-//删除
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        reloadPage()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的数据')
-        return false
-    }
-    //确认删除菜单
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            reloadPage()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-</script>

+ 0 - 271
src/views/system/dict.vue

@@ -1,271 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-32">
-                <el-select v-model="searchType" placeholder="选择搜索类型" filterable block>
-                    <el-option label="字典编号" value="code" />
-                    <el-option label="字典名称" value="dictValue" />
-                </el-select>
-            </div>
-            <div class="ml-2 w-60">
-                <hc-search-input v-model="searchName" placeholder="请输入关键词" @search="searchClick" />
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-            <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-        </template>
-        <hc-table
-            ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading"
-             is-check :check-style="{ width: 29 }" :index-style="{ width: 60 }"
-            @selection-change="tableCheckChange"
-        >
-            <template #isSealed="{ row }">
-                {{ row.isSealed === 1 ? '是' : '否' }}
-            </template>
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link type="primary" @click="handleRowClick(row)">配置</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-        <template #action>
-            <hc-pages :pages="searchForm" @change="pageChange" />
-        </template>
-
-        <!-- 新增/修改 -->
-        <hc-dialog v-model="isDialogShow" widths="400px" is-footer-center :title="dialogTitle" @close="dialogClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-form-item label="字典编号:" prop="code">
-                    <el-input v-model="formModel.code" clearable placeholder="请输入字典编号" />
-                </el-form-item>
-                <el-form-item label="字典名称:" prop="dictValue">
-                    <el-input v-model="formModel.dictValue" clearable placeholder="请输入字典名称" />
-                </el-form-item>
-                <el-form-item label="字典备注:">
-                    <el-input v-model="formModel.remark" clearable placeholder="请输入字典备注" />
-                </el-form-item>
-                <el-form-item label="字典排序:" prop="sort">
-                    <el-input-number v-model="formModel.sort" :min="1" block controls-position="right" />
-                </el-form-item>
-                <el-form-item label="字典封存:" prop="isSealed">
-                    <el-radio-group v-model="formModel.isSealed">
-                        <el-radio :label="1">是</el-radio>
-                        <el-radio :label="0">否</el-radio>
-                    </el-radio-group>
-                </el-form-item>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-
-        <!-- 字典配置 -->
-        <HcChildDict v-model="isConfigDialog" :info="dictTableRow" @close="dictTableClose" />
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { arrToId, formValidate, getArrValue } from 'js-fast-way'
-import HcChildDict from './modules/dict/dict.vue'
-import { HcDelMsg } from 'hc-vue3-ui'
-import mainApi from '~api/system/dict'
-
-defineOptions({
-    name: 'Dict',
-})
-
-//激活
-onActivated(() => {
-    searchForm.value.current = 1
-    getTableData()
-})
-
-//搜索表单
-const searchType = ref('code')
-const searchName = ref('')
-const searchForm = ref({ current: 1, size: 30, total: 0 })
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableRef = ref(null)
-const tableColumn = ref([
-    { key: 'code', name: '字典编号' },
-    { key: 'dictValue', name: '字典名称' },
-    { key: 'isSealed', name: '封存', width: 80 },
-    { key: 'remark', name: '字典备注' },
-    { key: 'action', name: '操作', width: 120, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const form = {
-        ...searchForm.value,
-        total: null,
-    }
-    if (searchName.value) {
-        form[searchType.value] = searchName.value
-    }
-    const { error, code, data } = await mainApi.page(form)
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const dialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    code: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入字典编号',
-    },
-    dictValue: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入字典名称',
-    },
-    sort: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入字典排序',
-    },
-    isSealed: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择字典封存',
-    },
-}
-
-//新增
-const addClick = () => {
-    dialogTitle.value = '新增系统字典'
-    formModel.value = { sort: 1, isSealed: 0 }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改菜单
-const editRowClick = (row) => {
-    formModel.value = {}
-    dialogTitle.value = '修改系统字典'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//删除菜单
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除菜单
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的菜单')
-        return false
-    }
-    //确认删除
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            getTableData().then()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        getTableData().then()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-
-//字典配置
-const isConfigDialog = ref(false)
-const dictTableRow = ref({})
-const handleRowClick = (row) => {
-    dictTableRow.value = row
-    nextTick(() => {
-        isConfigDialog.value = true
-    })
-}
-
-//关闭字典配置弹窗
-const dictTableClose = () => {
-    isConfigDialog.value = false
-}
-</script>

+ 0 - 271
src/views/system/dictbiz.vue

@@ -1,271 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-32">
-                <el-select v-model="searchType" placeholder="选择搜索类型" filterable block>
-                    <el-option label="字典编号" value="code" />
-                    <el-option label="字典名称" value="dictValue" />
-                </el-select>
-            </div>
-            <div class="ml-2 w-60">
-                <hc-search-input v-model="searchName" placeholder="请输入关键词" @search="searchClick" />
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-            <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-        </template>
-        <hc-table
-            ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading"
-             is-check :check-style="{ width: 29 }" :index-style="{ width: 60 }"
-            @selection-change="tableCheckChange"
-        >
-            <template #isSealed="{ row }">
-                {{ row.isSealed === 1 ? '是' : '否' }}
-            </template>
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link type="primary" @click="handleRowClick(row)">配置</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-        <template #action>
-            <hc-pages :pages="searchForm" @change="pageChange" />
-        </template>
-
-        <!-- 新增/修改 -->
-        <hc-dialog v-model="isDialogShow" widths="400px" is-footer-center :title="dialogTitle" @close="dialogClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-form-item label="字典编号:" prop="code">
-                    <el-input v-model="formModel.code" clearable placeholder="请输入字典编号" />
-                </el-form-item>
-                <el-form-item label="字典名称:" prop="dictValue">
-                    <el-input v-model="formModel.dictValue" clearable placeholder="请输入字典名称" />
-                </el-form-item>
-                <el-form-item label="字典备注:">
-                    <el-input v-model="formModel.remark" clearable placeholder="请输入字典备注" />
-                </el-form-item>
-                <el-form-item label="字典排序:" prop="sort">
-                    <el-input-number v-model="formModel.sort" :min="1" block controls-position="right" />
-                </el-form-item>
-                <el-form-item label="字典封存:" prop="isSealed">
-                    <el-radio-group v-model="formModel.isSealed">
-                        <el-radio :label="1">是</el-radio>
-                        <el-radio :label="0">否</el-radio>
-                    </el-radio-group>
-                </el-form-item>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-
-        <!-- 字典配置 -->
-        <HcChildDictbiz v-model="isConfigDialog" :info="dictTableRow" @close="dictTableClose" />
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { arrToId, formValidate, getArrValue } from 'js-fast-way'
-import HcChildDictbiz from './modules/dictbiz/dictbiz.vue'
-import { HcDelMsg } from 'hc-vue3-ui'
-import mainApi from '~api/system/dictbiz'
-
-defineOptions({
-    name: 'Dictbiz',
-})
-
-//激活
-onActivated(() => {
-    searchForm.value.current = 1
-    getTableData()
-})
-
-//搜索表单
-const searchType = ref('code')
-const searchName = ref('')
-const searchForm = ref({ current: 1, size: 30, total: 0 })
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableRef = ref(null)
-const tableColumn = ref([
-    { key: 'code', name: '字典编号' },
-    { key: 'dictValue', name: '字典名称' },
-    { key: 'isSealed', name: '封存', width: 80 },
-    { key: 'remark', name: '字典备注' },
-    { key: 'action', name: '操作', width: 120, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const form = {
-        ...searchForm.value,
-        total: null,
-    }
-    if (searchName.value) {
-        form[searchType.value] = searchName.value
-    }
-    const { error, code, data } = await mainApi.page(form)
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const dialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    code: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入字典编号',
-    },
-    dictValue: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入字典名称',
-    },
-    sort: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入字典排序',
-    },
-    isSealed: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择字典封存',
-    },
-}
-
-//新增
-const addClick = () => {
-    dialogTitle.value = '新增业务字典'
-    formModel.value = { sort: 1, isSealed: 0 }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改菜单
-const editRowClick = (row) => {
-    formModel.value = {}
-    dialogTitle.value = '修改业务字典'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//删除菜单
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除菜单
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的菜单')
-        return false
-    }
-    //确认删除
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            getTableData().then()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        getTableData().then()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-
-//字典配置
-const isConfigDialog = ref(false)
-const dictTableRow = ref({})
-const handleRowClick = (row) => {
-    dictTableRow.value = row
-    nextTick(() => {
-        isConfigDialog.value = true
-    })
-}
-
-//关闭字典配置弹窗
-const dictTableClose = () => {
-    isConfigDialog.value = false
-}
-</script>

+ 0 - 234
src/views/system/menu-top.vue

@@ -1,234 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-60">
-                <hc-search-input v-model="searchForm.name" placeholder="请输入菜单名称" @search="searchClick" />
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-            <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-        </template>
-        <hc-table
-            ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading"
-            :is-index="false"  is-check :check-style="{ width: 29 }"
-            @selection-change="tableCheckChange"
-        >
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-        <template #action>
-            <hc-pages :pages="searchForm" @change="pageChange" />
-        </template>
-
-        <!-- 新增/修改 菜单 -->
-        <hc-dialog v-model="isDialogShow" widths="800px" is-footer-center :title="iconDialogTitle" @close="dialogClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-row :gutter="20">
-                    <el-col :span="12">
-                        <el-form-item label="菜单名称:" prop="name">
-                            <el-input v-model="formModel.name" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="跳转地址:" prop="code">
-                            <el-input v-model="formModel.code" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="菜单图标:">
-                            <hc-icon-input v-model="formModel.source" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="菜单排序:" prop="sort">
-                            <el-input-number v-model="formModel.sort" :min="1" block controls-position="right" />
-                        </el-form-item>
-                    </el-col>
-                </el-row>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { arrToId, formValidate, getArrValue } from 'js-fast-way'
-import { reloadPage } from '~uti/tools'
-import { HcDelMsg } from 'hc-vue3-ui'
-import mainApi from '~api/system/menu-top'
-
-defineOptions({
-    name: 'TopMenu',
-})
-
-//激活
-onActivated(() => {
-    searchClick()
-})
-
-//搜索表单
-const searchForm = ref({ name: null, current: 1, size: 30, total: 0 })
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableRef = ref(null)
-const tableColumn = ref([
-    { key: 'name', name: '菜单名称' },
-    { key: 'code', name: '跳转地址' },
-    { key: 'sort', name: '排序' },
-    { key: 'action', name: '操作', width: 200, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { error, code, data } = await mainApi.page({
-        ...searchForm.value,
-        total: null,
-    })
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const iconDialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    name: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入菜单名称',
-    },
-    code: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入跳转地址',
-    },
-    sort: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入菜单排序',
-    },
-}
-
-//新增菜单
-const addClick = () => {
-    iconDialogTitle.value = '新增菜单'
-    formModel.value = {}
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改菜单
-const editRowClick = (row) => {
-    formModel.value = {}
-    iconDialogTitle.value = '修改菜单'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//删除菜单
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        reloadPage()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除菜单
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的菜单')
-        return false
-    }
-    //确认删除
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            reloadPage()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        reloadPage()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-</script>

+ 0 - 478
src/views/system/menu.vue

@@ -1,478 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-40">
-                <el-select v-model="searchForm.sysId" filterable clearable block placeholder="选择所属系统">
-                    <el-option v-for="item in clinets" :key="item.id" :label="item.name ?? item.clientId" :value="item.id" />
-                </el-select>
-            </div>
-            <div class="ml-3 w-60">
-                <hc-search-input v-model="searchForm.name" placeholder="请输入菜单名称" @search="searchClick" />
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-            <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-        </template>
-        <hc-table
-            ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading"
-            :is-index="false" is-check :check-style="{ width: 29 }" lazy :load="tableLoad"
-            @selection-change="tableCheckChange"
-        >
-            <template #sysId="{ row }">
-                {{ getSystemNmae(row.sysId) }}
-            </template>
-            <template #category="{ row }">
-                {{ row.category === 1 ? '菜单' : '按钮' }}
-            </template>
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link type="success" @click="addRowClick(row)">新增子项</el-link>
-                <el-link type="primary" @click="copyRowClick(row)">复制</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-
-        <!-- 新增/修改 菜单 -->
-        <hc-dialog v-model="isDialogShow" widths="800px" is-footer-center :title="iconDialogTitle" @close="dialogClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-row :gutter="20">
-                    <el-col :span="8">
-                        <el-form-item label="菜单名称:" prop="name">
-                            <el-input v-model="formModel.name" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="路由地址:" prop="path">
-                            <el-input v-model="formModel.path" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="菜单编号:" prop="code">
-                            <el-input v-model="formModel.code" clearable />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="菜单图标:">
-                            <el-input v-model="formModel.source" clearable>
-                                <template #append>
-                                    <el-button @click="isIconShow = true">选择图标</el-button>
-                                </template>
-                            </el-input>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="所属系统:" prop="sysId">
-                            <el-select v-model="formModel.sysId" placeholder="选择所属系统" filterable clearable block>
-                                <el-option v-for="item in clinets" :key="item.id" :label="item.name ?? item.clientId" :value="item.id" />
-                            </el-select>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="上级菜单:">
-                            <el-tree-select
-                                v-model="formModel.parentId" placeholder="选择上级菜单"
-                                :data="levelMenu" :props="levelMenuProps" clearable filterable check-strictly block :render-after-expand="false"
-                            />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="菜单类型:" prop="category">
-                            <div class="form-item-div">
-                                <el-radio-group v-model="formModel.category">
-                                    <el-radio :value="1">菜单</el-radio>
-                                    <el-radio :value="2">按钮</el-radio>
-                                </el-radio-group>
-                            </div>
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-if="formModel.category === 2" :span="8">
-                        <el-form-item label="按钮是否显示:" prop="isShowButton">
-                            <div class="form-item-div">
-                                <el-radio-group v-model="formModel.isShowButton">
-                                    <el-radio :value="2">否</el-radio>
-                                    <el-radio :value="1">是</el-radio>
-                                </el-radio-group>
-                            </div>
-                        </el-form-item>
-                    </el-col>
-                    <el-col v-if="formModel.category === 1" :span="8">
-                        <el-form-item label="是否外层:" prop="isLayout">
-                            <div class="form-item-div">
-                                <el-radio-group v-model="formModel.isLayout">
-                                    <el-radio :value="1">否</el-radio>
-                                    <el-radio :value="2">是</el-radio>
-                                </el-radio-group>
-                            </div>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="是否新窗口:" prop="isOpen">
-                            <div class="form-item-div">
-                                <el-radio-group v-model="formModel.isOpen">
-                                    <el-radio :value="1">否</el-radio>
-                                    <el-radio :value="2">是</el-radio>
-                                </el-radio-group>
-                            </div>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="菜单排序:" prop="sort">
-                            <el-input-number v-model="formModel.sort" :min="1" block controls-position="right" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="16">
-                        <el-form-item label="按钮提示语:">
-                            <el-input v-model="formModel.textInfo" clearable :disabled="formModel.category === 1" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="24">
-                        <el-form-item label="菜单备注:">
-                            <el-input v-model="formModel.remark" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="24">
-                        <el-form-item>
-                            <template #label>
-                                <div class="hc-form-item-label">
-                                    <div class="title-content">
-                                        <span class="title">菜单视频:</span>
-                                        <span content="text">(只能上传MP4格式,且不能用QQ录屏,推荐使用win10自带录屏录制,文件大小限制50兆)</span>
-                                    </div>
-                                    <div class="right-content">
-                                        <el-link type="warning" @click="formModel.videoUrl = ''">清除</el-link>
-                                    </div>
-                                </div>
-                            </template>
-                            <hc-form-upload v-model="formModel.videoUrl" :upload="{ options: videoUpload }" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="24">
-                        <el-form-item label="文档信息:">
-                            <template #label>
-                                <div class="hc-form-item-label">
-                                    <div class="title-content">文档信息:</div>
-                                    <div class="right-content">
-                                        <el-link type="warning" @click="formModel.excelUrl = ''">清除</el-link>
-                                    </div>
-                                </div>
-                            </template>
-                            <hc-form-upload v-model="formModel.excelUrl" :upload="{ options: excelUpload }" />
-                        </el-form-item>
-                    </el-col>
-                </el-row>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-
-        <!-- 图标选择 -->
-        <hc-menu-icon v-model="isIconShow" @finish="menuIconFinish" />
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { useRoute, useRouter } from 'vue-router'
-import { arrToId, formValidate, getArrValue, getObjValue } from 'js-fast-way'
-import { HcDelMsg } from 'hc-vue3-ui'
-import { reloadPage } from '~uti/tools'
-import { getClinetAll } from '~api/other'
-import mainApi from '~api/system/menu'
-
-//初始组合式
-const router = useRouter()
-const useRoutes = useRoute()
-
-defineOptions({
-    name: 'HcMenu',
-})
-
-//激活
-onActivated(() => {
-    //获取参数
-    const { sysId, name } = getObjValue(useRoutes.query)
-    searchForm.value = { sysId: sysId, name: name }
-    //获取数据
-    getClinetAllApi()
-    getTableData()
-    getLevelMenuData()
-})
-
-//获取所有系统
-const clinets = ref([])
-const getClinetAllApi = async () => {
-    const { data } = await getClinetAll()
-    clinets.value = getArrValue(data)
-}
-
-//获取系统名称
-const getSystemNmae = (id) => {
-    const item = clinets.value.find((item) => item.id === id)
-    return item ? item.name : ''
-}
-
-//搜索表单
-const searchForm = ref({
-    sysId: null, name: null,
-})
-
-//搜索
-const searchClick = () => {
-    router.push({
-        name: 'menu',
-        query: searchForm.value,
-    })
-    getTableData()
-}
-
-//表格数据
-const tableRef = ref(null)
-const tableColumn = ref([
-    { key: 'name', name: '菜单名称' },
-    { key: 'sysId', name: '所属系统' },
-    { key: 'path', name: '路由地址' },
-    { key: 'code', name: '菜单编号' },
-    { key: 'category', name: '菜单类型', width: 90, align: 'center' },
-    { key: 'sort', name: '排序', width: 80, align: 'center' },
-    { key: 'action', name: '操作', width: 200, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { data } = await mainApi.getLazyList({
-        ...searchForm.value,
-        parentId: 0,
-    })
-    tableData.value = getArrValue(data)
-    tableLoading.value = false
-}
-
-//懒加载表格
-const tableLoad = async (row, node, resolve) => {
-    const { data } = await mainApi.getLazyList({
-        ...searchForm.value,
-        parentId: row.id,
-    })
-    resolve(getArrValue(data))
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//上级菜单
-const levelMenuProps = {
-    label: 'title',
-}
-
-const levelMenu = ref([])
-const getLevelMenuData = async () => {
-    const { data } = await mainApi.getMenuTree()
-    levelMenu.value = getArrValue(data)
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const iconDialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    name: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入菜单名称',
-    },
-    path: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入路由地址',
-    },
-    code: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入菜单编号',
-    },
-    sysId: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择所属系统',
-    },
-    category: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择菜单类型',
-    },
-    isShowButton: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择按钮是否显示',
-    },
-    isLayout: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择是否外层',
-    },
-    isOpen: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择是否新窗口',
-    },
-    sort: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入菜单排序',
-    },
-}
-
-//图标选择
-const isIconShow = ref(false)
-const menuIconFinish = (icon) => {
-    formModel.value.source = icon
-    isIconShow.value = false
-}
-
-//新增菜单
-const addClick = () => {
-    iconDialogTitle.value = '新增菜单'
-    formModel.value = {
-        category: 1, isOpen: 1, isLayout: 1, isShowButton: 1,
-        sort: 1, sysId: searchForm.value.sysId ?? null, parentId: null,
-    }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改菜单
-const editRowClick = (row) => {
-    formModel.value = {}
-    iconDialogTitle.value = '修改菜单'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//新增子项
-const addRowClick = (row) => {
-    iconDialogTitle.value = '新增子菜单'
-    formModel.value = {
-        name: row.name, path: row.path, code: row.code, source: row.source,
-        sysId: row.sysId, parentId: row.id,
-        category: 1, isOpen: 1, isLayout: 1, isShowButton: 1, sort: 1,
-    }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//复制菜单
-const copyRowClick = (row) => {
-    iconDialogTitle.value = '复制菜单'
-    formModel.value = {
-        ...row,
-        id: null,
-        sort: row.sort + 1,
-    }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//删除菜单
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        reloadPage()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除菜单
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的菜单')
-        return false
-    }
-    //确认删除
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            reloadPage()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-
-//菜单视频
-const videoUpload = {
-    multiple: false,
-    accept: '.mp4',
-    accept_tip: '只能上传MP4格式,且不能用QQ录屏,推荐使用win10自带录屏录制,文件大小限制50兆',
-    size: 100,
-}
-
-//文档信息
-const excelUpload = {
-    multiple: false,
-    accept: '.png,.jpg,jpeg,.xls,.xlsx,.pdf,.doc,.docx',
-    accept_tip: '图片(png、jpg、jpeg)<br/>Excel(xls、xlsx)<br/>PDF<br/>Word(doc、docx)',
-    size: 100,
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //处理数据
-    const form = formModel.value
-    form.parentId = form.parentId ?? 0
-    form.alias = form.alias ?? form.code
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(form)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        reloadPage()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-</script>

+ 0 - 289
src/views/system/modules/dict/dict.vue

@@ -1,289 +0,0 @@
-<template>
-    <hc-dialog v-model="isShow" widths="800px" is-table :footer="false" :is-close="false">
-        <template #header>
-            <div class="hc-flex">
-                <div class="hc-flex flex-1">
-                    <div class="w-32">
-                        <el-select v-model="searchType" placeholder="选择搜索类型" filterable block>
-                            <el-option label="字典编号" value="code" />
-                            <el-option label="字典名称" value="dictValue" />
-                        </el-select>
-                    </div>
-                    <div class="ml-2 w-60">
-                        <hc-search-input v-model="searchName" placeholder="请输入关键词" @search="getTableData" />
-                    </div>
-                </div>
-                <div class="hc-flex">
-                    <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-                    <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-                    <el-button hc-btn @click="configDialogClose">关闭</el-button>
-                </div>
-            </div>
-        </template>
-        <hc-table
-            ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading"
-             is-check :check-style="{ width: 29 }" :index-style="{ width: 60 }"
-            @selection-change="tableCheckChange"
-        >
-            <template #isSealed="{ row }">
-                {{ row.isSealed === 1 ? '是' : '否' }}
-            </template>
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-    </hc-dialog>
-
-    <!-- 新增/修改 -->
-    <hc-dialog v-model="isDialogShow" widths="550px" is-footer-center :title="dialogTitle" @close="dialogClose">
-        <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-            <el-row :gutter="20">
-                <el-col :span="12">
-                    <el-form-item label="字典编号:">
-                        <el-input v-model="dictInfo.code" disabled />
-                    </el-form-item>
-                </el-col>
-                <el-col :span="12">
-                    <el-form-item label="上级字典:">
-                        <el-input v-model="dictInfo.dictValue" disabled />
-                    </el-form-item>
-                </el-col>
-                <el-col :span="12">
-                    <el-form-item label="字典名称:" prop="dictValue">
-                        <el-input v-model="formModel.dictValue" clearable placeholder="请输入字典名称" />
-                    </el-form-item>
-                </el-col>
-                <el-col :span="12">
-                    <el-form-item label="字典键值:" prop="dictKey">
-                        <el-input v-model="formModel.dictKey" clearable placeholder="请输入字典键值" />
-                    </el-form-item>
-                </el-col>
-                <el-col :span="12">
-                    <el-form-item label="字典备注:">
-                        <el-input v-model="formModel.remark" clearable placeholder="请输入字典备注" />
-                    </el-form-item>
-                </el-col>
-                <el-col :span="12">
-                    <el-form-item label="字典排序:" prop="sort">
-                        <el-input-number v-model="formModel.sort" :min="1" block controls-position="right" />
-                    </el-form-item>
-                </el-col>
-                <el-col :span="24">
-                    <el-form-item label="字典封存:" prop="isSealed">
-                        <el-radio-group v-model="formModel.isSealed">
-                            <el-radio :label="1">是</el-radio>
-                            <el-radio :label="0">否</el-radio>
-                        </el-radio-group>
-                    </el-form-item>
-                </el-col>
-            </el-row>
-        </el-form>
-        <template #footer>
-            <el-button hc-btn @click="dialogClose">取消</el-button>
-            <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-        </template>
-    </hc-dialog>
-</template>
-
-<script setup>
-import { nextTick, ref, watch } from 'vue'
-import { arrToId, formValidate, getArrValue } from 'js-fast-way'
-import { HcDelMsg } from 'hc-vue3-ui'
-import mainApi from '~api/system/dict'
-
-const props = defineProps({
-    info: {
-        type: Object,
-        default: () => ({}),
-    },
-})
-
-//事件
-const emit = defineEmits(['close'])
-
-//双向绑定
-// eslint-disable-next-line no-undef
-const isShow = defineModel('modelValue', {
-    default: false,
-})
-
-//搜索表单
-const searchType = ref('code')
-const searchName = ref('')
-
-//监听可否编辑
-const dictInfo = ref(props.info)
-watch(() => props.info, (data) => {
-    dictInfo.value = data
-}, { immediate: true, deep: true })
-
-//监听显示
-watch(isShow, (val) => {
-    if (val) {
-        getTableData()
-    }
-})
-
-//表格数据
-const tableRef = ref(null)
-const tableColumn = ref([
-    { key: 'code', name: '字典编号' },
-    { key: 'dictValue', name: '字典名称' },
-    { key: 'dictKey', name: '字典键值' },
-    { key: 'isSealed', name: '封存', width: 80 },
-    { key: 'remark', name: '字典备注' },
-    { key: 'action', name: '操作', width: 100, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const form = {
-        current: 1,
-        size: 200,
-        parentId: dictInfo.value.id,
-    }
-    if (searchName.value) {
-        form[searchType.value] = searchName.value
-    }
-    const { error, code, data } = await mainApi.getChildList(form)
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data)
-    } else {
-        tableData.value = []
-    }
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const dialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    dictValue: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入字典名称',
-    },
-    dictKey: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入字典键值',
-    },
-    sort: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入字典排序',
-    },
-    isSealed: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择字典封存',
-    },
-}
-
-//新增
-const addClick = () => {
-    dialogTitle.value = '新增系统字典配置'
-    const { id, code } = dictInfo.value
-    formModel.value = { sort: 1, isSealed: 0, code: code, parentId: id }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改菜单
-const editRowClick = (row) => {
-    formModel.value = {}
-    dialogTitle.value = '修改系统字典配置'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//删除菜单
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除菜单
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的菜单')
-        return false
-    }
-    //确认删除
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            getTableData().then()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        getTableData().then()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-
-//关闭字典配置弹窗
-const configDialogClose = () => {
-    isShow.value = false
-    dictInfo.value = {}
-    tableData.value = []
-    emit('close')
-}
-</script>

+ 0 - 289
src/views/system/modules/dictbiz/dictbiz.vue

@@ -1,289 +0,0 @@
-<template>
-    <hc-dialog v-model="isShow" widths="800px" is-table :footer="false" :is-close="false">
-        <template #header>
-            <div class="hc-flex">
-                <div class="hc-flex flex-1">
-                    <div class="w-32">
-                        <el-select v-model="searchType" placeholder="选择搜索类型" filterable block>
-                            <el-option label="字典编号" value="code" />
-                            <el-option label="字典名称" value="dictValue" />
-                        </el-select>
-                    </div>
-                    <div class="ml-2 w-60">
-                        <hc-search-input v-model="searchName" placeholder="请输入关键词" @search="getTableData" />
-                    </div>
-                </div>
-                <div class="hc-flex">
-                    <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-                    <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-                    <el-button hc-btn @click="configDialogClose">关闭</el-button>
-                </div>
-            </div>
-        </template>
-        <hc-table
-            ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading"
-             is-check :check-style="{ width: 29 }" :index-style="{ width: 60 }"
-            @selection-change="tableCheckChange"
-        >
-            <template #isSealed="{ row }">
-                {{ row.isSealed === 1 ? '是' : '否' }}
-            </template>
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-    </hc-dialog>
-
-    <!-- 新增/修改 -->
-    <hc-dialog v-model="isDialogShow" widths="550px" is-footer-center :title="dialogTitle" @close="dialogClose">
-        <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-            <el-row :gutter="20">
-                <el-col :span="12">
-                    <el-form-item label="字典编号:">
-                        <el-input v-model="dictInfo.code" disabled />
-                    </el-form-item>
-                </el-col>
-                <el-col :span="12">
-                    <el-form-item label="上级字典:">
-                        <el-input v-model="dictInfo.dictValue" disabled />
-                    </el-form-item>
-                </el-col>
-                <el-col :span="12">
-                    <el-form-item label="字典名称:" prop="dictValue">
-                        <el-input v-model="formModel.dictValue" clearable placeholder="请输入字典名称" />
-                    </el-form-item>
-                </el-col>
-                <el-col :span="12">
-                    <el-form-item label="字典键值:" prop="dictKey">
-                        <el-input v-model="formModel.dictKey" clearable placeholder="请输入字典键值" />
-                    </el-form-item>
-                </el-col>
-                <el-col :span="12">
-                    <el-form-item label="字典备注:">
-                        <el-input v-model="formModel.remark" clearable placeholder="请输入字典备注" />
-                    </el-form-item>
-                </el-col>
-                <el-col :span="12">
-                    <el-form-item label="字典排序:" prop="sort">
-                        <el-input-number v-model="formModel.sort" :min="1" block controls-position="right" />
-                    </el-form-item>
-                </el-col>
-                <el-col :span="24">
-                    <el-form-item label="字典封存:" prop="isSealed">
-                        <el-radio-group v-model="formModel.isSealed">
-                            <el-radio :label="1">是</el-radio>
-                            <el-radio :label="0">否</el-radio>
-                        </el-radio-group>
-                    </el-form-item>
-                </el-col>
-            </el-row>
-        </el-form>
-        <template #footer>
-            <el-button hc-btn @click="dialogClose">取消</el-button>
-            <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-        </template>
-    </hc-dialog>
-</template>
-
-<script setup>
-import { nextTick, ref, watch } from 'vue'
-import { arrToId, formValidate, getArrValue } from 'js-fast-way'
-import { HcDelMsg } from 'hc-vue3-ui'
-import mainApi from '~api/system/dictbiz'
-
-const props = defineProps({
-    info: {
-        type: Object,
-        default: () => ({}),
-    },
-})
-
-//事件
-const emit = defineEmits(['close'])
-
-//双向绑定
-// eslint-disable-next-line no-undef
-const isShow = defineModel('modelValue', {
-    default: false,
-})
-
-//搜索表单
-const searchType = ref('code')
-const searchName = ref('')
-
-//监听可否编辑
-const dictInfo = ref(props.info)
-watch(() => props.info, (data) => {
-    dictInfo.value = data
-}, { immediate: true, deep: true })
-
-//监听显示
-watch(isShow, (val) => {
-    if (val) {
-        getTableData()
-    }
-})
-
-//表格数据
-const tableRef = ref(null)
-const tableColumn = ref([
-    { key: 'code', name: '字典编号' },
-    { key: 'dictValue', name: '字典名称' },
-    { key: 'dictKey', name: '字典键值' },
-    { key: 'isSealed', name: '封存', width: 80 },
-    { key: 'remark', name: '字典备注' },
-    { key: 'action', name: '操作', width: 100, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const form = {
-        current: 1,
-        size: 200,
-        parentId: dictInfo.value.id,
-    }
-    if (searchName.value) {
-        form[searchType.value] = searchName.value
-    }
-    const { error, code, data } = await mainApi.getChildList(form)
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data)
-    } else {
-        tableData.value = []
-    }
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const dialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    dictValue: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入字典名称',
-    },
-    dictKey: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入字典键值',
-    },
-    sort: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入字典排序',
-    },
-    isSealed: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择字典封存',
-    },
-}
-
-//新增
-const addClick = () => {
-    dialogTitle.value = '新增业务字典配置'
-    const { id, code } = dictInfo.value
-    formModel.value = { sort: 1, isSealed: 0, code: code, parentId: id }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改菜单
-const editRowClick = (row) => {
-    formModel.value = {}
-    dialogTitle.value = '修改业务字典配置'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//删除菜单
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除菜单
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的菜单')
-        return false
-    }
-    //确认删除菜单
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            getTableData().then()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        getTableData().then()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-
-//关闭字典配置弹窗
-const configDialogClose = () => {
-    isShow.value = false
-    dictInfo.value = {}
-    tableData.value = []
-    emit('close')
-}
-</script>

+ 0 - 92
src/views/system/modules/tenant/data-source.vue

@@ -1,92 +0,0 @@
-<template>
-    <hc-dialog v-model="isShow" title="租户数据源配置" widths="400px" is-footer-center @close="dialogClose">
-        <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="left" label-width="auto">
-            <el-form-item label="数据源:" prop="datasourceId">
-                <el-select v-model="formModel.datasourceId" placeholder="请选择数据源" filterable block>
-                    <el-option v-for="item in sourceList" :key="item.id" :label="item.name" :value="item.id" />
-                </el-select>
-            </el-form-item>
-        </el-form>
-        <template #footer>
-            <el-button hc-btn @click="dialogClose">取消</el-button>
-            <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-        </template>
-    </hc-dialog>
-</template>
-
-<script setup>
-import { ref, watch } from 'vue'
-import { deepClone, getArrValue } from 'js-fast-way'
-import mainApi from '~api/system/tenant'
-import { get } from '~api'
-
-const props = defineProps({
-    info: {
-        type: Object,
-        default: () => ({}),
-    },
-})
-
-//事件
-const emit = defineEmits(['finish'])
-
-//双向绑定
-// eslint-disable-next-line no-undef
-const isShow = defineModel('modelValue', {
-    default: false,
-})
-
-//监听可否编辑
-const dataInfo = ref(props.info)
-watch(() => props.info, (data) => {
-    dataInfo.value = data
-}, { immediate: true, deep: true })
-
-//监听显示
-watch(isShow, (val) => {
-    if (val) {
-        initFormData()
-    }
-})
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    datasourceId: [{ required: true, message: '请选择数据源', trigger: 'change' }],
-}
-
-//初始化表单
-const sourceList = ref([])
-const initFormData = async () => {
-    submitLoading.value = false
-    formModel.value = deepClone(dataInfo.value)
-    //获取数据源列表
-    const { data } = await get({
-        url: '/api/blade-develop/datasource/select',
-    })
-    sourceList.value = getArrValue(data)
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    submitLoading.value = true
-    const { error, code, msg } = await mainApi.datasource(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        window?.$message?.success('操作成功')
-        emit('finish')
-        dialogClose()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-</script>

+ 0 - 230
src/views/system/modules/tenant/package-data.vue

@@ -1,230 +0,0 @@
-<template>
-    <hc-dialog v-model="isShow" widths="800px" is-table :footer="false" :is-close="false">
-        <template #header>
-            <div class="hc-flex">
-                <div class="hc-flex flex-1">
-                    <div class="w-60">
-                        <hc-search-input v-model="searchForm.packageName" placeholder="产品包名" @search="getTableData" />
-                    </div>
-                </div>
-                <div class="hc-flex">
-                    <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-                    <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-                    <el-button hc-btn @click="configDialogClose">关闭</el-button>
-                </div>
-            </div>
-        </template>
-        <hc-table
-            ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading"
-             is-check :check-style="{ width: 29 }" :index-style="{ width: 60 }"
-            @selection-change="tableCheckChange"
-        >
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-    </hc-dialog>
-
-    <!-- 新增/修改 -->
-    <hc-dialog v-model="isDialogShow" widths="450px" is-footer-center :title="dialogTitle" @close="dialogClose">
-        <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-            <el-form-item label="产品包名:" prop="packageName">
-                <el-input v-model="formModel.packageName" placeholder="请输入产品包名称" />
-            </el-form-item>
-            <el-form-item label="菜单列表:" prop="menuIds">
-                <el-tree-select
-                    v-model="formModel.menuIds" :data="menuData" :render-after-expand="false" node-key="id"
-                    :props="menuTreeProps" multiple show-checkbox clearable block placeholder="请选择菜单列表"
-                />
-            </el-form-item>
-            <el-form-item label="备注:">
-                <el-input v-model="formModel.remark" placeholder="请输入备注" />
-            </el-form-item>
-        </el-form>
-        <template #footer>
-            <el-button hc-btn @click="dialogClose">取消</el-button>
-            <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-        </template>
-    </hc-dialog>
-</template>
-
-<script setup>
-import { nextTick, ref, watch } from 'vue'
-import { arrToId, formValidate, getArrValue } from 'js-fast-way'
-import { HcDelMsg } from 'hc-vue3-ui'
-import mainApi from '~api/system/tenant-package'
-import menuApi from '~api/system/menu'
-
-//事件
-const emit = defineEmits(['close'])
-
-//双向绑定
-// eslint-disable-next-line no-undef
-const isShow = defineModel('modelValue', {
-    default: false,
-})
-
-//搜索表单
-const searchForm = ref({
-    packageName: null, current: 1, size: 200,
-})
-
-//监听显示
-watch(isShow, (val) => {
-    if (val) {
-        getTableData()
-        getMenuTreeApi()
-    }
-})
-
-//表格数据
-const tableRef = ref(null)
-const tableColumn = ref([
-    { key: 'packageName', name: '产品包名' },
-    { key: 'remark', name: '备注' },
-    { key: 'action', name: '操作', width: 100, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { data } = await mainApi.page(searchForm.value)
-    tableData.value = getArrValue(data['records'])
-    tableLoading.value = false
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const dialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    packageName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入产品包名称',
-    },
-    menuIds: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择菜单',
-    },
-}
-
-//菜单列表
-const menuData = ref([])
-const getMenuTreeApi = async () => {
-    const { data } = await menuApi.getMenuTree()
-    menuData.value = getArrValue(data)
-}
-//菜单树
-const menuTreeProps = {
-    label: 'title',
-}
-
-//新增
-const addClick = () => {
-    dialogTitle.value = '新增产品包'
-    formModel.value = {}
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改菜单
-const editRowClick = (row) => {
-    formModel.value = {}
-    dialogTitle.value = '修改产品包'
-    formModel.value = { ...row }
-    formModel.value.menuIds = row?.menuId?.split(',') ?? []
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//删除菜单
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除菜单
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的菜单')
-        return false
-    }
-    //确认删除
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            getTableData().then()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //处理数据
-    const form = formModel.value
-    form.menuId = form.menuIds?.join(',') ?? ''
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(form)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        getTableData().then()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-
-//关闭字典配置弹窗
-const configDialogClose = () => {
-    isShow.value = false
-    tableData.value = []
-    emit('close')
-}
-</script>

+ 0 - 136
src/views/system/modules/tenant/package.vue

@@ -1,136 +0,0 @@
-<template>
-    <hc-dialog v-model="isShow" title="租户授权配置" widths="400px" is-footer-center @close="dialogClose">
-        <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="left" label-width="auto">
-            <el-form-item label="产品包:">
-                <el-select v-model="formModel.packageId" placeholder="选择搜索类型" filterable block @change="packageChange">
-                    <el-option v-for="item in packageData" :key="item.id" :label="item.packageName" :value="item.id" />
-                </el-select>
-            </el-form-item>
-            <el-form-item label="菜单列表:" prop="menuIds">
-                <el-tree-select
-                    v-model="formModel.menuIds" :data="menuData" :render-after-expand="false" node-key="id"
-                    :props="menuTreeProps" multiple show-checkbox clearable block placeholder="请选择菜单列表"
-                />
-            </el-form-item>
-        </el-form>
-        <template #footer>
-            <el-button hc-btn @click="dialogClose">取消</el-button>
-            <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-        </template>
-    </hc-dialog>
-</template>
-
-<script setup>
-import { ref, watch } from 'vue'
-import { getArrValue, getObjValue } from 'js-fast-way'
-import mainApi from '~api/system/tenant'
-import menuApi from '~api/system/menu'
-import { get } from '~api'
-
-const props = defineProps({
-    info: {
-        type: Object,
-        default: () => ({}),
-    },
-})
-
-//事件
-const emit = defineEmits(['finish'])
-
-//双向绑定
-// eslint-disable-next-line no-undef
-const isShow = defineModel('modelValue', {
-    default: false,
-})
-
-//监听可否编辑
-const dataInfo = ref(props.info)
-watch(() => props.info, (data) => {
-    dataInfo.value = data
-}, { immediate: true, deep: true })
-
-//监听显示
-watch(isShow, (val) => {
-    if (val) {
-        initFormData()
-    }
-})
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {}
-
-//初始化表单
-const initFormData = () => {
-    submitLoading.value = false
-    getMenuTreeApi()
-    getPackageList()
-    getPackageInfo()
-    formModel.value = {
-        tenantId: dataInfo.value.id,
-    }
-}
-
-//菜单列表
-const menuData = ref([])
-const getMenuTreeApi = async () => {
-    const { data } = await menuApi.getMenuTree()
-    menuData.value = getArrValue(data)
-}
-//菜单树
-const menuTreeProps = {
-    label: 'title',
-}
-
-//获取产品包信息
-const getPackageInfo = async () => {
-    const { data } = await mainApi.packageInfo(dataInfo.value.id)
-    let res = getObjValue(data)
-    res.packageId = res.id
-    res.menuIds = res.menuId?.split(',') ?? []
-    formModel.value = res
-}
-
-//获取产品包列表
-const packageData = ref([])
-const getPackageList = async () => {
-    const { data } = await get({
-        url: '/api/blade-system/tenant-package/select',
-    })
-    packageData.value = getArrValue(data)
-}
-
-//产品包改变
-const packageChange = (val) => {
-    const item = packageData.value.find((item) => item.id === val)
-    const menuId = item ? item.menuId : ''
-    formModel.value.menuIds = menuId.split(',') ?? []
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    submitLoading.value = true
-    //处理数据
-    const form = formModel.value
-    form.menuId = form.menuIds?.join(',') ?? ''
-    //发起请求
-    const { error, code, msg } = await mainApi.packageSetting(form)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        window?.$message?.success('操作成功')
-        emit('finish')
-        dialogClose()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-</script>

+ 0 - 87
src/views/system/modules/tenant/setting.vue

@@ -1,87 +0,0 @@
-<template>
-    <hc-dialog v-model="isShow" title="租户授权配置" widths="400px" is-footer-center @close="dialogClose">
-        <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="left" label-width="auto">
-            <el-form-item label="账号额度:">
-                <el-input-number v-model="formModel.accountNumber" block controls-position="right" />
-            </el-form-item>
-            <el-form-item label="过期时间:">
-                <el-date-picker
-                    v-model="formModel.expireTime" type="datetime" class="block"
-                    format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
-                />
-            </el-form-item>
-        </el-form>
-        <template #footer>
-            <el-button hc-btn @click="dialogClose">取消</el-button>
-            <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-        </template>
-    </hc-dialog>
-</template>
-
-<script setup>
-import { ref, watch } from 'vue'
-import { deepClone } from 'js-fast-way'
-import mainApi from '~api/system/tenant'
-
-const props = defineProps({
-    info: {
-        type: Object,
-        default: () => ({}),
-    },
-})
-
-//事件
-const emit = defineEmits(['finish'])
-
-//双向绑定
-// eslint-disable-next-line no-undef
-const isShow = defineModel('modelValue', {
-    default: false,
-})
-
-//监听可否编辑
-const dataInfo = ref(props.info)
-watch(() => props.info, (data) => {
-    dataInfo.value = data
-}, { immediate: true, deep: true })
-
-//监听显示
-watch(isShow, (val) => {
-    if (val) {
-        initFormData()
-    }
-})
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {}
-
-//初始化表单
-const initFormData = () => {
-    submitLoading.value = false
-    formModel.value = deepClone(dataInfo.value)
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    submitLoading.value = true
-    const { error, code, msg } = await mainApi.setting(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        window?.$message?.success('操作成功')
-        emit('finish')
-        dialogClose()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-</script>

+ 0 - 221
src/views/system/param.vue

@@ -1,221 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-60">
-                <hc-search-input v-model="searchForm.paramName" placeholder="请输入参数名称关键词" @search="searchClick" />
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-            <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-        </template>
-        <hc-table
-            ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading"
-             is-check :check-style="{ width: 29 }" :index-style="{ width: 60 }"
-            @selection-change="tableCheckChange"
-        >
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-        <template #action>
-            <hc-pages :pages="searchForm" @change="pageChange" />
-        </template>
-
-        <!-- 新增/修改 -->
-        <hc-dialog v-model="isDialogShow" widths="800px" is-footer-center :title="dialogTitle" @close="dialogClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-form-item label="参数名称:" prop="paramName">
-                    <el-input v-model="formModel.paramName" clearable placeholder="请输入参数名称" />
-                </el-form-item>
-                <el-form-item label="参数键名:" prop="paramKey">
-                    <el-input v-model="formModel.paramKey" clearable placeholder="请输入参数键名" />
-                </el-form-item>
-                <el-form-item label="参数键值:" prop="paramValue">
-                    <el-input v-model="formModel.paramValue" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" placeholder="请输入参数键值" />
-                </el-form-item>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { arrToId, formValidate, getArrValue } from 'js-fast-way'
-import { reloadPage } from '~uti/tools'
-import { HcDelMsg } from 'hc-vue3-ui'
-import mainApi from '~api/system/param'
-
-defineOptions({
-    name: 'Param',
-})
-
-//激活
-onActivated(() => {
-    searchForm.value.current = 1
-    getTableData()
-})
-
-//搜索表单
-const searchForm = ref({ current: 1, size: 30, total: 0 })
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableRef = ref(null)
-const tableColumn = ref([
-    { key: 'paramName', name: '参数名称' },
-    { key: 'paramKey', name: '参数键名' },
-    { key: 'paramValue', name: '参数键值' },
-    { key: 'action', name: '操作', width: 100, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([{}])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const { error, code, data } = await mainApi.page({
-        ...searchForm.value,
-        total: null,
-    })
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const dialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    paramName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入参数名称',
-    },
-    paramKey: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入参数键名',
-    },
-    paramValue: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入参数键值',
-    },
-}
-
-//新增
-const addClick = () => {
-    dialogTitle.value = '新增参数'
-    formModel.value = {}
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改菜单
-const editRowClick = (row) => {
-    formModel.value = {}
-    dialogTitle.value = '修改参数'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//删除菜单
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        reloadPage()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除菜单
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的菜单')
-        return false
-    }
-    //确认删除
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            reloadPage()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        window?.$message?.success('操作成功')
-        reloadPage()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-</script>

+ 0 - 300
src/views/system/post.vue

@@ -1,300 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <div class="w-32">
-                <el-select v-model="searchForm.category" placeholder="选择岗位类型" filterable clearable block>
-                    <el-option v-for="item in categoryType" :key="item.value" :label="item.label" :value="item.value" />
-                </el-select>
-            </div>
-            <div class="ml-2 w-32">
-                <el-select v-model="searchType" placeholder="选择搜索类型" filterable block>
-                    <el-option label="岗位编号" value="postCode" />
-                    <el-option label="岗位名称" value="postName" />
-                </el-select>
-            </div>
-            <div class="ml-2 w-60">
-                <hc-search-input v-model="searchName" placeholder="请输入关键词" @search="searchClick" />
-            </div>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-            <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-        </template>
-        <hc-table
-            ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading"
-             is-check :check-style="{ width: 29 }" :index-style="{ width: 60 }"
-            @selection-change="tableCheckChange"
-        >
-            <template #tenantId="{ row }">
-                {{ getTenantNmae(row.tenantId) }}
-            </template>
-            <template #category="{ row }">
-                {{ getCategoryType(row.category) }}
-            </template>
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-        <template #action>
-            <hc-pages :pages="searchForm" @change="pageChange" />
-        </template>
-
-        <!-- 新增/修改 -->
-        <hc-dialog v-model="isDialogShow" widths="600px" is-footer-center :title="dialogTitle" @close="dialogClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-row :gutter="20">
-                    <el-col :span="12">
-                        <el-form-item label="岗位类型:" prop="category">
-                            <el-select v-model="formModel.category" placeholder="选择岗位类型" filterable clearable block>
-                                <el-option v-for="item in categoryType" :key="item.value" :label="item.label" :value="item.value" />
-                            </el-select>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="岗位编号:" prop="postCode">
-                            <el-input v-model="formModel.postCode" clearable placeholder="请输入岗位编号" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="岗位名称:" prop="postName">
-                            <el-input v-model="formModel.postName" clearable placeholder="请输入岗位名称" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="岗位排序:" prop="sort">
-                            <el-input-number v-model="formModel.sort" :min="1" block controls-position="right" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="24">
-                        <el-form-item label="岗位描述:">
-                            <el-input v-model="formModel.remark" :autosize="{ minRows: 4, maxRows: 8 }" type="textarea" placeholder="请输入岗位描述" />
-                        </el-form-item>
-                    </el-col>
-                </el-row>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { arrToId, formValidate, getArrValue } from 'js-fast-way'
-import { getDictionaryData } from '~uti/tools'
-import { HcDelMsg } from 'hc-vue3-ui'
-import tenantApi from '~api/system/tenant'
-import mainApi from '~api/system/post'
-
-defineOptions({
-    name: 'Post',
-})
-
-//激活
-onActivated(() => {
-    searchForm.value.current = 1
-    getDataApi()
-})
-
-const getDataApi = async () => {
-    await getPostCategory()
-    await getTenantList()
-    getTableData().then()
-}
-
-//搜索表单
-const searchType = ref('postCode')
-const searchName = ref('')
-const searchForm = ref({ current: 1, size: 30, total: 0 })
-
-//获取岗位类型
-const categoryType = ref([])
-const getPostCategory = async () => {
-    categoryType.value = await getDictionaryData('post_category')
-}
-const getCategoryType = (id) => {
-    const item = categoryType.value.find((item) => item.value === id)
-    return item ? item.label : id
-}
-
-//获取租户列表
-const tenantList = ref([])
-const getTenantList = async () => {
-    const { data } = await tenantApi.getSelect()
-    tenantList.value = getArrValue(data)
-}
-const getTenantNmae = (id) => {
-    const item = tenantList.value.find((item) => item.tenantId === id)
-    return item ? item.tenantName : id
-}
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableRef = ref(null)
-const tableColumn = ref([
-    { key: 'tenantId', name: '所属租户' },
-    { key: 'category', name: '岗位类型' },
-    { key: 'postCode', name: '岗位编号' },
-    { key: 'postName', name: '岗位名称' },
-    { key: 'sort', name: '岗位排序' },
-    { key: 'action', name: '操作', width: 100, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([{}])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const form = {
-        ...searchForm.value,
-        total: null,
-    }
-    if (searchName.value) {
-        form[searchType.value] = searchName.value
-    }
-    const { error, code, data } = await mainApi.page(form)
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const dialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    category: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择岗位类型',
-    },
-    postCode: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入岗位编号',
-    },
-    postName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入岗位名称',
-    },
-    sort: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入字典排序',
-    },
-}
-
-//新增
-const addClick = () => {
-    dialogTitle.value = '新增岗位'
-    formModel.value = { sort: 1 }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改菜单
-const editRowClick = (row) => {
-    formModel.value = {}
-    dialogTitle.value = '修改岗位'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//删除菜单
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除菜单
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的菜单')
-        return false
-    }
-    //确认删除
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            getTableData().then()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        getTableData().then()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-</script>

+ 0 - 398
src/views/system/tenant.vue

@@ -1,398 +0,0 @@
-<template>
-    <hc-card>
-        <template #header>
-            <el-button hc-btn type="success" :disabled="tableCheckKeys.length <= 0" @click="handleSetting">授权配置</el-button>
-            <el-button hc-btn type="success" :disabled="tableCheckKeys.length <= 0" @click="handleDatasource">数据源配置</el-button>
-            <el-button hc-btn type="warning" :disabled="tableCheckKeys.length <= 0" @click="handlePackage">产品包配置</el-button>
-            <el-button hc-btn type="warning" @click="handlePackageSetting">产品包管理</el-button>
-        </template>
-        <template #extra>
-            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
-            <el-button hc-btn type="danger" @click="delClick">删除</el-button>
-        </template>
-        <template #search>
-            <div class="w-32">
-                <el-select v-model="searchType" placeholder="选择搜索类型" filterable block>
-                    <el-option label="租户ID" value="tenantId" />
-                    <el-option label="租户名称" value="tenantName" />
-                    <el-option label="联系人" value="linkman" />
-                    <el-option label="联系电话" value="contactNumber" />
-                </el-select>
-            </div>
-            <div class="ml-2 w-60">
-                <hc-search-input v-model="searchName" placeholder="请输入关键词" @search="searchClick" />
-            </div>
-        </template>
-        <hc-table
-            ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading"
-            is-check :check-style="{ width: 29 }" :index-style="{ width: 60 }"
-            @selection-change="tableCheckChange"
-        >
-            <template #accountNumber="{ row }">
-                {{ row.accountNumber > 0 ? row.accountNumber : '不限制' }}
-            </template>
-            <template #expireTime="{ row }">
-                {{ row.expireTime ? row.expireTime : '不限制' }}
-            </template>
-            <template #action="{ row }">
-                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
-                <el-link v-del-com:[delRowClick]="row" type="danger">删除</el-link>
-            </template>
-        </hc-table>
-        <template #action>
-            <hc-pages :pages="searchForm" @change="pageChange" />
-        </template>
-
-        <!-- 新增/修改 -->
-        <hc-dialog v-model="isDialogShow" widths="700px" is-footer-center :title="dialogTitle" @close="dialogClose">
-            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
-                <el-row :gutter="20">
-                    <el-col :span="12">
-                        <el-form-item label="租户名称:" prop="tenantName">
-                            <el-input v-model="formModel.tenantName" clearable placeholder="请输入租户名称" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="系统名称:" prop="tenantTitle">
-                            <el-input v-model="formModel.tenantTitle" clearable placeholder="请输入系统名称" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="联系人:" prop="linkman">
-                            <el-input v-model="formModel.linkman" clearable placeholder="请输入联系人" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="联系电话:">
-                            <el-input v-model="formModel.contactNumber" clearable placeholder="请输入联系电话" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="联系地址:">
-                            <el-input v-model="formModel.address" clearable placeholder="请输入联系地址" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="绑定域名:" prop="domainUrl">
-                            <el-input v-model="formModel.domainUrl" clearable placeholder="请输入绑定域名" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="租户图片(透明黑色图):">
-                            <hc-form-upload v-model="formModel.tenantAvatar" :options="{ type: 'preview' }" :upload="{ options: uploadOptions }" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :span="12">
-                        <el-form-item label="租户图片文字(透明黑色图):">
-                            <hc-form-upload v-model="formModel.tenantAvatarText" :options="{ type: 'preview' }" :upload="{ options: uploadOptions }" />
-                        </el-form-item>
-                    </el-col>
-                </el-row>
-            </el-form>
-            <template #footer>
-                <el-button hc-btn @click="dialogClose">取消</el-button>
-                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
-            </template>
-        </hc-dialog>
-
-        <!-- 授权配置 -->
-        <HcSettingVue v-model="isSettingShow" :info="settingInfo" @finish="settingFinish" />
-
-        <!-- 数据源配置 -->
-        <HcDataSource v-model="isSourceShow" :info="sourceInfo" @finish="sourceFinish" />
-
-        <!-- 产品包配置 -->
-        <HcPackage v-model="isPackageShow" :info="packageInfo" @finish="packageFinish" />
-
-        <!-- 产品包管理 -->
-        <HcPackageData v-model="isPackageDataShow" />
-    </hc-card>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-import { arrToId, formValidate, getArrValue } from 'js-fast-way'
-import { HcDelMsg } from 'hc-vue3-ui'
-import HcSettingVue from './modules/tenant/setting.vue'
-import HcDataSource from './modules/tenant/data-source.vue'
-import HcPackageData from './modules/tenant/package-data.vue'
-import HcPackage from './modules/tenant/package.vue'
-import mainApi from '~api/system/tenant'
-
-defineOptions({
-    name: 'Tenant',
-})
-
-//激活
-onActivated(() => {
-    searchClick()
-})
-
-//搜索表单
-const searchType = ref('tenantId')
-const searchName = ref('')
-const searchForm = ref({ current: 1, size: 30, total: 0 })
-
-//搜索
-const searchClick = () => {
-    searchForm.value.current = 1
-    getTableData()
-}
-
-//分页
-const pageChange = ({ current, size }) => {
-    searchForm.value.current = current
-    searchForm.value.size = size
-    getTableData()
-}
-
-//表格数据
-const tableRef = ref(null)
-const tableColumn = ref([
-    { key: 'tenantId', name: '租户ID', width: 80, align: 'center' },
-    { key: 'tenantName', name: '租户名称' },
-    { key: 'tenantTitle', name: '系统名称' },
-    { key: 'domainUrl', name: '绑定域名' },
-    { key: 'linkman', name: '联系人', width: 80 },
-    { key: 'contactNumber', name: '联系电话', width: 110 },
-    { key: 'accountNumber', name: '账号额度', width: 80, align: 'center' },
-    { key: 'expireTime', name: '过期时间', width: 80, align: 'center' },
-    { key: 'action', name: '操作', width: 100, align: 'center' },
-])
-
-//获取表格数据
-const tableLoading = ref(true)
-const tableData = ref([])
-const getTableData = async () => {
-    tableData.value = []
-    tableLoading.value = true
-    const form = {
-        ...searchForm.value,
-        total: null,
-    }
-    if (searchName.value) {
-        form[searchType.value] = searchName.value
-    }
-    const { error, code, data } = await mainApi.page(form)
-    tableLoading.value = false
-    if (!error && code === 200) {
-        tableData.value = getArrValue(data['records'])
-        searchForm.value.total = data['total']
-    } else {
-        tableData.value = []
-        searchForm.value.total = 0
-    }
-}
-
-//表格被选择
-const tableCheckKeys = ref([])
-const tableCheckChange = (rows) => {
-    tableCheckKeys.value = rows
-}
-
-//新增/修改 弹窗
-const isDialogShow = ref(false)
-const dialogTitle = ref('')
-
-//菜单表单
-const formRef = ref(null)
-const formModel = ref({})
-const formRules = {
-    category: {
-        required: true,
-        trigger: 'blur',
-        message: '请选择岗位类型',
-    },
-    postCode: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入岗位编号',
-    },
-    postName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入岗位名称',
-    },
-    sort: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入字典排序',
-    },
-}
-
-//新增
-const addClick = () => {
-    dialogTitle.value = '新增租户'
-    formModel.value = { sort: 1 }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//修改菜单
-const editRowClick = (row) => {
-    formModel.value = {}
-    dialogTitle.value = '修改租户'
-    formModel.value = { ...row }
-    //显示表单弹窗
-    nextTick(() => {
-        isDialogShow.value = true
-    })
-}
-
-//删除菜单
-const delRowClick = async ({ item }, resolve) => {
-    const { code, msg } = await mainApi.del(item.id)
-    if (code === 200) {
-        resolve()
-        window.$message.success('删除成功')
-        getTableData().then()
-    } else {
-        resolve()
-        window.$message.error(msg ?? '删除失败')
-    }
-}
-
-//批量删除菜单
-const delClick = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要删除的菜单')
-        return false
-    }
-    //确认删除
-    HcDelMsg(async (resolve) => {
-        //发起请求
-        const ids = arrToId(rows)
-        const { code, msg } = await mainApi.del(ids)
-        //关闭弹窗的回调
-        resolve()
-        //处理结果
-        if (code === 200) {
-            window.$message.success('删除成功')
-            getTableData().then()
-        } else {
-            window.$message.error(msg ?? '删除失败')
-        }
-    })
-}
-
-//上传文件
-const uploadOptions = {
-    url: '/api/blade-resource/oss/endpoint/put-file2',
-    accept: '.png',
-    accept_tip: '只能上传:png格式的图片',
-    multiple: false,
-}
-
-//提交表单
-const submitLoading = ref(false)
-const dialogSubmit = async () => {
-    const formRes = await formValidate(formRef.value)
-    if (!formRes) return false
-    submitLoading.value = true
-    //发起请求
-    const { error, code, msg } = await mainApi.submit(formModel.value)
-    submitLoading.value = false
-    if (!error && code === 200) {
-        dialogClose()
-        window?.$message?.success('操作成功')
-        getTableData().then()
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-    }
-}
-
-//关闭弹窗
-const dialogClose = () => {
-    isDialogShow.value = false
-    submitLoading.value = false
-    formModel.value = {}
-}
-
-//授权配置
-const isSettingShow = ref(false)
-const settingInfo = ref({})
-const handleSetting = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要授权的租户')
-        return false
-    }
-    //处理数据
-    settingInfo.value = {
-        accountNumber: rows[0].accountNumber,
-        expireTime: rows[0].expireTime,
-        ids: arrToId(rows),
-    }
-    //显示表单弹窗
-    nextTick(() => {
-        isSettingShow.value = true
-    })
-}
-//授权配置完成
-const settingFinish = () => {
-    isSettingShow.value = false
-    getTableData()
-}
-
-//数据源配置
-const isSourceShow = ref(false)
-const sourceInfo = ref({})
-const handleDatasource = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要授权的租户')
-        return false
-    }
-    if (rows.length > 1) {
-        window.$message.warning('只能选择一个租户')
-        return false
-    }
-    //处理数据
-    sourceInfo.value = { id: rows[0].id }
-    //显示表单弹窗
-    nextTick(() => {
-        isSourceShow.value = true
-    })
-}
-//数据源配置完成
-const sourceFinish = () => {
-    isSourceShow.value = false
-    getTableData()
-}
-
-
-//产品包配置
-const isPackageShow = ref(false)
-const packageInfo = ref({})
-const handlePackage = () => {
-    const rows = tableCheckKeys.value
-    if (rows.length <= 0) {
-        window.$message.warning('请选择要授权的租户')
-        return false
-    }
-    if (rows.length > 1) {
-        window.$message.warning('只能选择一个租户')
-        return false
-    }
-    //处理数据
-    packageInfo.value = { id: rows[0].id }
-    //显示表单弹窗
-    nextTick(() => {
-        isPackageShow.value = true
-    })
-}
-//产品包配置完成
-const packageFinish = () => {
-    isPackageShow.value = false
-    getTableData()
-}
-
-//产品包管理
-const isPackageDataShow = ref(false)
-const handlePackageSetting = () => {
-    isPackageDataShow.value = true
-}
-</script>

+ 0 - 7
src/views/system/user.vue

@@ -1,7 +0,0 @@
-<template>
-    <div>user</div>
-</template>
-
-<script setup>
-import { nextTick, onActivated, ref } from 'vue'
-</script>

+ 0 - 197
src/views/user/index.vue

@@ -1,197 +0,0 @@
-<template>
-    <hc-card is-action-btn>
-        <el-tabs tab-position="left" class="hc-h-full">
-            <el-tab-pane label="个人信息">
-                <div class="relative w-[460px] p-4">
-                    <el-form ref="formUserRef" :model="formUserModel" :rules="formUserRules" label-position="top">
-                        <el-form-item label="头像图片:" prop="avatar">
-                            <hc-form-upload v-model="formUserModel.avatar" :options="{ type: 'preview' }" :upload="avatarUpOptions" />
-                        </el-form-item>
-                        <el-form-item label="姓名:" prop="name">
-                            <el-input v-model="formUserModel.name" />
-                        </el-form-item>
-                        <el-form-item label="用户名:" prop="realName">
-                            <el-input v-model="formUserModel.realName" />
-                        </el-form-item>
-                        <el-form-item label="手机号码:" prop="phone">
-                            <el-input v-model="formUserModel.phone" />
-                        </el-form-item>
-                        <el-form-item label="电子邮箱:">
-                            <el-input v-model="formUserModel.email" />
-                        </el-form-item>
-                    </el-form>
-                </div>
-            </el-tab-pane>
-            <el-tab-pane label="修改密码">
-                <div class="relative w-[460px] p-4">
-                    <el-form ref="formPasswordRef" :model="formPasswordModel" :rules="formPasswordRules" label-position="top">
-                        <el-form-item label="原密码:" prop="oldPassword">
-                            <el-input v-model="formPasswordModel.oldPassword" />
-                        </el-form-item>
-                        <el-form-item label="新密码:" prop="newPassword">
-                            <el-input v-model="formPasswordModel.newPassword" />
-                        </el-form-item>
-                        <el-form-item label="确认密码:" prop="newPassword1">
-                            <el-input v-model="formPasswordModel.newPassword1" />
-                        </el-form-item>
-                    </el-form>
-                </div>
-            </el-tab-pane>
-        </el-tabs>
-        <template #action>
-            <el-button hc-btn @click="resetClick">重置</el-button>
-            <el-button hc-btn type="primary" :loading="submitLoading" @click="submitClick">提交</el-button>
-        </template>
-    </hc-card>
-</template>
-
-<script setup>
-import { onActivated, ref } from 'vue'
-import { deepClone, formValidate, getObjValue, isPhone } from 'js-fast-way'
-import { avatarUpOptions } from 'hc-vue3-ui'
-import mainApi from '~api/system/user'
-import { reloadPage } from '~uti/tools.js'
-
-defineOptions({
-    name: 'UserInfo',
-})
-
-onActivated(() => {
-    getUserInfoApi()
-})
-
-//获取用户信息
-const oldUserInfo = ref({})
-const getUserInfoApi = async () => {
-    const { data } = await mainApi.getUserInfo()
-    const res = getObjValue(data)
-    oldUserInfo.value = res
-    formUserModel.value = deepClone(res)
-}
-
-//个人信息表单
-const formUserRef = ref(null)
-const formUserModel = ref({})
-const formUserRules = {
-    avatar: {
-        required: true,
-        trigger: 'blur',
-        message: '请上传头像图片',
-    },
-    name: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入姓名',
-    },
-    realName: {
-        required: true,
-        trigger: 'blur',
-        message: '请输入用户名',
-    },
-    phone: {
-        required: true,
-        validator: (rule, value, callback) => {
-            if (!value) {
-                callback(new Error('请输入手机号'))
-            } else if (!isPhone(value)) {
-                callback(new Error('手机号码格式错误'))
-            } else {
-                callback()
-            }
-        },
-        trigger: 'blur',
-    },
-}
-
-//密码表单
-const formPasswordRef = ref(null)
-const formPasswordModel = ref({})
-const formPasswordRules = {
-    oldPassword: {
-        required: true,
-        trigger: 'blur',
-        message: '请上传头像图片',
-    },
-    newPassword: {
-        required: true,
-        validator: (rule, value, callback) => {
-            const { newPassword1 } = formPasswordModel.value
-            if (!value) {
-                callback(new Error('请输入新的密码'))
-            } else if (newPassword1 && value !== newPassword1) {
-                callback(new Error('新的密码和确认新密码不一致'))
-            } else {
-                callback()
-            }
-        },
-        trigger: 'blur',
-    },
-    newPassword1: {
-        required: true,
-        validator: (rule, value, callback) => {
-            const { newPassword } = formPasswordModel.value
-            if (!value) {
-                callback(new Error('请输入确认新密码'))
-            } else if (newPassword && value !== newPassword) {
-                callback(new Error('新的密码和确认新密码不一致'))
-            } else {
-                callback()
-            }
-        },
-        trigger: 'blur',
-    },
-}
-
-//重置
-const resetClick = () => {
-    formUserModel.value = deepClone(oldUserInfo.value)
-}
-
-//提交
-const submitLoading = ref(false)
-const submitClick = async () => {
-    submitLoading.value = true
-    //修改用户信息
-    const isUserRes = await updateUserInfo()
-    //修改密码
-    const isPasswordRes = await updatePasswordInfo()
-    submitLoading.value = false
-    //状态提示
-    if (isUserRes || isPasswordRes) {
-        window?.$message?.success('保存成功')
-        reloadPage()
-    }
-}
-
-//修改用户信息
-const updateUserInfo = async () => {
-    const formRes = await formValidate(formUserRef.value)
-    if (!formRes) return false
-    const { id, avatar, name, realName, phone, email } = formUserModel.value
-    const { error, code, msg } = await mainApi.updateInfo({
-        id, avatar, name, realName, phone, email,
-    })
-    if (!error && code === 200) {
-        return true
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-        return false
-    }
-}
-
-//修改密码
-const updatePasswordInfo = async () => {
-    const formRes = await formValidate(formPasswordRef.value)
-    if (!formRes) return false
-    const { oldPassword, newPassword, newPassword1 } = formPasswordModel.value
-    const { error, code, msg } = await mainApi.updatePassword({
-        oldPassword, newPassword, newPassword1, plaintextPassword: newPassword,
-    })
-    if (!error && code === 200) {
-        return true
-    } else {
-        window?.$message?.error(msg ?? '操作失败')
-        return false
-    }
-}
-</script>