379 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			379 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <div style="height:100%;">
 | |
|     <ai-detail v-if="!showAdd && !showSonDetail">
 | |
|       <template #title>
 | |
|         <ai-title title="任务详情" isShowBottomBorder isShowBack @onBackClick="onBack(true)">
 | |
|           <template #rightBtn>
 | |
|             <template v-if="detailType == 0 && formData.status == 0">
 | |
|               <el-button type="primary" icon="iconfont iconEdit"  @click="taskProcess=true,processForm.percent=myUserInfo.percent">更新进度</el-button>
 | |
|             </template>
 | |
|           </template>
 | |
|         </ai-title>
 | |
|       </template>
 | |
|       <template #content>
 | |
|         <ai-card title="任务进度">
 | |
|           <template slot="content">
 | |
|             <ai-wrapper class="mar-t16" label-width="80px" :columnsNumber="2" v-if="detailType == 1">
 | |
|               <ai-info-item label="任务状态:" :class="{color1:formData.status==0,color2:formData.status==1,color3:formData.status==2}"><span>{{dict.getLabel('workTaskStatus',formData.status)||'-'}}</span></ai-info-item>
 | |
|               <ai-info-item label="当前进度:"><span>{{formData.percent+'%'}}</span></ai-info-item>
 | |
|             </ai-wrapper>
 | |
|             <ai-wrapper class="mar-t16" label-width="80px" :columnsNumber="2" v-if="detailType == 0">
 | |
|               <ai-info-item label="任务状态:" :class="{color1:myUserInfo.doStatus==0,color2:myUserInfo.doStatus==1,color3:myUserInfo.doStatus==2}"><span>{{dict.getLabel('workTaskStatus',myUserInfo.doStatus)||'-'}}</span></ai-info-item>
 | |
|               <ai-info-item label="当前进度:"><span>{{myUserInfo.percent+'%'}}</span></ai-info-item>
 | |
|             </ai-wrapper>
 | |
|           </template>
 | |
|         </ai-card>
 | |
|         <ai-card title="任务信息">
 | |
|           <template slot="content">
 | |
|             <ai-wrapper class="mar-t16" label-width="80px" :columnsNumber="2">
 | |
|               <ai-info-item label="发起人:"><span>{{formData.sponsorUserName}}</span></ai-info-item>
 | |
|               <ai-info-item label="创建人:"><span>{{formData.createUserName}}</span></ai-info-item>
 | |
|               <ai-info-item label="创建时间:"><span>{{formData.createTime}}</span></ai-info-item>
 | |
|             </ai-wrapper>
 | |
|             <ai-wrapper class="mar-t16" label-width="80px" :columnsNumber="2">
 | |
|               <ai-info-item label="任务状态:">
 | |
|                 <span v-if="detailType == 0">{{dict.getLabel('workTaskStatus',formData.status)||'-'}}</span>
 | |
|                 <span v-if="detailType == 1">{{dict.getLabel('workTaskStatus',formData.status)||'-'}}</span>
 | |
|               </ai-info-item>
 | |
|               <ai-info-item label="任务类型:"><span>{{$dict.getLabel("workTaskType", formData.type) || '-'}}</span></ai-info-item>
 | |
|             </ai-wrapper>
 | |
|             <ai-wrapper class="mar-t16" label-width="80px" :columnsNumber="2">
 | |
|               <ai-info-item label="截止日期:">
 | |
|                 <span>{{formData.lastTime}}<i  :style="formData.isOverTime==0?'color:#FF8822;':'color:#FF4466;'" style="margin-left:8px;font-style:inherit" v-if="formData.overTimeStatus">({{formData.overTimeStatus}})</i></span>
 | |
|               </ai-info-item>
 | |
|             </ai-wrapper>
 | |
|             <ai-wrapper label-width="80px" :columnsNumber="1">
 | |
|               <ai-info-item label="任务说明:"><span>{{formData.taskDescription}}</span></ai-info-item>
 | |
|             </ai-wrapper>
 | |
|             <ai-wrapper label-width="80px" :columnsNumber="1" v-if="detailType == 0">
 | |
|               <ai-info-item label="执行说明:"><span>{{myUserInfo.doDescription}}</span></ai-info-item>
 | |
|             </ai-wrapper>
 | |
|             <ai-bar title="附件" >
 | |
|               <template slot="right" v-if="formData.fileList && formData.fileList.length">
 | |
|                 <span class="Edit" @click="downFileAll"><i class="iconfont iconDownload"></i>下载全部</span>
 | |
