xiongchengqiang 377f38cc7b 优化
2020-12-07 15:39:52 +08:00

456 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- -->
<template>
<div class="goals">
<SmallNav />
<div class="goals-content boderAndRadius">
<div class="goals-content-name">
<InfoHeader :obj="{
src:obj.avatar,
name:obj.staffName,
departmentName:obj.departmentName
}" />
</div>
<div class="goals-content-tabbar">
<el-tabs :value="activeId">
<el-tab-pane v-for="(i,index) in obj.recortModelDtos"
:key="i.id"
:label="i.name + ' ( '+( i.maxCount===null?(handleNumber(i)):(handleNumber(i)+'/'+i.maxCount))+' ) '"
:name="String(i.id)">
<div class="goals-content-tabbar-table">
<div class="goals-content-tabbar-table-header commonFont">
<span style="width:30%">指标名称</span>
<span class="kaohe"
style="width:30%">考核标准</span>
<span style="width:30%">权重</span>
<span style="width:10%">操作</span>
</div>
<div style="justify-content:center;"
v-if="handleFilter(i.detailDtos).length===0"
class="goals-content-tabbar-table-content commonFont items">
暂无指标
</div>
<draggable v-model="i.tagetLibItems"
:options='options1'>
<div class="goals-content-tabbar-table-content commonFont items"
v-for="(j,indexJ) in handleFilter(i.detailDtos)"
:key="indexJ">
<div style="width:30%"
class="my-handle"><img style="width:20px;height:20px;"
src="@/assets/img/yidong.png"
alt="">{{j.target}}</div>
<div style="width:30%"
class="kaohe">
<pre>{{j.keyResult}}</pre>
</div>
<div style="width:30%">{{ Math.round((j.checkWeight * 100)*1000)/1000}}%</div>
<div style="width:10%">
<el-button @click="hanidleEdit(j,indexJ,index)"
type="text"
size="small">
编辑
</el-button>
<el-button @click="handleDelateWeidu(j,indexJ,index)"
type="text"
size="small">
删除
</el-button>
</div>
</div>
</draggable>
<div style=" padding: 10px;font-size:16px;"
class="commonFont">
<div>
业务指标权重:{{handleGetWeight(i)}}% <span v-if="i.weight !== null">/{{Math.round((i.weight * 100)*1000)/1000}}%</span>
</div>
<div>
所有指标总权重: {{ handleGetWeight1()}}%
</div>
</div>
<div style=" padding: 10px;">
<!-- <el-button size="mini" plain>选择指标项</el-button> -->
<el-button @click="hanidleEdit(i,-1,index)"
type="primary"
icon="el-icon-plus"
size="small"
plain>增加指标项</el-button>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
<popup-right v-if="showIndicators"
@cancel='handleCancelZhibiao'
@submit="handleSubmitZhibiao"
:title="zhibiaoTitle">
<div slot="content"
class="weiduManage">
<el-form label-position="left"
ref="formIndicators"
:model="formIndicators"
:rules="ruleIndicators"
label-width="180px">
<el-form-item label="指标类型">
<el-select v-model="formIndicators.type"
disabled
placeholder="请选择维度类型">
<el-option v-for="i in dimensionsList"
:key="i.id"
:label="i.name"
:value="i.id"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="target"
label='指标名称'>
<el-input clearable
size="small"
v-model="formIndicators.target"></el-input>
</el-form-item>
<el-form-item label="考核标准"
prop="keyResult">
<el-input size="small"
clearable
:rows="24"
type="textarea"
v-model="formIndicators.keyResult"></el-input>
</el-form-item>
<el-form-item label="权重"
prop="weight">
<el-input size="small"
@blur="$handleBlur('formIndicators.checkWeight')"
@input.native="$handleInputInt('formIndicators.checkWeight')"
v-model="formIndicators.checkWeight">
<template slot="append">%</template>
</el-input>
</el-form-item>
</el-form>
</div>
</popup-right>
<div class="goals-bottom">
<div class="goals-bottom-content">
<el-button size='small'
@click="handleSaveDetail()"
plain>暂存</el-button>
<el-button size='small'
type="primary"
@click="handleGetNext">提交</el-button>
</div>
</div>
</div>
</template>
<script>
import SmallNav from '@/components/kpi-layout/SmallNav'
import InfoHeader from '@/components/InfoHeader'
import PopupRight from '@/components/PopupRight'
import draggable from 'vuedraggable'
import { getDimensions } from '@/api/data'
import { apiResultGetDetail, apiSaveDetail, apiSaveapproval } from '@/api/assessment'
export default {
data () {
return {
zhibiaoTitle: '添加指标',
showIndicators: false,
dimensionsList: [],
formIndicators: {},
ruleIndicators: {
target: [{
required: true,
message: '请输入指标名称',
trigger: 'blur'
}
],
keyResult: [{
required: true,
message: '请输入考核标准',
trigger: 'blur'
}
],
checkWeight: [{
required: true,
message: '请输入权重大小',
trigger: 'blur'
}
]
},
activeId: null,
obj: {
recortModelDto: []
},
options1: {
group: 'names',
draggable: '.items',
handle: '.my-handle',
scroll: true,
sort: true, // 内部排序列表
delay: 0, // 以毫秒为单位定义排序何时开始。
touchStartThreshold: 0, // px,在取消延迟拖动事件之前,点应该移动多少像素?
disabled: false, // 如果设置为真则禁用sortable。
store: null, // @see Store
animation: 150 // ms, 动画速度运动项目排序时,' 0 ' -没有动画。
}
}
},
components: {
SmallNav,
InfoHeader,
draggable,
PopupRight
},
computed: {},
beforeMount () { },
mounted () {
this.handleGetDimensions()
this.handleGetTbale()
},
methods: {
handleNumber (item) {
return item.detailDtos ? item.detailDtos.filter(i => !i.isDelete).length : 0
},
async handleGetNext () {
const arr = this.handleFilter(this.obj.recortModelDtos)
if (arr.some(i => i.weight === null)) {
let weight = 0
let maxWeight = 0
const nullArray = arr.map(i => {
i.detailDtos.map(j => {
if (i.weight === null) maxWeight += j.checkWeight
weight += j.checkWeight
})
})
if (weight !== 1) {
const noWeightArr = arr.filter(i => i.weight === null)
let str = noWeightArr.map(i => i.name).join(',')
this.$message.error(str + '维度内的权重和必须为100%')
return
}
} else {
for (let i in arr) {
if (arr[i].detailDtos.length > 0 && !arr[i].isTrue) {
this.$message.error(arr[i].name + '维度内的权重和必须为' + Math.round((arr[i].weight * 100) * 1000) / 1000)
return
}
}
}
const obj = { status: 1, menuName: '制定了' }
const params = Object.assign({}, { resultRecordId: this.$route.query.id || '' }, obj)
let res = await apiSaveapproval(params)
console.log("🚀 ~ file: index.vue ~ line 238 ~ handleGetNext ~ res", res)
if (res.code !== 200) {
this.$message.error(res.msg || '出错了 ')
return
}
this.obj.commentId = res.commentId
let res1 = await apiSaveDetail(this.obj)
if (res1.code !== 200) {
this.$message.error(res1.msg)
return
}
this.$message({
message: res.msg,
type: 'success'
})
// history.go(-1)
},
handleGetWeight1 () {
let num = 0
this.obj.recortModelDtos.map(i => {
i.detailDtos.filter(i => !i.isDelete).map(i => {
num += i.checkWeight
})
})
return Math.round((num * 100) * 1000) / 1000
},
handleGetWeight (arr) {
const weight = arr.detailDtos.filter(i => !i.isDelete).reduce((num, i) => {
num += i.isDelete !== 1 ? i.checkWeight : 0
return num
}, 0)
arr.isTrue = (Math.round((weight * 100) * 1000) / 1000) === (Math.round((arr.weight * 100) * 1000) / 1000)
return Math.round((weight * 100) * 1000) / 1000
},
async handleSaveDetail (params = this.obj) {
let res = await apiSaveDetail(params)
if (res.code !== 200) {
this.$message.error(res.msg)
return
}
this.$message({
message: res.msg,
type: 'success'
})
this.handleGetTbale()
},
// 获取维度类型
async handleGetDimensions () {
try {
let res = await getDimensions()
if (res.code !== 200) {
this.dimensionsList = []
return
}
res = res.data
this.dimensionsList = res
} catch (error) {
this.$message.error(error.msg)
}
},
handleCancelZhibiao () {
this.showIndicators = false
},
handleSubmitZhibiao () {
this.$refs.formIndicators.validate((v) => {
if (v) {
if (this.formIndicators.index === -1) {
this.obj.recortModelDtos[this.formIndicators.dazhibiaoIndex].detailDtos.push(Object.assign({}, this.formIndicators, { checkWeight: this.formIndicators.checkWeight / 100 }))
} else {
this.obj.recortModelDtos[this.formIndicators.dazhibiaoIndex].detailDtos[this.formIndicators.index] = Object.assign({}, this.formIndicators, { checkWeight: this.formIndicators.checkWeight / 100 })
}
this.showIndicators = false
}
})
},
// 编辑
hanidleEdit (item, index, type) {
if (item.maxCount !== null) {
const len = this.handleNumber(item)
if (item.maxCount <= len) {
this.$message.info('指标数量不能大于' + item.maxCount)
return
}
}
if (index === -1) {
this.formIndicators = {
checkWeight: 0
}
} else {
this.formIndicators = Object.assign({}, item)
this.formIndicators.checkWeight = this.formIndicators.checkWeight * 100
}
this.formIndicators.dazhibiaoIndex = type
this.formIndicators.index = index
this.formIndicators.type = item.type
this.showIndicators = true
},
handleDelateWeidu (item, index, type) {
if (item.id) {
item.isDelete = 1
this.$forceUpdate()
return
}
this.obj.recortModelDtos[type].detailDtos = this.obj.recortModelDtos[type].detailDtos.filter(i => i !== item)
this.$forceUpdate()
},
handleFilter (item) {
return item ? item.filter(i => !i.isDelete) : []
},
async handleGetTbale (id = this.$route.query.id) {
let res = await apiResultGetDetail({ id })
if (res.code !== 200) return
this.obj = res.data
this.activeId = String(res.data.recortModelDtos[0].id)
}
},
watch: {}
}
</script>
<style lang='less' scoped>
.goals {
.kaohe {
flex: none;
width: 500px;
display: block;
pre {
white-space: pre-wrap;
word-wrap: break-word;
word-break: break-all;
}
}
margin-bottom: 100px;
position: relative;
.my-handle {
cursor: move;
display: flex;
align-items: center;
img {
margin-right: 10px;
}
}
&-bottom {
position: fixed;
height: 60px;
border-top: 1px solid @borderColor;
padding: 0 80px;
width: 100%;
background: #fff;
bottom: 0;
left: 0;
&-content {
padding: 0 80px;
margin: 0 auto;
height: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
}
}
&-content {
padding: 28px;
&-name {
display: flex;
align-items: center;
justify-content: space-between;
}
&-title {
margin: 0 0 10px 0;
display: flex;
align-items: center;
&-img {
width: 40px;
height: 40px;
border-radius: 50%;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
&-right {
margin-left: 20px;
display: flex;
flex-direction: column;
}
}
&-tabbar {
&-table {
&-header {
display: flex;
justify-content: space-between;
align-items: center;
height: 60px;
background: rgb(231, 231, 231);
border-bottom: 1px solid @borderColor;
span {
padding: 0 0 0 20px;
}
}
&-content {
display: flex;
padding: 20px 0;
// align-items: center;
// height: 60px;
border-bottom: 1px solid @borderColor;
justify-content: space-between;
div {
padding: 0 0 0 20px;
}
}
}
}
}
}
</style>