682 lines
19 KiB
Vue
682 lines
19 KiB
Vue
<template>
|
||
<div class='table'>
|
||
<div v-if="obj.recortModelDtos.length !== 0"
|
||
class="table-list commonFont">
|
||
<div class="table-header">
|
||
<div class="title table-left weidu">维度</div>
|
||
<div class="title table-header-flex name">名称</div>
|
||
<div class="title table-header-flex jindu">进度</div>
|
||
<div class="title table-header-flex kaohe">考核标准</div>
|
||
<div class="title table-header-flex jieguo"
|
||
v-if="tableInfo.result || tableAuth.showResult">结果值</div>
|
||
<div class="title table-header-flex quanzhong">权重({{Math.round((obj.weight * 100)*1000)/1000}}%)</div>
|
||
<template v-if="obj.recortModelDtos.length>0 && obj.recortModelDtos[0].detailDtos && obj.recortModelDtos[0].detailDtos.length>0">
|
||
<!-- v-if="tableAuth.editScore" -->
|
||
<div class="title table-header-flex pingfen"
|
||
v-for="(k,index1) in handleGetScorlList(obj.recortModelDtos[0].detailDtos[0].scoreDtos)"
|
||
:key="index1">
|
||
<div class="pingfen-title">上级评分 - {{k.approvalName}} ( {{( Math.round((k.weight * 100) * 1000) / 1000 )}}%)</div>
|
||
<div class="pingfen-content">
|
||
<div class="pingfen-content-ping">评分</div>
|
||
<div class="pingfen-content-defen">得分</div>
|
||
<div class=" pingfen-content-shuoming">评分说明</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
<div class="table-weidu"
|
||
v-for="(item,index) in ((tableInfo.score || tableAuth.showScore)?obj.recortModelDtos:obj.recortModelDtos.slice(0,obj.recortModelDtos.length-1))"
|
||
:key="index">
|
||
<!-- ((tableInfo.score || tableAuth.showScore) && tableAuth.editScore?obj.recortModelDtos:obj.recortModelDtos.slice(0,obj.recortModelDtos.length-1)) -->
|
||
<div class="weidu">
|
||
<div v-for="(name,indexname) in item.name"
|
||
:key="indexname">
|
||
{{name}}
|
||
</div>
|
||
</div>
|
||
<div style="flex: 1 1 auto;"
|
||
class="table-right">
|
||
<div class="table-content"
|
||
v-for="(i,index2) in item.detailDtos"
|
||
:key="index2">
|
||
<div class="name"
|
||
v-html="i.target">
|
||
</div>
|
||
<div class="jindu">
|
||
<el-progress type="circle"
|
||
:width='50'
|
||
:stroke-width='4'
|
||
:percentage="Math.round((i.processRate * 100) * 1000) / 1000 "></el-progress>
|
||
<el-button type="text"
|
||
@click="handleLookProcess(i)"
|
||
size="mini">
|
||
查看任务
|
||
</el-button>
|
||
</div>
|
||
<div class="kaohe pre">
|
||
<pre>
|
||
{{i.keyResult}}
|
||
</pre>
|
||
</div>
|
||
<div class="jieguo pre"
|
||
v-if="tableInfo.result || tableAuth.showResult">
|
||
<el-input v-if="tableInfo.result"
|
||
type="textarea"
|
||
:rows="12"
|
||
size="mini"
|
||
placeholder="请输入内容"
|
||
v-model="i.checkResult"
|
||
clearable></el-input>
|
||
<pre v-else>{{i.checkResult || '--'}}</pre>
|
||
</div>
|
||
<div class="quanzhong">
|
||
{{( Math.round((i.checkWeight * 100) * 1000) / 1000 )}}%
|
||
</div>
|
||
<template>
|
||
<div v-for="(dto,index3) in handleGetScorlList(i.scoreDtos)"
|
||
:key="index3"
|
||
class="pingfen table-content-pingfen">
|
||
<div class="pingfen-content-ping">
|
||
<el-select v-if="tableInfo.score && obj.gradeGroupId===1 && dto.approvalId ===userInfo.userId"
|
||
style="width:115px;"
|
||
size="mini"
|
||
v-model="dto.acquireScore">
|
||
<el-option v-for="item in scoreList"
|
||
:key="item.id"
|
||
:label="item.name"
|
||
:value="item.score">
|
||
</el-option>
|
||
</el-select>
|
||
<el-input v-if="tableInfo.score && obj.gradeGroupId===2 && dto.approvalId ===userInfo.userId"
|
||
style="width:115px;"
|
||
size="mini"
|
||
placeholder="请输入评分值"
|
||
v-model="dto.acquireScore"
|
||
clearable></el-input>
|
||
<span v-if="!tableInfo.score || dto.approvalId !== userInfo.userId">{{handleScore(dto.acquireScore)}}</span>
|
||
</div>
|
||
<div class="pingfen-content-defen">
|
||
{{dto.acquireScore}}
|
||
</div>
|
||
<div class="pingfen-content-shuoming">
|
||
<el-input v-if="tableInfo.score && dto.approvalId ===userInfo.userId"
|
||
style="width:200px;"
|
||
:rows="4"
|
||
size="mini"
|
||
type="textarea"
|
||
placeholder="请输入内容"
|
||
v-model="dto.scoreComment"
|
||
clearable></el-input>
|
||
<span v-else>{{dto.scoreComment || '--'}}</span>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
</div>
|
||
<div class="table-content"
|
||
v-if="item.detailDtos.length===0">
|
||
<div class="name">
|
||
--
|
||
</div>
|
||
<div class="jindu">
|
||
暂无进度
|
||
</div>
|
||
<div class="kaohe">
|
||
--
|
||
</div>
|
||
<div class="jieguo"
|
||
v-if="tableInfo.result || tableAuth.showResult">
|
||
--
|
||
</div>
|
||
<div class="quanzhong">
|
||
--
|
||
</div>
|
||
<template>
|
||
<div v-for="(k,index4) in (scoreListForParams)"
|
||
:key="index4"
|
||
class="pingfen table-content-pingfen">
|
||
<div class="pingfen-content-ping">
|
||
{{k.Level}}
|
||
</div>
|
||
<div class="pingfen-content-defen">
|
||
{{k.Score}}
|
||
</div>
|
||
<div class="pingfen-content-shuoming">
|
||
--
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div v-else
|
||
class='nojixiao'>
|
||
<img src="./imgs/nojixiao.png"
|
||
alt="">
|
||
<div class="commonFont">
|
||
未制定绩效目标,暂无数据
|
||
</div>
|
||
</div>
|
||
<div v-if="tableInfo.result || tableInfo.score"
|
||
class="table-bottom">
|
||
<div class="table-bottom-content">
|
||
<el-button size='small'
|
||
@click="handleCancelResult"
|
||
plain>取消</el-button>
|
||
<el-button size='small'
|
||
:loading='loadingZan'
|
||
@click="handleSaveDetail()"
|
||
plain>暂存</el-button>
|
||
<el-button size='small'
|
||
:loading='loadingTi'
|
||
@click="handleGetNext"
|
||
type="primary">{{tableInfo.result?'提交结果值':'提交评分'}}</el-button>
|
||
</div>
|
||
</div>
|
||
<div v-if="scoreListForParams.length>0"
|
||
class="commonFont"
|
||
style="font-size:12px;margin:10px 0;">{{handleGetAllScore(scoreListForParams)}}</div>
|
||
<process v-if="!_.isEmpty(taskInfo)"
|
||
:taskObj='taskInfo'
|
||
:drawer.sync='drawer' />
|
||
</div>
|
||
</template>
|
||
<script>
|
||
import { apiSaveDetail, apiGet375, apiSaveapproval, apiTaskDetail } from '@/api/assessment'
|
||
import process from './process.vue'
|
||
import { mapGetters } from 'vuex'
|
||
|
||
export default {
|
||
name: 'columnsTbale',
|
||
props: {
|
||
obj: {
|
||
type: Object,
|
||
default: () => {
|
||
return {
|
||
recortModelDtos: []
|
||
}
|
||
}
|
||
},
|
||
tableInfo: {
|
||
type: Object,
|
||
default: () => {
|
||
return {
|
||
result: false,
|
||
score: false
|
||
}
|
||
}
|
||
},
|
||
tableAuth: {
|
||
type: Object,
|
||
default: () => {
|
||
return {}
|
||
}
|
||
}
|
||
},
|
||
data () {
|
||
return {
|
||
drawer: false,
|
||
loadingTi: false,
|
||
loadingZan: false,
|
||
input: '',
|
||
scoreList: [],
|
||
taskInfo: {}
|
||
// score: {
|
||
// lastScore: '',
|
||
// scoreLevel: ''
|
||
// }
|
||
}
|
||
},
|
||
components: {
|
||
process
|
||
},
|
||
computed: {
|
||
...mapGetters(['userInfo']),
|
||
scoreListForParams () {
|
||
if (this.obj.recortModelDtos.length > 0 && this.obj.recortModelDtos[0].detailDtos && this.obj.recortModelDtos[0].detailDtos.length > 0) {
|
||
return this.handleGetScorlList(this.obj.recortModelDtos[0].detailDtos[0].scoreDtos).map((item, index) => {
|
||
let result = 0
|
||
this.obj.recortModelDtos.map(j => {
|
||
j.detailDtos.map((k, index2) => {
|
||
let str = k.scoreDtos[index].calculate.replace(/{\w+}/g, (l) => {
|
||
l = l.replace(/{|}/g, '')
|
||
return k.scoreDtos[index][l] || 0
|
||
})
|
||
// eslint-disable-next-line no-eval
|
||
result += (k.scoreDtos[index].score || eval(str))
|
||
!k.scoreDtos[index].score && (k.scoreDtos[index].score = result)
|
||
})
|
||
})
|
||
const arr = this.scoreList.filter(i => i.minScore <= result && i.maxScore > result)
|
||
return {
|
||
Score: result.toFixed(3),
|
||
Level: arr.length > 0 ? arr[0].name : ''
|
||
}
|
||
})
|
||
} else {
|
||
return []
|
||
}
|
||
},
|
||
score () {
|
||
const result = this.obj.recortModelDtos.reduce((result, i) => {
|
||
i.detailDtos.map(j => {
|
||
j.scoreDtos.map(k => {
|
||
const str = j.calculate.replace(/{\w+}/g, (i) => {
|
||
i = i.replace(/{|}/g, '')
|
||
return k[i]
|
||
})
|
||
// eslint-disable-next-line no-eval
|
||
let a = eval(str)
|
||
result += a
|
||
})
|
||
})
|
||
return result
|
||
}, 0)
|
||
const arr = this.scoreList.filter(i => i.minScore <= result && i.maxScore > result)
|
||
return {
|
||
lastScore: result.toFixed(3),
|
||
scoreLevel: arr.length > 0 ? arr[0].name : ''
|
||
}
|
||
}
|
||
},
|
||
mounted () {
|
||
this.handleGrt375()
|
||
},
|
||
methods: {
|
||
// 获取指标任务详情
|
||
async handleGetTaskDetail (id = '') {
|
||
let res = await apiTaskDetail({ detailId: id })
|
||
if (res.code !== 200) {
|
||
this.$message.error(res.msg)
|
||
return false
|
||
}
|
||
return Object.assign({}, res.data, { detailId: id })
|
||
},
|
||
async handleLookProcess (item) {
|
||
console.log(item)
|
||
this.taskInfo = {}
|
||
let result = await this.handleGetTaskDetail(item.id)
|
||
if (!result) return
|
||
this.taskInfo = result
|
||
this.$nextTick(() => {
|
||
this.drawer = true
|
||
})
|
||
},
|
||
handleGetAllScore (arr) {
|
||
const result = arr.reduce((result, item) => {
|
||
result += Number(item.Score)
|
||
return result
|
||
}, 0)
|
||
return '总分:' + (this.scoreList.filter(i => i.minScore <= result && i.maxScore > result).length > 0 ? this.scoreList.filter(i => i.minScore <= result && i.maxScore > result)[0].name : '--')
|
||
},
|
||
handleGetScorlList (list) {
|
||
console.log('list: ', list)
|
||
console.log('userInfo: ', this.userInfo.userId)
|
||
return list.filter(i => i.acquireScore !== null || (i.approvalId === this.userInfo.userId && this.tableInfo.score))
|
||
},
|
||
handleScore (item) {
|
||
return this.scoreList.filter(i => i.score === item).length > 0 ? this.scoreList.filter(i => i.score === item)[0].name : 0
|
||
},
|
||
async handleGetNext () {
|
||
this.loadingTi = true
|
||
let res1 = await apiSaveDetail(Object.assign({}, this.obj, this.score))
|
||
if (res1.code !== 200) {
|
||
this.$message.error(res1.msg)
|
||
this.loadingTi = false
|
||
return
|
||
}
|
||
const obj = { status: 1, menuName: this.tableInfo.result ? '提交了结果值' : '提交了评分' }
|
||
const params = Object.assign({}, { resultRecordId: this.$route.query.id || '' }, obj)
|
||
let res = await apiSaveapproval(params)
|
||
this.loadingTi = false
|
||
if (res.code !== 200) {
|
||
this.$message.error(res.msg)
|
||
return
|
||
}
|
||
this.$message({
|
||
message: res.msg,
|
||
type: 'success'
|
||
})
|
||
history.go(0)
|
||
},
|
||
handleCancelResult () {
|
||
this.$emit('update:tableInfo', Object.assign({}, this.tableInfo, { result: false, score: false }))
|
||
},
|
||
handleGetTable (type) {
|
||
this.$parent.handleGetTbale({ id: this.$route.query.id || '' }, type)
|
||
},
|
||
async handleGrt375 () {
|
||
let res = await apiGet375()
|
||
if (res.code !== 200) return
|
||
this.scoreList = res.data
|
||
},
|
||
async handleSaveDetail (params = Object.assign({}, this.obj, this.score)) {
|
||
this.loadingZan = true
|
||
let res = await apiSaveDetail(params)
|
||
this.loadingZan = false
|
||
if (res.code !== 200) {
|
||
this.$message.error(res.msg)
|
||
return
|
||
}
|
||
this.$message({
|
||
message: res.msg,
|
||
type: 'success'
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
<style lang='less' scoped>
|
||
.title {
|
||
background: #f5f5f5;
|
||
border-bottom: 1px solid @borderColor;
|
||
}
|
||
.jieguo {
|
||
padding: 10px !important;
|
||
width: 260px !important;
|
||
.center();
|
||
}
|
||
.name {
|
||
padding: 10px !important;
|
||
width: 200px;
|
||
.center();
|
||
}
|
||
.jindu {
|
||
width: 60px;
|
||
.center();
|
||
flex-direction: column;
|
||
}
|
||
.kaohe {
|
||
width: 300px;
|
||
flex: 1 1 auto;
|
||
padding: 10px !important;
|
||
display: block;
|
||
.center();
|
||
pre {
|
||
white-space: pre-line;
|
||
word-wrap: break-word;
|
||
word-break: break-all;
|
||
}
|
||
}
|
||
.weidu {
|
||
flex: none;
|
||
width: 60px;
|
||
.center();
|
||
flex-direction: column;
|
||
padding: 10px !important;
|
||
border-left: 1px solid @borderColor;
|
||
border-right: 1px solid @borderColor;
|
||
border-bottom: 1px solid @borderColor;
|
||
> div {
|
||
text-align: center;
|
||
}
|
||
// .center();
|
||
}
|
||
.quanzhong {
|
||
width: 86px !important;
|
||
.center();
|
||
}
|
||
.pingfen {
|
||
display: flex;
|
||
padding: 0 !important;
|
||
border-right: 1px solid @borderColor !important;
|
||
flex-direction: column;
|
||
&-title {
|
||
padding: 10px 0 !important;
|
||
text-align: center;
|
||
border-bottom: 1px solid @borderColor;
|
||
}
|
||
&-content {
|
||
flex: 1;
|
||
align-items: center;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
> div {
|
||
border-right: 1px solid @borderColor;
|
||
padding: 10px 0 !important;
|
||
.center();
|
||
}
|
||
&-ping {
|
||
width: 120px;
|
||
height: 100%;
|
||
}
|
||
&-defen {
|
||
width: 50px !important;
|
||
height: 100%;
|
||
}
|
||
&-shuoming {
|
||
width: 120px;
|
||
padding: 10px;
|
||
border-right: none !important;
|
||
flex: 1;
|
||
}
|
||
}
|
||
}
|
||
.defen {
|
||
width: 50px;
|
||
}
|
||
.shuoming {
|
||
width: 200px;
|
||
}
|
||
|
||
.nojixiao {
|
||
text-align: center;
|
||
}
|
||
.listNone {
|
||
height: 100px;
|
||
text-align: center;
|
||
line-height: 100px;
|
||
border-bottom: 1px solid @borderColor;
|
||
}
|
||
.table-list {
|
||
padding: 0 0 10px 0;
|
||
// border: 1px solid @borderColor;
|
||
// border-bottom: none;
|
||
overflow: auto;
|
||
}
|
||
.table-weidu {
|
||
display: flex;
|
||
font-size: 12px;
|
||
}
|
||
.table-header {
|
||
display: flex;
|
||
font-size: 12px;
|
||
flex-shrink: 0;
|
||
// justify-content: space-between;
|
||
// border: 1px solid @borderColor;
|
||
> div {
|
||
padding: 10px;
|
||
border-right: 1px solid @borderColor;
|
||
border-top: 1px solid @borderColor;
|
||
}
|
||
> div:last-child {
|
||
border-right: none;
|
||
}
|
||
&-flex {
|
||
flex-shrink: 0;
|
||
// flex: 1;
|
||
// .center();
|
||
}
|
||
}
|
||
// .table-content{
|
||
// display: flex;
|
||
// justify-content: space-between;
|
||
// >div{
|
||
// padding: 10px;
|
||
// border-right: 1px solid @borderColor;
|
||
// }
|
||
// >div:last-child{
|
||
// border-right: none;
|
||
// padding: 0px;
|
||
// }
|
||
// &-left{
|
||
// border-bottom: 1px solid @borderColor;
|
||
// display: flex;
|
||
// flex-direction: column;
|
||
// align-items: center;
|
||
// justify-content: center;
|
||
// >div{
|
||
// .center();
|
||
// }
|
||
// }
|
||
// &-right{
|
||
// flex:1;
|
||
// display: flex;
|
||
// flex-direction: column;
|
||
// // justify-content: space-between;
|
||
// // align-items: center;
|
||
// >div{
|
||
// flex: 1;
|
||
// border-bottom: 1px solid @borderColor;;
|
||
// }
|
||
// >div:last-child{
|
||
// // border-bottom: none;
|
||
// }
|
||
// &-item:hover{
|
||
// background: #f5f5f5;
|
||
// }
|
||
// &-item{
|
||
|
||
// >div{
|
||
// border-right: 1px solid @borderColor;
|
||
// padding: 10px;
|
||
// }
|
||
// >div:last-child{
|
||
// border-right: none;
|
||
// }
|
||
// // flex: 1;
|
||
// display: flex;
|
||
// >div{
|
||
// flex: 1;
|
||
// // .center();
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
.table-left {
|
||
width: 60px;
|
||
text-align: center;
|
||
}
|
||
.quanzhomng {
|
||
width: 100px !important;
|
||
text-align: center;
|
||
}
|
||
.table-content:hover {
|
||
background: rgb(247, 247, 247);
|
||
}
|
||
.table-right {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
.table-content {
|
||
flex: 1 1 auto;
|
||
display: flex;
|
||
> div {
|
||
border-right: 1px solid @borderColor;
|
||
border-bottom: 1px solid @borderColor;
|
||
padding: 10px 0;
|
||
}
|
||
&-pingfen {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
> div {
|
||
text-align: center;
|
||
border-right: 1px solid @borderColor;
|
||
.center();
|
||
}
|
||
}
|
||
}
|
||
.table {
|
||
position: relative;
|
||
&-bottoms {
|
||
width: 100%;
|
||
height: 60px;
|
||
z-index: 1000000;
|
||
bottom: 0;
|
||
left: 0;
|
||
background: transparent;
|
||
position: fixed;
|
||
display: flex;
|
||
// align-items: center;
|
||
justify-content: center;
|
||
&-contenct {
|
||
height: 40px;
|
||
display: flex;
|
||
background: #fff;
|
||
justify-content: space-between;
|
||
border-radius: 40px;
|
||
box-shadow: 0 1px 6px 0 rgba(0, 0, 0, 0.12),
|
||
0 1px 6px 0 rgba(0, 0, 0, 0.12);
|
||
&-left {
|
||
line-height: 40px;
|
||
font-size: 14px;
|
||
padding: 0 16px;
|
||
i {
|
||
margin: 0 6px;
|
||
font-weight: 800;
|
||
}
|
||
cursor: pointer;
|
||
color: @fontBlue;
|
||
}
|
||
&-center {
|
||
.center();
|
||
font-size: 14px;
|
||
padding: 0 10px;
|
||
}
|
||
&-right {
|
||
line-height: 40px;
|
||
font-size: 14px;
|
||
padding: 0 16px;
|
||
i {
|
||
margin: 0 6px;
|
||
font-weight: 800;
|
||
}
|
||
cursor: pointer;
|
||
color: @fontBlue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.table-bottom {
|
||
height: 60px;
|
||
position: fixed;
|
||
padding: 0 80px;
|
||
width: 100%;
|
||
background: #fff;
|
||
border-top: 1px solid @borderColor;
|
||
bottom: 0;
|
||
left: 0;
|
||
&-content {
|
||
width: 1360px;
|
||
margin: 0 auto;
|
||
height: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
}
|
||
}
|
||
table {
|
||
margin-top: 15px;
|
||
width: 100%;
|
||
border: 1px solid #e9eaec;
|
||
border-collapse: collapse;
|
||
}
|
||
th {
|
||
background-color: #f8f8f9;
|
||
}
|
||
th,
|
||
td {
|
||
padding: 5px;
|
||
border: 1px solid #e9eaec;
|
||
text-align: center;
|
||
vertical-align: top;
|
||
line-height: 30px;
|
||
}
|
||
td {
|
||
}
|
||
</style>
|