From e5e86e24e5133e57f256f313651563df72934f70 Mon Sep 17 00:00:00 2001 From: qsh <> Date: Wed, 28 May 2025 12:04:02 +0800 Subject: [PATCH] sc --- .env.base | 4 +- src/permission.js | 12 +- src/router/modules/static.ts | 47 +++++ src/store/modules/permission.ts | 21 +++ src/store/modules/user.ts | 1 + src/utils/tableObjectSpanMethod.js | 80 ++++++++ src/views/OKR/Analysis/index.vue | 177 ++++++++++++++++++ .../OKR/Management/Components/AllTarget.vue | 13 +- .../OKR/Management/Components/MyDuty.vue | 13 +- src/views/OKR/Management/Components/MySon.vue | 13 +- .../OKR/Management/Components/OkrTable.vue | 4 + src/views/OKR/Management/index.vue | 6 +- .../Components/DialogWait.vue | 0 .../WaitTarget.vue => Wait/index.vue} | 2 +- 14 files changed, 370 insertions(+), 23 deletions(-) create mode 100644 src/router/modules/static.ts create mode 100644 src/utils/tableObjectSpanMethod.js create mode 100644 src/views/OKR/Analysis/index.vue rename src/views/OKR/{Management => Wait}/Components/DialogWait.vue (100%) rename src/views/OKR/{Management/Components/WaitTarget.vue => Wait/index.vue} (99%) diff --git a/.env.base b/.env.base index 978fb4c..4bc8726 100644 --- a/.env.base +++ b/.env.base @@ -6,9 +6,9 @@ VITE_DEV=true # 请求路径 # VITE_BASE_URL='http://localhost:48080' -VITE_BASE_URL='http://47.98.161.246:48080' +# VITE_BASE_URL='http://47.98.161.246:48080' # VITE_BASE_URL='http://114.55.169.15:48080' -# VITE_BASE_URL='http://114.215.207.150:48080' +VITE_BASE_URL='http://114.215.207.150:48080' # 上传路径 VITE_UPLOAD_URL='http://47.98.161.246:48080/admin-api/system/file/upload' diff --git a/src/permission.js b/src/permission.js index 52f958a..2eac4ef 100644 --- a/src/permission.js +++ b/src/permission.js @@ -20,18 +20,20 @@ const whiteList = ['/login', '/social-login', '/auth-redirect', '/bind', '/regis router.beforeEach(async (to, from, next) => { start() loadStart() + const userStore = useUserStoreWithOut() + if (to.path == '/login') { + userStore.resetState() // 重置用户信息状态 + } if (getAccessToken()) { if (to.path === '/login') { if (to.query?.tenantId && to.query?.appId) { setApp(to.query.tenantId, to.query.appId) await waitTime(1500) - } else { - next({ path: '/' }) } + next({ path: '/' }) } else { // 获取所有字典 const dictStore = useDictStoreWithOut() - const userStore = useUserStoreWithOut() const permissionStore = usePermissionStoreWithOut() if (!dictStore.getIsSetDict) { await dictStore.setDictMap() @@ -60,9 +62,9 @@ router.beforeEach(async (to, from, next) => { const tenantId = getTenantId() const appId = getAppId() if (tenantId && appId) { - next(`/oa/login?tenantId=${tenantId}&appId=${appId}&redirect=${to.fullPath}`) // 否则全部重定向到登录页 + next(`/login?tenantId=${tenantId}&appId=${appId}&redirect=${to.fullPath}`) // 否则全部重定向到登录页 } else { - next(`/oa/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页 + next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页 } } } diff --git a/src/router/modules/static.ts b/src/router/modules/static.ts new file mode 100644 index 0000000..e33943f --- /dev/null +++ b/src/router/modules/static.ts @@ -0,0 +1,47 @@ +const staticRouter: AppCustomRouteRecordRaw[] = [ + { + icon: 'ep:calendar', + path: '/Okr', + component: '', + name: 'OKR', + componentName: '', + redirect: '', + parentId: 0, + visible: true, + alwaysShow: true, + children: [ + { + icon: 'ep:finished', + path: 'okr-management', + name: 'OKR管理', + componentName: 'OkrManagement', + component: 'OKR/Management/index', + visible: true, + alwaysShow: true, + meta: { + title: 'OKR管理' + }, + redirect: '' + }, + { + icon: 'ep:alarm-clock', + path: 'okr-wait', + name: '待办事项', + componentName: 'OkrWait', + component: 'OKR/Wait/index', + meta: { + title: '待办事项' + }, + visible: true, + alwaysShow: true, + redirect: '' + } + ], + meta: { + title: 'OKR', + icon: 'ep:calendar' + } + } +] + +export default staticRouter diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts index 1b1d94e..e9b38c6 100644 --- a/src/store/modules/permission.ts +++ b/src/store/modules/permission.ts @@ -2,6 +2,7 @@ import { defineStore } from 'pinia' import { store } from '../index' import { cloneDeep } from 'lodash-es' import remainingRouter from '@/router/modules/remaining' +import staticRouter from '@/router/modules/static' import { generateRoute, flatMultiLevelRoutes } from '@/utils/routerHelper' import { CACHE_KEY } from '@/hooks/web/useCache' @@ -37,6 +38,25 @@ export const usePermissionStore = defineStore('permission', { if (cache.local.get(CACHE_KEY.ROLE_ROUTERS)) { res = cache.local.get(CACHE_KEY.ROLE_ROUTERS) as AppCustomRouteRecordRaw[] } + const staticRouters = cloneDeep(staticRouter) + // 与动态路由比较,首先判断目录是否存在,如果存在就合并,并替换动态路由中的目录 + staticRouters.forEach((item) => { + const index = res.findIndex((item2) => item2.path === item.path) + if (index !== -1) { + const arr = [] + if (!item.children || item.children.length === 0) { + item.children = arr + } + if (res[index].children && res[index].children.length > 0) { + item.children = item.children.concat(res[index].children) + } + // routerMap[index].children = item.children + // 插入动态路由数组的第二位 + res[index] = { ...res, ...item } + } else { + res = [...staticRouters, ...res] + } + }) const routerMap: AppRouteRecordRaw[] = generateRoute(res) // 动态路由,404一定要放到最后面 this.addRouters = routerMap.concat([ @@ -50,6 +70,7 @@ export const usePermissionStore = defineStore('permission', { } } ]) + // 渲染菜单的所有路由 this.routers = cloneDeep(remainingRouter).concat(routerMap) resolve() diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 23cd47d..c687e6e 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -75,6 +75,7 @@ export const useUserStore = defineStore('admin-user', { avatar: '', nickname: '' } + cache.local.delete(CACHE_KEY.USER) }, refresh() { cache.local.delete(CACHE_KEY.USER) diff --git a/src/utils/tableObjectSpanMethod.js b/src/utils/tableObjectSpanMethod.js new file mode 100644 index 0000000..2dabd28 --- /dev/null +++ b/src/utils/tableObjectSpanMethod.js @@ -0,0 +1,80 @@ +/** + * @Author: River_qiu + * @Date: 2021/11/18 + */ +// 表格单元格合并多列 +let [spanObj, pos] = [{}, {}] +//spanObj 存储每个key 对应的合并值 +//pos 存储的是 key合并值得索引 大概吧 +export const dataMethod = (data, isH, allColumns = []) => { + //循环数据(行) + for (let i in data) { + let dataI = data[i] + //循环数据内对象,查看有多少key + if (allColumns.length > 0) { + let preProp = undefined + // dataI.historyValue = + // 循环列数据 + for (let index = 0; index < allColumns.length; index++) { + let j = allColumns[index] + if (i == 0) { + // 第一行,每列至少展示1行 + spanObj[j] = [1] + pos[j] = 0 + } else { + if (index == 0) { + data[i].historyValue = '' + data[i - 1].historyValue = '' + } else { + data[i].historyValue += data[i][preProp] + data[i - 1].historyValue += data[i - 1][preProp] + } + // e: 当前行数据,k:上一行数据 + let [e, k] = [dataI, data[i - 1]] + // 判断上一行数据是否存在 + // 空数据不合并 + // 前一列值相同并且不为空或者为第一列 + // 存在当前的列的值与上一行是否一样 + // 判断是否有数组规定只允许那几列需要合并单元格的 + if ( + k && + e[j] && + (!preProp || (e.historyValue && e.historyValue == k.historyValue)) && + e[j] == k[j] && + (!isH || isH.length == 0 || isH.includes(j)) + ) { + //如果上一级和当前一级相当,数组就加1 数组后面就添加一个0 + spanObj[j][pos[j]] += 1 + spanObj[j].push(0) + } else { + spanObj[j].push(1) + pos[j] = i + } + preProp = j + } + } + } else { + for (let j in dataI) { + //如果只有一条数据时默认为1即可,无需合并 + if (i == 0) { + spanObj[j] = [1] + pos[j] = 0 + } else { + let [e, k] = [dataI, data[i - 1]] + //判断上一级别是否存在 , + //存在当前的key是否和上级别的key是否一样 + //判断是否有数组规定只允许那几列需要合并单元格的 + if (k && e[j] && k[j] && e[j] == k[j] && (!isH || isH.length == 0 || isH.includes(j))) { + //如果上一级和当前一级相当,数组就加1 数组后面就添加一个0 + spanObj[j][pos[j]] += 1 + spanObj[j].push(0) + } else { + spanObj[j].push(1) + pos[j] = i + } + } + } + } + } + return spanObj +} diff --git a/src/views/OKR/Analysis/index.vue b/src/views/OKR/Analysis/index.vue new file mode 100644 index 0000000..3b8d285 --- /dev/null +++ b/src/views/OKR/Analysis/index.vue @@ -0,0 +1,177 @@ + + + + + diff --git a/src/views/OKR/Management/Components/AllTarget.vue b/src/views/OKR/Management/Components/AllTarget.vue index ea757e1..55a7f7a 100644 --- a/src/views/OKR/Management/Components/AllTarget.vue +++ b/src/views/OKR/Management/Components/AllTarget.vue @@ -72,7 +72,7 @@ const isCurrentLeafNode = ref(false) function handleSearchPeroid() { getAllNodeTree().then((resp) => { if (resp.nodeId) { - peroidList.value = listToTree(resp.tree, { + peroidList.value = listToTree(resp?.tree || [], { id: 'nodeId', pid: 'parentId', children: 'children' @@ -103,9 +103,14 @@ function nodeChange(nodeId) { function getOkrList() { getAllOkrPage(searchForm.value).then((resp) => { const list = resp - nextTick(() => { - okrTableRef.value.prepareData(list) - }) + if (list && list.length > 0) { + nextTick(() => { + okrTableRef.value.prepareData(list) + }) + } else { + // 如果没有数据,清空表格 + okrTableRef.value.prepareData([]) + } }) } diff --git a/src/views/OKR/Management/Components/MyDuty.vue b/src/views/OKR/Management/Components/MyDuty.vue index f5a833d..6373f79 100644 --- a/src/views/OKR/Management/Components/MyDuty.vue +++ b/src/views/OKR/Management/Components/MyDuty.vue @@ -53,7 +53,7 @@ handleSearchPeroid() function handleSearchPeroid() { getMyNodeTree().then((resp) => { - peroidList.value = listToTree(resp.tree, { + peroidList.value = listToTree(resp?.tree || [], { id: 'nodeId', pid: 'parentId', children: 'children' @@ -66,9 +66,14 @@ function handleSearchPeroid() { function getOkrList() { getMyOkrPage(searchForm.value).then((resp) => { const list = resp - nextTick(() => { - okrTableRef.value.prepareData(list) - }) + if (list && list.length > 0) { + nextTick(() => { + okrTableRef.value.prepareData(list) + }) + } else { + // 如果没有数据,清空表格 + okrTableRef.value.prepareData([]) + } }) } diff --git a/src/views/OKR/Management/Components/MySon.vue b/src/views/OKR/Management/Components/MySon.vue index f407afc..2b2ad26 100644 --- a/src/views/OKR/Management/Components/MySon.vue +++ b/src/views/OKR/Management/Components/MySon.vue @@ -66,7 +66,7 @@ handleSearchPeroid() function handleSearchPeroid() { getMySonNodeTree({ userId: props.userId }).then((resp) => { - peroidList.value = listToTree(resp.tree, { + peroidList.value = listToTree(resp?.tree || [], { id: 'nodeId', pid: 'parentId', children: 'children' @@ -80,9 +80,14 @@ function getOkrList() { ...searchForm.value, userId: props.userId }).then((resp) => { - nextTick(() => { - okrTableRef.value.prepareData(resp) - }) + if (resp && resp.length > 0) { + nextTick(() => { + okrTableRef.value.prepareData(resp) + }) + } else { + // 如果没有数据,清空表格 + okrTableRef.value.prepareData([]) + } }) } diff --git a/src/views/OKR/Management/Components/OkrTable.vue b/src/views/OKR/Management/Components/OkrTable.vue index bb5c7a4..d1f165c 100644 --- a/src/views/OKR/Management/Components/OkrTable.vue +++ b/src/views/OKR/Management/Components/OkrTable.vue @@ -82,6 +82,10 @@ const okrList = ref([]) const helpList = ref([]) function prepareData(list) { + if (!list || !Array.isArray(list) || list.length === 0) { + okrList.value = [] + return + } helpList.value = [] expandedRows.value = {} okrList.value = list.map((item) => { diff --git a/src/views/OKR/Management/index.vue b/src/views/OKR/Management/index.vue index 95c367b..c8c9d0c 100644 --- a/src/views/OKR/Management/index.vue +++ b/src/views/OKR/Management/index.vue @@ -11,9 +11,9 @@ - + @@ -48,7 +48,7 @@ import AllTarget from './Components/AllTarget.vue' import MyDuty from './Components/MyDuty.vue' import MySon from './Components/MySon.vue' import ObjectList from './Components/ObjectList.vue' -import WaitTarget from './Components/WaitTarget.vue' +// import WaitTarget from './Components/WaitTarget.vue' import { getMyMemberList } from '@/api/okr/okr' diff --git a/src/views/OKR/Management/Components/DialogWait.vue b/src/views/OKR/Wait/Components/DialogWait.vue similarity index 100% rename from src/views/OKR/Management/Components/DialogWait.vue rename to src/views/OKR/Wait/Components/DialogWait.vue diff --git a/src/views/OKR/Management/Components/WaitTarget.vue b/src/views/OKR/Wait/index.vue similarity index 99% rename from src/views/OKR/Management/Components/WaitTarget.vue rename to src/views/OKR/Wait/index.vue index f012c1d..44e1545 100644 --- a/src/views/OKR/Management/Components/WaitTarget.vue +++ b/src/views/OKR/Wait/index.vue @@ -165,7 +165,7 @@