Merge branch 'main' of http://114.215.207.150:3000/qiushanhe/ss-oa-manage-web into dev-cl
commit
b05e42f9c7
@ -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 |
@ -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 |
||||
} |
@ -0,0 +1,177 @@ |
||||
<template> |
||||
<div> |
||||
<el-row class="mb-10px"> |
||||
<el-tree-select |
||||
v-model="searchForm.nodeId" |
||||
:data="peroidList" |
||||
:props="defaultProps" |
||||
:render-after-expand="false" |
||||
:default-expand-all="false" |
||||
check-strictly |
||||
style="width: 400px" |
||||
@change="nodeChange" |
||||
/> |
||||
</el-row> |
||||
|
||||
<el-table :data="originList" border :span-method="objectSpanMethod"> |
||||
<el-table-column prop="objectInfo.objectiveName" label="目标"> |
||||
<template #default="{ row }"> |
||||
{{ row.objectInfo.objectiveName }} |
||||
</template> |
||||
</el-table-column> |
||||
<!-- <el-table-column prop="objectiveId" label="占比" width="100px"> |
||||
<template #default> 0 </template> |
||||
</el-table-column> --> |
||||
<el-table-column prop="keyResultShowName" label="关键成果"> |
||||
<template #default="{ row }"> |
||||
{{ row.sourceName ? `【${row.sourceName}】` : '' }} {{ row.keyResultShowName }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="targetValue" label="目标值" width="100px" /> |
||||
<el-table-column prop="currentValue" label="当前进度" width="100px" /> |
||||
<el-table-column label="开始日期" width="120px"> |
||||
<template #default> |
||||
{{ currentNode.startTime }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="status" label="完成状态" width="100px"> |
||||
<template #default="{ row }"> |
||||
<el-tag v-if="row.currentValue >= row.targetValue" type="success">完成</el-tag> |
||||
<el-tag v-else type="danger">未完成</el-tag> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="muis" label="差值" width="100px"> |
||||
<template #default="{ row }"> |
||||
<span |
||||
:style="{ |
||||
color: row.targetValue >= row.currentValue ? 'red' : '#333', |
||||
'font-weight': row.targetValue >= row.currentValue ? 'bold' : '500' |
||||
}" |
||||
> |
||||
{{ parseInt(row.targetValue - row.currentValue) }} |
||||
</span> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="complete" label="完成度" width="200px"> |
||||
<template #default="{ row }"> |
||||
<el-progress :percentage="parseInt(row.progress)" :color="customColors" /> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="endTime" label="结束日期" width="120px"> |
||||
<template #default> |
||||
{{ currentNode.endTime }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="objectInfo.progress" label="目标完成度" width="100px" align="center"> |
||||
<template #default="{ row }"> |
||||
{{ parseInt(row.objectInfo.progress) }}% |
||||
<!-- <el-progress :percentage="parseInt(row.objectInfo.progress)" :color="customColors" /> --> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</div> |
||||
</template> |
||||
|
||||
<script setup name="Analysis"> |
||||
import { listToTree, findNode } from '@/utils/tree' |
||||
import { getAllNodeTree, getAllOkrPage } from '@/api/okr/okr' |
||||
import { cloneDeep } from 'lodash-es' |
||||
|
||||
const message = useMessage() |
||||
const defaultProps = { |
||||
value: 'nodeId', |
||||
label: 'nodeName', |
||||
children: 'children' |
||||
} |
||||
const searchForm = ref({ |
||||
nodeId: undefined |
||||
}) |
||||
|
||||
const currentNode = ref(undefined) |
||||
|
||||
const customColors = [ |
||||
{ color: 'rgb(196, 86.4, 86.4)', percentage: 20 }, |
||||
{ color: 'rgb(196, 86.4, 86.4)', percentage: 40 }, |
||||
{ color: 'rgb(237.5, 189.9, 118.5)', percentage: 60 }, |
||||
{ color: 'rgb(159.5, 206.5, 255)', percentage: 80 }, |
||||
{ color: 'rgb(179, 224.5, 156.5)', percentage: 100 } |
||||
] |
||||
|
||||
const peroidList = ref([]) |
||||
|
||||
handleSearchPeroid() |
||||
|
||||
// 当前是否是叶子节点 |
||||
// 如果不是叶子节点,则表格数据不可修改 |
||||
const isCurrentLeafNode = ref(false) |
||||
|
||||
function handleSearchPeroid() { |
||||
getAllNodeTree().then((resp) => { |
||||
if (resp.nodeId) { |
||||
peroidList.value = listToTree(resp?.tree || [], { |
||||
id: 'nodeId', |
||||
pid: 'parentId', |
||||
children: 'children' |
||||
}) |
||||
nodeChange(resp.nodeId) |
||||
currentNode.value = (resp.tree || []).find((item) => item.nodeId === resp.nodeId) |
||||
} else { |
||||
message.warning('请先创建节点数据') |
||||
} |
||||
}) |
||||
} |
||||
|
||||
function nodeChange(nodeId) { |
||||
if (nodeId) { |
||||
searchForm.value.nodeId = nodeId |
||||
getOkrList() |
||||
currentNode.value = findNode(peroidList.value, (node) => { |
||||
return node.nodeId == nodeId |
||||
}) |
||||
searchForm.value.creatorId = currentNode.value.creatorId |
||||
if (!currentNode.value.children || currentNode.value.children.length == 0) { |
||||
isCurrentLeafNode.value = true |
||||
} else { |
||||
isCurrentLeafNode.value = false |
||||
} |
||||
} |
||||
} |
||||
|
||||
const originList = ref([]) |
||||
const spanObj = ref([]) |
||||
function getOkrList() { |
||||
getAllOkrPage(searchForm.value).then((resp) => { |
||||
originList.value = [] |
||||
spanObj.value = [] |
||||
if (resp && resp.length) { |
||||
resp.map((o) => { |
||||
if (o.keyResults && o.keyResults.length) { |
||||
const arr = o.keyResults.map((k, index) => { |
||||
spanObj.value.push(index == 0 ? o.keyResults.length : 0) |
||||
const obj = cloneDeep(o) |
||||
delete obj.keyResults |
||||
return { |
||||
...k, |
||||
objectInfo: obj |
||||
} |
||||
}) |
||||
originList.value = [...originList.value, ...arr] |
||||
} |
||||
}) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
function objectSpanMethod({ column, rowIndex }) { |
||||
if (['目标', '目标完成度'].includes(column.label)) { |
||||
let _row = spanObj.value[rowIndex] |
||||
let _col = _row > 0 ? 1 : 0 |
||||
return { |
||||
rowspan: _row, |
||||
colspan: _col |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped></style> |
Loading…
Reference in new issue