|               </template>
 | |
|             </ai-bar>
 | |
|             <ai-file-list v-if="formData.fileList && formData.fileList.length"
 | |
|               :fileList="formData.fileList"
 | |
|               :fileOps="{ name: 'name', size: 'fileSizeStr' }"
 | |
|             ></ai-file-list>
 | |
|           </template>
 | |
|         </ai-card>
 | |
| 
 | |
|          <ai-card title="任务执行情况" v-if="formData.userInfoList">
 | |
|           <template slot="content">
 | |
|             <ai-table :isShowPagination="false"
 | |
|               class="ai-table"
 | |
|               :tableData="formData.userInfoList"
 | |
|               :col-configs="userInfoListColConfigs"
 | |
|               :dict="dict"
 | |
|             >
 | |
|               <el-table-column slot="percent" label="完成进度" align="center">
 | |
|                 <template slot-scope="{ row }">
 | |
|                   <span>{{ row.percent + "%" }}</span>
 | |
|                 </template>
 | |
|               </el-table-column>
 | |
|             </ai-table>
 | |
|           </template>
 | |
|         </ai-card>
 | |
|         <ai-card title="子任务进度">
 | |
|           <template slot="content">
 | |
|             <el-row type="flex" justify="space-between" align="center" style="margin-bottom:8px;">
 | |
|               <el-col :span="16">
 | |
|                 <el-radio-group v-model="sonListType" size="small" @change="getList">
 | |
|                   <el-radio-button label="">全部</el-radio-button>
 | |
|                   <el-radio-button label="0">进行中</el-radio-button>
 | |
|                   <el-radio-button label="1">已完成</el-radio-button>
 | |
|                   <el-radio-button label="2">已关闭</el-radio-button>
 | |
|                 </el-radio-group>
 | |
|               </el-col >
 | |
|               <el-col :span="8" class="icon add-icon">
 | |
|                 <i class="iconfont iconAdd" style="color:#5088FF;" @click="gotoCreate" v-if="formData.status==0">  创建子任务</i>
 | |
|               </el-col>
 | |
|             </el-row>
 | |
|             <ai-table style="margin-top: 16px;" class="ai-table" :tableData="workList" :col-configs="colConfigs" :total="page.total" :current.sync="page.current" :size.sync="page.size" @getList="getList" :dict="dict">
 | |
|               <el-table-column slot="percent" label="当前进度" align="center">
 | |
|                 <template slot-scope="{ row }">
 | |
|                   <span>{{row.percent+'%'}}</span>
 | |
|                 </template>
 | |
|               </el-table-column>
 | |
|               <el-table-column slot="options" label="操作" align="center" fixed="right" width="200">
 | |
|                 <template slot-scope="{ row }">
 | |
|                   <div class="table-options">
 | |
|                     <el-button type="text" @click="toSonDetail(row)">详情</el-button>
 | |
|                   </div>
 | |
|                 </template>
 | |
|               </el-table-column>
 | |
|             </ai-table>
 | |
|           </template>
 | |
|         </ai-card>
 | |
|         <ai-dialog
 | |
|           title="更新进度"
 | |
|           :visible.sync="taskProcess"
 | |
|           @onConfirm="updateProcess('processForm')"
 | |
|           @onCancel="taskProcess=false"
 | |
|           width="580px">
 | |
|           <div style="width:480px;margin:auto;padding:8px 0;">
 | |
|             <el-form :model="processForm" label-width="100px" ref='processForm' :rules="processRules">
 | |
|               <el-form-item label="选择进度:" prop="percent" :rules="[{ required: true, message: '请选择进度', trigger: 'change' },]">
 | |
|               <el-slider v-model="processForm.percent" show-input></el-slider>
 | |
|               </el-form-item>
 | |
|               <el-form-item label="更新说明:" prop="remarks">
 | |
|                 <el-input type="textarea" :rows="4" maxlength="1000" show-word-limit placeholder="请输入..." v-model="processForm.remarks"></el-input>
 | |
|               </el-form-item>
 | |
|             </el-form>
 | |
|           </div>
 | |
|         </ai-dialog>
 | |
|       </template>
 | |
|     </ai-detail>
 | |
|     <add v-if="showAdd" :parentTaskCode="parentTaskCode" :instance="instance" :dict="dict" @back="comBack" :params="formData"></add>
 | |
