From 81a384799226f66a47ed16ab4a238ba900d943e1 Mon Sep 17 00:00:00 2001 From: qsh <> Date: Fri, 11 Apr 2025 17:24:41 +0800 Subject: [PATCH] sc --- src/api/okr/okr.js | 18 ++ src/views/Basic/Dept/index.vue | 11 +- .../OKR/Management/Components/AllTarget.vue | 20 +- .../OKR/Management/Components/DialogOkr.vue | 35 ++-- .../OKR/Management/Components/DialogWait.vue | 2 +- .../OKR/Management/Components/MyDuty.vue | 26 ++- .../OKR/Management/Components/ObjectList.vue | 175 +++++++++--------- .../OKR/Management/Components/OkrTable.vue | 2 +- 8 files changed, 168 insertions(+), 121 deletions(-) diff --git a/src/api/okr/okr.js b/src/api/okr/okr.js index a274ab0..0289278 100644 --- a/src/api/okr/okr.js +++ b/src/api/okr/okr.js @@ -90,3 +90,21 @@ export const updateOkrProgress = (data) => { // headers: { 'instance-id': 1016 } }) } + +// 获取目标关系树一级节点 +export const getOkrRelationTree = (params) => { + return request.get({ + url: '/admin-api/okr/node/first-node', + params + // headers: { 'instance-id': 1016 } + }) +} + +// 获取目标关系树下级节点数据 +export const getOkrRelationTreeChildren = (params) => { + return request.get({ + url: '/admin-api/okr/node/node-tree', + params + // headers: { 'instance-id': 1016 } + }) +} diff --git a/src/views/Basic/Dept/index.vue b/src/views/Basic/Dept/index.vue index 2cfa701..dbcae05 100644 --- a/src/views/Basic/Dept/index.vue +++ b/src/views/Basic/Dept/index.vue @@ -22,8 +22,15 @@ <el-table v-loading="loading" :data="list" row-key="id" default-expand-all border> <el-table-column prop="name" label="部门名称" /> <el-table-column prop="leaderUserName" label="负责人" width="120" /> - <el-table-column prop="sort" label="排序" width="200" /> - <el-table-column prop="status" label="状态" width="100" /> + <el-table-column prop="" label="业务系统" width="200" /> + <el-table-column prop="sort" label="排序" width="80" /> + <el-table-column prop="status" label="状态" width="100"> + <template #default="scope"> + <el-tag :type="scope.row.status == 0 ? 'success' : 'danger'"> + {{ scope.row.status == 0 ? '正常' : '停用' }} + </el-tag> + </template> + </el-table-column> <el-table-column label="创建时间" prop="createTime" width="180" :formatter="dateFormatter" /> <el-table-column label="操作" class-name="fixed-width" width="160"> <template #default="scope"> diff --git a/src/views/OKR/Management/Components/AllTarget.vue b/src/views/OKR/Management/Components/AllTarget.vue index df18538..5410f73 100644 --- a/src/views/OKR/Management/Components/AllTarget.vue +++ b/src/views/OKR/Management/Components/AllTarget.vue @@ -16,10 +16,19 @@ </el-row> <el-row> <el-button type="info" @click="handleShowOkr(searchForm.nodeId)"> 节点详情 </el-button> - <el-button type="warning" @click="handleEditOkr(searchForm.nodeId)"> + <el-button + type="warning" + v-if="currentUserId == searchForm.creatorId" + @click="handleEditOkr(searchForm.nodeId)" + > 修改当前节点 </el-button> - <el-button type="success" @click="handleUpdateProcess">更新进度</el-button> + <el-button + type="success" + v-if="searchForm.executor?.includes(currentUserId)" + @click="handleUpdateProcess" + >更新进度</el-button + > </el-row> </div> @@ -36,8 +45,11 @@ import DialogOkr from './DialogOkr.vue' import { getAllNodeTree, getAllOkrPage } from '@/api/okr/okr' import { listToTree, findNode } from '@/utils/tree' +import { useUserStore } from '@/store/modules/user' const message = useMessage() +const userStore = useUserStore() +const currentUserId = userStore.getUser.id const defaultProps = { value: 'nodeId', @@ -52,9 +64,7 @@ const searchForm = ref({ const peroidList = ref([]) -onMounted(() => { - handleSearchPeroid() -}) +handleSearchPeroid() // 当前是否是叶子节点 // 如果不是叶子节点,则表格数据不可修改 diff --git a/src/views/OKR/Management/Components/DialogOkr.vue b/src/views/OKR/Management/Components/DialogOkr.vue index be1e43d..599d323 100644 --- a/src/views/OKR/Management/Components/DialogOkr.vue +++ b/src/views/OKR/Management/Components/DialogOkr.vue @@ -22,7 +22,7 @@ </div> </div> <div class="flex items-center"> - <el-button link @click="emit('edit')"> + <el-button v-if="nodeInfo.creatorId == currentUserId" link @click="emit('edit')"> <el-tooltip content="编辑" placement="top" effect="dark"> <Icon icon="ep:edit" :size="16" /> </el-tooltip> @@ -47,7 +47,7 @@ </div> <div class="basic-title-item"> <div class="basic-title-label">执行人</div> - <div class="basic-title-value">{{ nodeInfo.executorName }}</div> + <div class="basic-title-value">{{ nodeInfo.executorName || '无' }}</div> </div> <div class="basic-title-item"> <div class="basic-title-label">目标数</div> @@ -55,7 +55,7 @@ </div> <div class="basic-title-item" style="min-width: 200px"> <div class="basic-title-label">总体进度</div> - <el-progress :percentage="nodeInfo.progress || 0" :stroke-width="8" /> + <el-progress :percentage="parseInt(nodeInfo.progress) || 0" :stroke-width="8" /> </div> </div> <div class="flex detail-basic-info"> @@ -72,7 +72,7 @@ </div> </el-tab-pane> </el-tabs> - <el-button class="sav-btn" type="primary" @click="handleSaveProcess"> + <el-button v-if="canEdit" class="sav-btn" type="primary" @click="handleSaveProcess"> 保存并更新 </el-button> </div> @@ -86,7 +86,7 @@ :key="item.nodeId" class="border-b-1 child-item" style="padding: 10px 5px; cursor: pointer" - @click="handleChildItem" + @click="handleChildItem(item)" > <div class="flex justify-between items-center overflow-hidden text-16px" @@ -95,21 +95,21 @@ <div class="child-label">【节点】{{ item.nodeName }}</div> <el-progress type="line" - :percentage="item.progress || 0" + :percentage="parseInt(item.progress) || 0" :stroke-width="6" style="width: 120px" /> </div> <div class="ml-10px flex items-center text-13px" style="line-height: 30px"> <span>目标数:</span> - <span style="color: #aaa">{{ item.objectiveCount }}</span> + <span style="color: #aaa">{{ item.objectiveNum }}</span> <el-divider direction="vertical" style="margin: 0 20px" /> <div class="flex-1 overflow-hidden h-30px" style="text-overflow: ellipsis; white-space: nowrap" > <span>执行人:</span> - <span style="color: #aaa">{{ item.executorName }}</span> + <span style="color: #aaa">{{ item.executorName || '无' }}</span> </div> </div> <div @@ -314,8 +314,11 @@ import { } from '@/api/okr/comment' import { listToTree } from '@/utils/tree' import { getEmployeeSimpleList } from '@/api/pers/employee' +import { useUserStore } from '@/store/modules/user' const message = useMessage() +const userStore = useUserStore() +const currentUserId = userStore.getUser.id const emit = defineEmits(['edit']) const show = ref(false) @@ -348,7 +351,7 @@ const nodeInfo = ref({}) const nodeRecords = ref([]) const commentTypeOptions = ref([]) -async function open(curNode) { +function open(curNode) { canEdit.value = curNode.canEdit nodeInfo.value.nodeId = curNode.nodeId // 获取数据详情 @@ -361,7 +364,12 @@ const employeeOptions = ref([]) function searchInfo(curNode) { try { getOkrNodeDetail(curNode.nodeId).then((resp) => { - nodeInfo.value = resp + nodeInfo.value = { + ...resp, + executor: resp.executor || [] + } + canEdit.value = + canEdit.value && currentUserId == nodeInfo.value.executor.includes(currentUserId) if (resp.objectives) { okrList.value = resp.objectives.map((item) => ({ ...item, @@ -410,8 +418,11 @@ function handleSaveProcess() { }) } -function handleChildItem() { - console.log('handleChildItem') +function handleChildItem(item) { + const arr = item.executor || [] + const isExecutor = arr.includes(currentUserId) + canEdit.value = isExecutor && (!item.children || item.children.length == 0) + searchInfo(item) } const addNewComment = ref(false) diff --git a/src/views/OKR/Management/Components/DialogWait.vue b/src/views/OKR/Management/Components/DialogWait.vue index 3358838..25c1697 100644 --- a/src/views/OKR/Management/Components/DialogWait.vue +++ b/src/views/OKR/Management/Components/DialogWait.vue @@ -237,7 +237,7 @@ const rules = ref({ const followList = ref([]) -async function open(type, id) { +function open(type, id) { show.value = true title.value = { create: '新增待办', update: '修改待办', do: '更新待办进度' }[type] formType.value = type diff --git a/src/views/OKR/Management/Components/MyDuty.vue b/src/views/OKR/Management/Components/MyDuty.vue index 4348149..afa1215 100644 --- a/src/views/OKR/Management/Components/MyDuty.vue +++ b/src/views/OKR/Management/Components/MyDuty.vue @@ -13,11 +13,12 @@ /> </el-row> <el-row> + <el-button type="info" @click="handleShowOkr(searchForm.nodeId)"> 节点详情 </el-button> <el-button type="success" @click="handleUpdateProcess">更新进度</el-button> </el-row> </div> - <OkrTable ref="okrTableRef" @row-click="handleShowOkr" /> + <OkrTable ref="okrTableRef" canEdit /> <DialogOkr ref="dialogOkr" @edit="handleEditOkr" /> <DialogOkrInfo ref="dialogOkrInfo" /> </div> @@ -46,11 +47,11 @@ const searchForm = ref({ const peroidList = ref([]) -onMounted(() => { - handleSearchPeroid() -}) +// onMounted(() => { +handleSearchPeroid() +// }) -async function handleSearchPeroid() { +function handleSearchPeroid() { getMyNodeTree().then((resp) => { peroidList.value = listToTree(resp.tree, { id: 'nodeId', @@ -62,7 +63,7 @@ async function handleSearchPeroid() { }) } -async function getOkrList() { +function getOkrList() { getMyOkrPage(searchForm.value).then((resp) => { const list = resp nextTick(() => { @@ -82,13 +83,18 @@ function handleEditOkr() { } function handleUpdateProcess() { - message.success('更新进度成功') - getOkrList() + okrTableRef.value.updateProcess(searchForm.value.nodeId).then(() => { + message.success('更新成功') + getOkrList() + }) } const dialogOkr = ref(null) -function handleShowOkr(row) { - dialogOkr.value.open(row.id) +function handleShowOkr(id) { + dialogOkr.value.open({ + nodeId: id, + canEdit: true + }) } </script> diff --git a/src/views/OKR/Management/Components/ObjectList.vue b/src/views/OKR/Management/Components/ObjectList.vue index ab1bf0d..04991b0 100644 --- a/src/views/OKR/Management/Components/ObjectList.vue +++ b/src/views/OKR/Management/Components/ObjectList.vue @@ -6,7 +6,7 @@ <div class="flex items-center border-1px w-300px h-32px p-10px peroid-select"> <Icon icon="ep:calendar" style="color: #aaa" /> <span class="text-14px ml-10px" style="color: #aaa"> - {{ searchForm.peroidName ? searchForm.peroidName : '选择周期' }} + {{ searchForm.nodeName ? searchForm.nodeName : '选择周期' }} </span> </div> </template> @@ -15,11 +15,13 @@ <el-table :data="peroidList" @row-click="handleSelectPeroid"> <el-table-column label="节点名称"> <template #default="{ row }"> - <el-radio v-model="searchForm.peroidId" :label="row.id">{{ row.name }}</el-radio> + <el-radio v-model="searchForm.nodeId" :label="row.nodeId">{{ + row.nodeName + }}</el-radio> </template> </el-table-column> - <el-table-column label="开始日期" prop="startDate" width="120" /> - <el-table-column label="截止日期" prop="endDate" width="120" /> + <el-table-column label="开始日期" prop="startTime" width="120" /> + <el-table-column label="截止日期" prop="endTime" width="120" /> </el-table> </div> </div> @@ -27,7 +29,13 @@ <el-button class="ml-10px" type="primary" @click="handleAddNode">新建节点</el-button> </div> - <vue3-tree-org :data="dataList" center collapsable @on-node-click="handleClickNode"> + <vue3-tree-org + :data="dataList" + center + collapsable + :props="treeProps" + @on-node-click="handleClickNode" + > <template #default="{ node }"> <div style="cursor: pointer"> <div class="tree-org-node__text node-label"> @@ -35,15 +43,19 @@ <template #reference> <div> <div style="max-height: 40px; overflow: hidden">{{ node.label }}</div> - <div class="tip"> 目标数: 3</div> + <div class="tip"> 目标数: {{ getNodePropData(node.id, 'objectiveNum') }}</div> + <!-- 执行人 --> + <div class="tip"> + 执行人: {{ getNodePropData(node.id, 'executorName') || '无' }} + </div> </div> </template> <template #default> <div style="font-size: 0.875rem; line-height: 1.5"> - <div v-for="i in 3" :key="i" class="mt-5"> - <span style="color: #aaa">0%</span> + <div v-for="i in getNodePropData(node.id, 'objectives')" :key="i.id" class="mt-5"> + <span style="color: #aaa">{{ parseInt(i.progress) }}%</span> <span style="margin-left: 0.5rem"> - 成交数达到10个,且订单的利润不能低于成交价的30% + {{ i.objectiveName }} </span> </div> </div> @@ -51,7 +63,12 @@ </el-popover> </div> <div class="p-5px"> - <el-progress type="line" :percentage="80" text-inside :stroke-width="12" /> + <el-progress + type="line" + :percentage="parseInt(getNodePropData(node.id, 'progress')) || 0" + text-inside + :stroke-width="12" + /> </div> </div> </template> @@ -67,95 +84,69 @@ import 'vue3-tree-org/lib/vue3-tree-org.css' import DialogOkr from './DialogOkr.vue' import DialogOkrInfo from './DialogOkrInfo.vue' -const dataList = ref({ - id: 1, - label: '寻驾全年目标', - noDragging: true, - disabled: true, - children: [ - { - id: 2, - pid: 1, - label: '1月', - noDragging: true, - disabled: true, - children: [ - { id: 6, pid: 2, label: '第一周', noDragging: true, disabled: true }, - { id: 8, pid: 2, label: '第二周', noDragging: true, disabled: true }, - { id: 10, pid: 2, label: '第三周', noDragging: true, disabled: true }, - { id: 10, pid: 2, label: '第四周', noDragging: true, disabled: true } - ] - }, - { - id: 3, - pid: 1, - label: '2月', - noDragging: true, - disabled: true, - children: [ - { id: 6, pid: 2, label: '第一周', noDragging: true, disabled: true }, - { id: 8, pid: 2, label: '第二周', noDragging: true, disabled: true }, - { id: 10, pid: 2, label: '第三周', noDragging: true, disabled: true }, - { id: 10, pid: 2, label: '第四周', noDragging: true, disabled: true } - ] - }, - { - id: 4, - pid: 1, - label: '3月', - noDragging: true, - disabled: true, - children: [ - { id: 6, pid: 2, label: '第一周', noDragging: true, disabled: true }, - { id: 8, pid: 2, label: '第二周', noDragging: true, disabled: true }, - { id: 10, pid: 2, label: '第三周', noDragging: true, disabled: true }, - { id: 10, pid: 2, label: '第四周', noDragging: true, disabled: true } - ] - } - ] -}) +import { getOkrRelationTree, getOkrRelationTreeChildren } from '@/api/okr/okr' +import { listToTree } from '@/utils/tree' + +const dataList = ref({}) +const helpDataList = ref([]) +const treeProps = { + children: 'children', + label: 'nodeName', + id: 'nodeId', + pid: 'parentId' +} const searchForm = ref({ - peroidName: '', - peroidId: null + nodeName: '', + nodeId: null }) const peroidList = ref([]) -onMounted(() => { - handleSearchPeroid() - if (!searchForm.value.peroidId && peroidList.value.length) { - searchForm.value.peroidId = peroidList.value[0].id - searchForm.value.peroidName = peroidList.value[0].name - } - handleSearchOkr() -}) +handleSearchPeroid() -async function handleSearchPeroid() { - peroidList.value = [ - { - id: 1, - name: '2025年寻驾okr', - startDate: '2022-01-01', - endDate: '2022-01-31' - }, - { - id: 2, - name: '2024年寻驾okr', - startDate: '2022-02-01', - endDate: '2022-02-28' +function handleSearchPeroid() { + getOkrRelationTree().then((resp) => { + peroidList.value = resp + if (resp && resp.length && !searchForm.value.nodeId) { + searchForm.value.nodeId = resp[0].nodeId + searchForm.value.nodeName = resp[0].nodeName + getOkrList() } - ] + }) +} + +function getOkrList() { + getOkrRelationTreeChildren({ + nodeId: searchForm.value.nodeId + }).then((resp) => { + const tree = listToTree(resp, { + id: 'nodeId', + pid: 'parentId', + children: 'children' + }) + helpDataList.value = resp + if (tree && tree.length) { + dataList.value = tree[0] + } else { + dataList.value = {} + } + }) } function handleSelectPeroid(row) { - searchForm.value.peroidName = row.name - searchForm.value.peroidId = row.id - handleSearchOkr() + searchForm.value.nodeName = row.nodeName + searchForm.value.nodeId = row.nodeId + getOkrList() } -function handleSearchOkr() { - console.log(searchForm.value) +function getNodePropData(nodeId, prop) { + const nodeData = helpDataList.value.find((it) => it.nodeId == nodeId) + if (nodeData) { + return nodeData[prop] + } else { + return '' + } } function toggleExpand(data, val) { @@ -177,19 +168,23 @@ function toggleExpand(data, val) { toggleExpand(dataList.value, true) const dialogOkr = ref(null) -const okrId = ref(null) +const clickNode = ref(null) function handleClickNode(node, data) { - okrId.value = data.id + clickNode.value = data openOkr() } function openOkr() { - okrId.value && dialogOkr.value.open(okrId.value) + clickNode.value && + dialogOkr.value.open({ + nodeId: clickNode.value.nodeId, + canEdit: !clickNode.value.children || clickNode.value.children.length == 0 + }) } const dialogOkrInfo = ref(null) function handleAddNode() { - okrId.value = null + clickNode.value = null dialogOkrInfo.value.open('create', null) } diff --git a/src/views/OKR/Management/Components/OkrTable.vue b/src/views/OKR/Management/Components/OkrTable.vue index 27f741c..202ed1a 100644 --- a/src/views/OKR/Management/Components/OkrTable.vue +++ b/src/views/OKR/Management/Components/OkrTable.vue @@ -50,7 +50,7 @@ </el-table-column> <el-table-column prop="progress" label="进度" width="200px"> <template #default="{ row }"> - <el-progress :percentage="row.progress || 0" /> + <el-progress :percentage="parseInt(row.progress) || 0" /> </template> </el-table-column> <el-table-column prop="executorName" label="执行人" width="200px" />