634 lines
19 KiB
Vue
634 lines
19 KiB
Vue
<!-- -->
|
||
<template>
|
||
<div class="drawer commonFont">
|
||
<el-drawer title="任务详情"
|
||
:visible.sync="drawer"
|
||
direction="btt"
|
||
:before-close="handleClose">
|
||
<div class="drawer-content">
|
||
<div class="drawer-content-left">
|
||
<div class="drawer-content-left-jiaoyi">
|
||
<div class="title">
|
||
<span>交易量</span>
|
||
</div>
|
||
<div class="process">
|
||
<span>
|
||
<span>整体进度:</span>
|
||
</span>
|
||
<el-progress :percentage="handleGetProgress(taskInfo.resultTasks)"></el-progress>
|
||
</div>
|
||
</div>
|
||
<div class="drawer-content-left-title">
|
||
<div> 关键结果({{handleFilter(taskInfo.resultTasks).length}})</div>
|
||
<div>
|
||
<el-button icon="el-icon-plus"
|
||
@click="handleAddTask"
|
||
type="text">添加</el-button>
|
||
</div>
|
||
</div>
|
||
<div v-for="i in handleFilter(taskInfo.resultTasks)"
|
||
:key="i.id"
|
||
class="boderAndRadius drawer-content-left-content">
|
||
<div :style="{border:!(!i.updateProcess && i.label)?'none':''}"
|
||
class="drawer-content-left-content-top">
|
||
<div class="drawer-content-left-content-top-process">
|
||
<el-progress type="circle"
|
||
:width='50'
|
||
:stroke-width='4'
|
||
:percentage="Math.round((i.processRate * 100)*1000)/1000 "></el-progress>
|
||
<div style="margin-left:10px;">
|
||
<span v-if="!i.editProcess">{{i.name}}</span>
|
||
<el-input v-if="i.editProcess"
|
||
size="small"
|
||
placeholder="请输入内容"
|
||
v-model="form.name"
|
||
clearable>
|
||
</el-input>
|
||
</div>
|
||
</div>
|
||
<div class="right">
|
||
<div v-if="i.editProcess">
|
||
<el-button size="mini"
|
||
@click="handleEditTask(1)"
|
||
type="primary">确认</el-button>
|
||
<el-button size="mini"
|
||
@click="handleEditProcess(i,false)"
|
||
type="danger">取消</el-button>
|
||
</div>
|
||
<div v-if="!i.editProcess"
|
||
class="right-item">
|
||
<div>
|
||
<el-tooltip class="item"
|
||
effect="dark"
|
||
content="更新进度"
|
||
placement="top-start">
|
||
<i @click="handleUpdateProcess(i,true)"
|
||
class="el-icon-refresh-left"></i>
|
||
</el-tooltip>
|
||
|
||
</div>
|
||
<div class="right-item-center">
|
||
<el-tooltip class="item"
|
||
effect="dark"
|
||
content="评论"
|
||
placement="top-start">
|
||
<i @click="handleAddPinglun(i)" class="el-icon-chat-square"></i>
|
||
</el-tooltip>
|
||
</div>
|
||
<div>
|
||
<el-dropdown size="mini">
|
||
<el-tooltip class="item"
|
||
effect="dark"
|
||
content="更多"
|
||
placement="top-start">
|
||
<i class="el-icon-more"></i>
|
||
</el-tooltip>
|
||
<el-dropdown-menu slot="dropdown">
|
||
<el-dropdown-item @click.native="handleEditProcess(i,true)">编辑</el-dropdown-item>
|
||
<el-dropdown-item @click.native="handleDetele(i.id)">删除</el-dropdown-item>
|
||
</el-dropdown-menu>
|
||
</el-dropdown>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div v-if="!i.updateProcess && i.typeDesc"
|
||
class="drawer-content-left-content-center"
|
||
:class="{bg:i.showTask}">
|
||
<div class="content commonFont">
|
||
<div class="drawer-content-left-content-center-left">
|
||
<img v-if="!i.showTask"
|
||
:onerror="defaultImg"
|
||
:src='i.avatar || defaultImg'
|
||
alt="">
|
||
<span v-if="!i.showTask">{{i.staffName}}:</span>
|
||
<span class="label"
|
||
style="word-wrap:break-word;"
|
||
v-if="!i.showTask">{{i.typeDesc}}</span>
|
||
</div>
|
||
<div style="user-select:none;">
|
||
<i :class="{rate:!i.showTask}"
|
||
@click="handleShowAll(i)"
|
||
style=" cursor: pointer;color:#3ba1ff;transition: all 0.2s;"
|
||
class="el-icon-arrow-down"></i>
|
||
</div>
|
||
</div>
|
||
<pinglun v-if="i.showTask"
|
||
:pinglunList='i.taskList' />
|
||
</div>
|
||
<div v-if="i.updateProcess"
|
||
class="drawer-content-left-content-bottom">
|
||
<el-form :model="form"
|
||
:rules="formRules"
|
||
label-width="80px">
|
||
<el-form-item label="当前进度:"
|
||
prop="weight">
|
||
<!-- <el-slider
|
||
v-model="form.processRate"
|
||
:step="10">
|
||
</el-slider> -->
|
||
<el-input size="small"
|
||
@blur="$handleBlur('form.processRate')"
|
||
@input.native="$handleInputInt('form.processRate')"
|
||
v-model="form.processRate">
|
||
<template slot="append">%</template>
|
||
</el-input>
|
||
</el-form-item>
|
||
<el-form-item label="进度说明:"
|
||
prop="remake">
|
||
<el-input type="textarea"
|
||
size="small"
|
||
placeholder="请输入进度说明"
|
||
v-model="form.remake">
|
||
</el-input>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<div style="text-align: right;">
|
||
<el-button type="primary"
|
||
size="mini"
|
||
@click="handleEditTask(2)">确定</el-button>
|
||
<el-button @click="handleUpdateProcess(i,false)"
|
||
size="mini">取消</el-button>
|
||
</div>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="drawer-content-right">
|
||
<div style="padding: 0 20px;">
|
||
<el-tabs v-model="activeName"
|
||
@tab-click="handleClick">
|
||
<el-tab-pane label="评论"
|
||
name="1">
|
||
</el-tab-pane>
|
||
<el-tab-pane label="记录"
|
||
name="2"></el-tab-pane>
|
||
</el-tabs>
|
||
</div>
|
||
<div v-if="activeName==='1'"
|
||
class="drawer-content-right-item pinglun">
|
||
<div class="pinglun-top" ref="pingList">
|
||
<pinglun :pinglunList='nowPingLunList' />
|
||
|
||
</div>
|
||
<div class="pinglun-bottom">
|
||
<div v-if="pinglunForm.id" class="pinglun-bottom-content top">
|
||
<div>评论KR:「{{pinglunForm.name}}」</div>
|
||
<i @click="pinglunForm={}" class="el-icon-circle-close"> </i>
|
||
</div>
|
||
<div class="pinglun-bottom-content">
|
||
<el-input type="textarea"
|
||
clearable
|
||
ref="input"
|
||
placeholder="请输入评论内容。。。"
|
||
v-model="form.content"></el-input>
|
||
<el-button size="small"
|
||
@click="handleSendPingLun"
|
||
type="primary">发送</el-button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div v-if="activeName==='2'"
|
||
class="drawer-content-right-item jilu">
|
||
<pinglun :pinglunList='pinglunList' />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-drawer>
|
||
<el-dialog :title="title"
|
||
:visible.sync="dialogFormVisible">
|
||
<el-form :model="form"
|
||
:rules="formRules">
|
||
<el-form-item prop="name"
|
||
label='任务名称'>
|
||
<el-input clearable
|
||
size="small"
|
||
placeholder="请输入任务名称"
|
||
v-model="form.name"></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="任务进度"
|
||
prop="weight">
|
||
<el-input size="small"
|
||
@blur="$handleBlur('form.processRate')"
|
||
@input.native="$handleInputInt('form.processRate')"
|
||
v-model="form.processRate">
|
||
<template slot="append">%</template>
|
||
</el-input>
|
||
</el-form-item>
|
||
</el-form>
|
||
<div slot="footer"
|
||
class="dialog-footer">
|
||
<el-button size="small"
|
||
@click="dialogFormVisible = false">取 消</el-button>
|
||
<el-button size="small"
|
||
type="primary"
|
||
@click="handleEditTask(3)">确 定</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import InfoHeader from '@/components/InfoHeader'
|
||
import pinglun from './pinglun.vue'
|
||
|
||
import { apiDeleteTask, apiEditTask, apiChangeTaskList, apiTaskCommentList, apiAddTaskComment } from '@/api/assessment'
|
||
|
||
export default {
|
||
props: {
|
||
drawer: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
taskObj: {
|
||
type: Object,
|
||
default: () => {
|
||
return {}
|
||
}
|
||
}
|
||
},
|
||
data () {
|
||
return {
|
||
taskInfo: {},
|
||
activeName: '1',
|
||
formRules: {
|
||
name: [{
|
||
required: true,
|
||
message: '请输入任务名称',
|
||
trigger: 'blur'
|
||
}
|
||
]
|
||
},
|
||
form: {
|
||
name: '',
|
||
processRate: '0'
|
||
},
|
||
pinglunForm: {},
|
||
pinglunList: [],
|
||
nowPingLunList: [],
|
||
dialogFormVisible: false,
|
||
title: '添加任务',
|
||
defaultImg: 'this.src="' + require('@/assets/img/default.jpg') + '"'
|
||
}
|
||
},
|
||
components: { pinglun, InfoHeader },
|
||
computed: {},
|
||
beforeMount () { },
|
||
mounted () {
|
||
this.taskInfo = Object.assign({}, this.taskObj)
|
||
this.handleGetChangeTaskList()
|
||
this.handleGetPingLunList()
|
||
console.log(this.taskInfo)
|
||
},
|
||
methods: {
|
||
async handleGetPingLunList () {
|
||
const params = {
|
||
currPage: 1,
|
||
detailId: this.taskInfo.detailId,
|
||
pageSize: 2300
|
||
}
|
||
let res = await apiTaskCommentList(params)
|
||
if (res.code !== 200) {
|
||
this.$message.error(res.msg)
|
||
return
|
||
}
|
||
this.nowPingLunList = res.data.list.reverse()
|
||
this.$nextTick(() => {
|
||
const pingList = this.$refs.pingList
|
||
pingList.scrollTop = pingList.scrollHeight
|
||
})
|
||
},
|
||
// 发送评论
|
||
async handleSendPingLun (event) {
|
||
let params = {}
|
||
// debugger
|
||
if (!this.form.content) return
|
||
params.content = this.form.content
|
||
params[this.pinglunForm.id ? 'taskId' : 'detailId'] = this.pinglunForm.id ? this.pinglunForm.id : this.taskInfo.detailId
|
||
let res = await apiAddTaskComment(params)
|
||
if (res.code !== 200) {
|
||
this.$message.error(res.msg)
|
||
return
|
||
}
|
||
this.handleGetPingLunList()
|
||
this.form.content = ''
|
||
},
|
||
// 对任务添加评论
|
||
handleAddPinglun (item) {
|
||
this.pinglunForm = Object.assign({}, item)
|
||
const pingList = this.$refs.pingList
|
||
pingList.scrollTop = pingList.scrollHeight
|
||
this.$refs.input.focus()
|
||
},
|
||
// 获取当前任务的评论
|
||
async handleShowAll (i) {
|
||
if (i.showTask) {
|
||
i.showTask = false
|
||
this.$forceUpdate()
|
||
return
|
||
}
|
||
const params = {
|
||
currPage: 1,
|
||
taskId: i.id,
|
||
pageSize: 2300
|
||
}
|
||
i.taskList = []
|
||
let res = await apiChangeTaskList(params)
|
||
if (res.code !== 200) {
|
||
this.$message.error(res.msg)
|
||
return
|
||
}
|
||
i.showTask = true
|
||
i.taskList = res.data.list
|
||
this.$forceUpdate()
|
||
},
|
||
async handleGetChangeTaskList () {
|
||
const params = {
|
||
currPage: 1,
|
||
detailId: this.taskInfo.detailId,
|
||
pageSize: 2300,
|
||
useType: 0
|
||
}
|
||
this.pinglunList = []
|
||
let res = await apiChangeTaskList(params)
|
||
if (res.code !== 200) {
|
||
this.$message.error(res.msg)
|
||
return
|
||
}
|
||
this.pinglunList = res.data.list
|
||
},
|
||
async handleEditTask (type) {
|
||
const params = Object.assign({}, this.form)
|
||
if (type === 2 || type === 3) params.processRate = this.form.processRate / 100
|
||
if (type === 3) params.detailId = this.taskInfo.detailId
|
||
const res = await apiEditTask(params)
|
||
if (res.code !== 200) {
|
||
this.$message.error(res.msg)
|
||
return
|
||
}
|
||
this.form = {}
|
||
this.taskInfo = await this.$parent.handleGetTaskDetail(this.taskInfo.detailId)
|
||
this.dialogFormVisible = false
|
||
this.handleGetChangeTaskList()
|
||
this.$parent.handleGetTable(true)
|
||
this.$message({
|
||
message: res.msg,
|
||
type: 'success'
|
||
})
|
||
},
|
||
handleGetProgress (arr = []) {
|
||
const result = this.handleFilter(arr).reduce((result, item) => {
|
||
result += Number(item.processRate)
|
||
return result
|
||
}, 0)
|
||
const _process = Number(result.toFixed(2)) / this.handleFilter(arr).length || 0
|
||
return Number((_process * 100).toFixed(2))
|
||
},
|
||
async handleDetele (id) {
|
||
let res = await apiDeleteTask({ taskId: id })
|
||
if (res.code !== 200) {
|
||
this.$message.error(res.msg)
|
||
return
|
||
}
|
||
this.taskInfo = await this.$parent.handleGetTaskDetail(this.taskInfo.detailId)
|
||
this.$parent.handleGetTable(true)
|
||
this.$message({
|
||
message: res.msg,
|
||
type: 'success'
|
||
})
|
||
},
|
||
// 更新进度
|
||
handleUpdateProcess (i, type = false) {
|
||
this.taskInfo.resultTasks.map(i => {
|
||
i.updateProcess = false
|
||
i.editProcess = false
|
||
})
|
||
if (type) {
|
||
this.form = Object.assign({}, i)
|
||
this.form.taskId = this.form.id
|
||
this.form.processRate = Math.round(Number(this.form.processRate) * 100)
|
||
} else {
|
||
this.form = {}
|
||
}
|
||
i.updateProcess = type
|
||
console.log(this.form)
|
||
this.$forceUpdate()
|
||
},
|
||
// 编辑/取消编辑进度
|
||
handleEditProcess (i, type = false) {
|
||
this.taskInfo.resultTasks.map(i => {
|
||
i.updateProcess = false
|
||
i.editProcess = false
|
||
})
|
||
i.editProcess = type
|
||
this.form = Object.assign({}, i)
|
||
this.form.taskId = this.form.id
|
||
this.$forceUpdate()
|
||
},
|
||
handleFilter (item) {
|
||
return item ? item.filter(i => !i.isDelete) : []
|
||
},
|
||
handleClick (tab, event) {
|
||
console.log(tab, event)
|
||
},
|
||
handleAddTask () {
|
||
this.dialogFormVisible = true
|
||
},
|
||
handleClose () {
|
||
this.$emit('update:drawer', false)
|
||
}
|
||
},
|
||
watch: {}
|
||
|
||
}
|
||
|
||
</script>
|
||
<style lang="less">
|
||
.el-drawer {
|
||
border-radius: 12px 12px 0 0 !important;
|
||
height: 80% !important;
|
||
overflow: auto;
|
||
}
|
||
.el-drawer__header {
|
||
margin: 0;
|
||
}
|
||
.el-drawer__body {
|
||
overflow: auto;
|
||
}
|
||
.el-progress-bar {
|
||
width: 94% !important;
|
||
}
|
||
</style>
|
||
<style lang='less'>
|
||
.drawer {
|
||
&-content {
|
||
display: flex;
|
||
height: 100%;
|
||
box-sizing: border-box;
|
||
background: #fafafa;
|
||
> div {
|
||
width: 50%;
|
||
box-sizing: border-box;
|
||
overflow: auto;
|
||
}
|
||
&-left {
|
||
padding: 20px 20px 0;
|
||
.img {
|
||
width: 20px;
|
||
height: 20px;
|
||
}
|
||
border-right: 1px solid #e7e7e7;
|
||
&-jiaoyi {
|
||
.title {
|
||
font-size: 16px;
|
||
margin-bottom: 10px;
|
||
}
|
||
.process {
|
||
padding: 0 0 0 20px;
|
||
display: flex;
|
||
align-items: center;
|
||
// width: %;
|
||
.el-progress {
|
||
width: 400px;
|
||
}
|
||
}
|
||
}
|
||
&-title {
|
||
margin: 10px 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
font-size: 16px;
|
||
}
|
||
&-content {
|
||
margin-bottom: 10px;
|
||
&-top {
|
||
display: flex;
|
||
align-content: center;
|
||
justify-content: space-between;
|
||
border-bottom: 1px solid @borderColor;
|
||
margin: 20px 20px 0;
|
||
padding-bottom: 6px;
|
||
&-process {
|
||
display: flex;
|
||
align-content: center;
|
||
> div {
|
||
.center();
|
||
}
|
||
}
|
||
.right {
|
||
.center();
|
||
&-item {
|
||
cursor: pointer;
|
||
border: 1px solid @borderColor;
|
||
> div {
|
||
padding: 2px;
|
||
}
|
||
display: flex;
|
||
&-center {
|
||
border-left: 1px solid @borderColor;
|
||
border-right: 1px solid @borderColor;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.bg {
|
||
background: #fafafa;
|
||
}
|
||
.rate {
|
||
transform: rotate(-180deg);
|
||
}
|
||
&-center {
|
||
padding: 6px 20px 6px;
|
||
.label {
|
||
width: 400px;
|
||
}
|
||
.content {
|
||
flex:1;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
// > div {
|
||
// flex-shrink: 0;
|
||
// }
|
||
}
|
||
&-left {
|
||
flex: 1 ;
|
||
display: flex;
|
||
align-items: center;
|
||
img {
|
||
width: 28px;
|
||
height: 28px;
|
||
border-radius: 50%;
|
||
overflow: hidden;
|
||
margin-right: 10px;
|
||
}
|
||
}
|
||
}
|
||
&-bottom {
|
||
padding: 10px 20px 6px;
|
||
border-top: 1px solid @borderColor;
|
||
}
|
||
}
|
||
}
|
||
&-right {
|
||
display: flex;
|
||
flex-direction: column;
|
||
&-item {
|
||
flex: 1 0 auto;
|
||
overflow: auto;
|
||
}
|
||
.pinglun {
|
||
display: flex;
|
||
flex: 1;
|
||
// overflow: auto;
|
||
flex-direction: column;
|
||
&-top {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: auto;
|
||
padding: 0 20px;
|
||
}
|
||
&-bottom {
|
||
width: 100%;
|
||
border-top: 1px solid @borderColor;
|
||
.top{
|
||
border-bottom: 1px solid @borderColor;
|
||
}
|
||
&-content{
|
||
padding: 6px 8px;
|
||
display: flex;
|
||
background: #fff;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
i{
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
textarea {
|
||
resize: none;
|
||
height: 46px;
|
||
font-size: 12px;
|
||
background: #f6f6f6;
|
||
border:none;
|
||
|
||
}
|
||
.el-button--small {
|
||
height: 46px;
|
||
margin: 0 0 0 6px;
|
||
}
|
||
}
|
||
}
|
||
.jilu {
|
||
padding: 0 20px;
|
||
flex: 1;
|
||
overflow: auto;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|