|     <son-detail v-if="showSonDetail" :instance="instance" :dict="dict" @back="comBack" :params="sonDetailParams" :detailType="'detail'"></son-detail>
 | |
|   </div>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| 
 | |
| import Add from './Add.vue'
 | |
| import SonDetail from './SonDetail.vue'
 | |
| 
 | |
| import {mapState} from 'vuex'
 | |
| export default {
 | |
|   name: 'Detail',
 | |
|   // 组件
 | |
|   components: {
 | |
|     Add,
 | |
|     SonDetail
 | |
|   },
 | |
|   props: {
 | |
|     instance: Function,
 | |
|     params: Object,
 | |
|     dict: Object,
 | |
|     detailType: String,
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       formData: {},
 | |
|       myUserInfo: {},
 | |
|       workList:[],
 | |
|       page:{
 | |
|         size:10,
 | |
|         current:1,
 | |
|         total:null
 | |
|       },
 | |
|       sonListType: '',
 | |
|       colConfigs: [
 | |
|         { prop: 'taskTitle', label: '任务标题' },
 | |
|         { prop: 'createTime', label: '创建日期' },
 | |
|         { prop: 'lastTime', label: '截止日期' },
 | |
|         {
 | |
|           prop: "status",
 | |
|           label: "任务状态",
 | |
|           width: 120,
 | |
|           align: "center",
 | |
|           format: (status) =>
 | |
|             this.$dict.getLabel("workTaskStatus", status),
 | |
|         },
 | |
|         { slot: 'percent', label: '当前进度' },
 | |
|         { slot: 'options', label: '操作' },
 | |
|       ],
 | |
|       taskProcess: false,
 | |
|       processForm:{
 | |
|         remarks: '',
 | |
|         percent: 0
 | |
|       },
 | |
|       showAdd: false,
 | |
|       parentTaskCode: '',
 | |
|       showSonDetail: false,
 | |
|       sonDetailParams: {},
 | |
|       processRules: {
 | |
|         remarks: [{ required: true, message: '请输入更新说明', trigger: 'change' }],
 | |
|       },
 | |
|       userInfoListColConfigs: [
 | |
|         { prop: "userName", label: "执行人" },
 | |
|         { prop: "unitName", label: "所属部门" },
 | |
|         {
 | |
|           prop: "doStatus",
 | |
|           label: "执行状态",
 | |
|           width: 120,
 | |
|           align: "center",
 | |
|           format: (doStatus) =>
 | |
|             this.$dict.getLabel("workTaskStatus", doStatus),
 | |
|         },
 | |
|         { prop: "finishTime", label: "完成时间", align: "center" },
 | |
|         { prop: "finishDescription", label: "完成说明", align: "center" },
 | |
|       ],
 | |
|     }
 | |
|   },
 | |
|   computed: {
 | |
|     ...mapState(['user']),
 | |
|   },
 | |
|   mounted() {
 | |
|     this.dict.load('workTaskType', 'workTaskStatus', 'workTaskFinishStatus').then(() => {
 | |
|       this.getDetail()
 | |
|     })
 | |
| 
 | |
|   },
 | |
|   methods: {
 | |
|     getDetail() {
 | |
|       // /app/appworktaskinfo/queryDetailById
 | |
|       this.instance.post(`/app/appworktaskinfo/queryDetailById?id=${this.params.id}`, null).then((res) => {
 | |
|         if (res.code == 0) {
 | |
|           this.formData = {...res.data}
 | |
|           this.formData.lastTime = this.formData.lastTime.substring(0, 10)
 | |
|           this.myUserInfo = res.data.myUserInfo
 | |
|           this.getList()
 | |
|         }
 | |
|       });
 | |
|     },
 | |
| 
 | |
|     // 子任务列表
 | |
|     getList(){
 | |
|       this.instance.post(`/app/appworktaskinfo/list`, null,{
 | |
|         params: {
 | |
|           parentTaskCode: this.formData.taskCode,
 | |
|           ...this.page,
 | |
|           status: this.sonListType,
 | |
|           taskRole: '0'
 | |
|         }
 | |
|       }).then(res => {
 | |
|         if (res && res.code == 0) {
 | |
|           this.workList = res.data.records;
 | |
|           this.page.total = res.data.total;
 | |
|         }
 | |
|       });
 | |
|     },
 | |
| 
 | |
|     toSonDetail(item) {
 | |
|       this.showSonDetail = true
 | |
|       this.sonDetailParams = item
 | |
|     },
 | |
| 
 | |
|     // 创建子任务
 | |
|     gotoCreate() {
 | |
|       this.showAdd = true
 | |
|       this.parentTaskCode = this.formData.taskCode
 | |
|     },
 | |
| 
 | |
|     // 更新进度
 | |
|     updateProcess(formName){
 | |
|       this.$refs[formName].validate((valid) => {
 | |
|         if (valid) {
 | |
|           this.instance.post(`/app/appworktaskprocess/addOrUpdate`, {...this.processForm, taskCode:this.formData.taskCode}, null).then(res => {
 | |
|             if (res && res.code == 0) {
 | |
|               this.taskProcess = false
 | |
|               this.getDetail()
 | |
|             }
 | |
|           });
 | |
|         } else {
 | |
|           console.log('error submit!!');
 | |
|           return false;
 | |
|         }
 | |
|       });
 | |
|     },
 | |
| 
 | |
|     onBack(isRefresh) {
 | |
|       if(this.params.fromType == 'SonDetail' && this.params.sonDetailId) {
 | |
|         this.$emit('change', {
 | |
|           type: 'SonDetail',
 | |
|           params: {
 | |
|             type: 'SonDetail',
 | |
|             id: this.params.sonDetailId
 | |
|           }
 | |
|         })
 | |
|       }else {
 | |
|         this.$emit('change', {
 | |
|           type: 'list',
 | |
|           isRefresh: isRefresh ? true : false,
 | |
|         })
 | |
|       }
 | |
|     },
 | |
|     comBack() {
 | |
|       this.showSonDetail = false
 | |
|       this.showAdd = false
 | |
|       this.getDetail()
 | |
|     },
 | |
|     downFileAll () {
 | |
|       if (this.formData.fileList.length > 0) {
 | |
|         this.instance.post('/app/appworktaskinfo/downLoadAllFileForDetail', null, {
 | |
|           responseType: 'blob',
 | |
|           params: {
 | |
|             id: this.formData.id
 | |
|           }
 | |
|         }).then((res) => {
 | |
|           const link = document.createElement('a')
 | |
|           let blob = new Blob([res], { type: 'application/vnd.ms-excel' })
 | |
|           link.style.display = 'none'
 | |
|           link.href = URL.createObjectURL(blob)
 | |
|           var num = ''
 | |
|           for (let i = 0; i < 10; i++) {
 | |
|             num += Math.ceil(Math.random() * 10)
 | |
|           }
 | |
|           link.setAttribute('download', '工作文件' + '.zip')
 | |
|           document.body.appendChild(link)
 | |
|           link.click()
 | |
|           document.body.removeChild(link)
 | |
|         })
 | |
|       } else {
 | |
|         this.$message.error('暂无附件提供下载')
 | |
|       }
 | |
|     },
 | |
|   },
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <style scoped lang="scss">
 | |
|   .especial {
 | |
|     margin-bottom: 12px;
 | |
|     .icon {
 | |
|       vertical-align: top;
 | |
|       display: inline-block;
 | |
|       padding-top: 5px;
 | |
|       margin-left: 20px;
 | |
|       color: #f46;
 | |
|     }
 | |
|     .people {
 | |
|       display: inline-block;
 | |
|       font-size: 14px;
 | |
|       color: #666;
 | |
|       margin-right: 16px;
 | |
|       vertical-align: top;
 | |
|     }
 | |
|     .AiWechatSelecter {
 | |
|       display: inline-block;
 | |
|       margin-left: 3px;
 | |
|     }
 | |
|     .hint {
 | |
|       font-size: 14px;
 | |
|       color: #999;
 | |
|       margin-left: 16px;
 | |
|     }
 | |
|     .mar-r40{
 | |
|       margin-right: 40px;
 | |
|     }
 | |
|     .w80{
 | |
|       width: 80px;
 | |
|       text-align: right;
 | |
|       color: #888;
 | |
|     }
 | |
|   }
 | |
|   .add-icon{
 | |
|     text-align: right;
 | |
|     cursor: pointer;
 | |
|     i{
 | |
|       font-size: 14px;
 | |
|     }
 | |
|   }
 | |
|   .color1{
 | |
|     color:#4B87FE;
 | |
|   }
 | |
|   .color2{
 | |
|     color:#2EA222;
 | |
|   }
 | |
|   .color3{
 | |
|     color:#999999;
 | |
|   }
 | |
|   .AiWechatSelecter{
 | |
|     width: calc(100% - 150px);
 | |
|   }
 | |
| </style>
 |