工作任务
This commit is contained in:
144
packages/conv/AppWorkTask/AppWorkTask.vue
Normal file
144
packages/conv/AppWorkTask/AppWorkTask.vue
Normal file
@@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<ai-list v-if="showlist">
|
||||
<template slot="title">
|
||||
<ai-title title="工作任务"> </ai-title>
|
||||
</template>
|
||||
|
||||
<template slot="tabs" class="tabs">
|
||||
<el-tabs v-model="currIndex" @tab-click="handleClick">
|
||||
<el-tab-pane
|
||||
v-for="(tab, i) in tabList"
|
||||
:key="i"
|
||||
:label="tab.label"
|
||||
:name="String(i)"
|
||||
>
|
||||
<component
|
||||
:is="tab.comp"
|
||||
v-if="currIndex === String(i)"
|
||||
:ref="currIndex"
|
||||
:instance="instance"
|
||||
:dict="dict"
|
||||
@change="changePage"
|
||||
:params="params"
|
||||
:taskRole="taskRole"
|
||||
></component>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
</ai-list>
|
||||
|
||||
<component
|
||||
v-else
|
||||
@change="changePage"
|
||||
:is="componentName"
|
||||
:params="params"
|
||||
:instance="instance"
|
||||
:dict="dict"
|
||||
:detailType="detailType"
|
||||
></component>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ExecuteList from './components/ExecuteList'
|
||||
import InitiatorList from './components/InitiatorList.vue'
|
||||
import Add from './components/Add.vue'
|
||||
import Detail from './components/Detail.vue'
|
||||
import SonDetail from './components/SonDetail.vue'
|
||||
|
||||
export default {
|
||||
label: '工作任务',
|
||||
name: 'AppWorkTask',
|
||||
// 组件
|
||||
components: {
|
||||
ExecuteList,
|
||||
InitiatorList,
|
||||
Add,
|
||||
Detail,
|
||||
SonDetail
|
||||
},
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showlist: true,
|
||||
currIndex: '0',
|
||||
taskRole: '',
|
||||
componentName: '',
|
||||
params: {
|
||||
taskRole: ''
|
||||
},
|
||||
detailType: '0', //0我执行详情 1我发起详情
|
||||
}
|
||||
},
|
||||
// 计算
|
||||
computed: {
|
||||
tabList() {
|
||||
return [
|
||||
{
|
||||
label: '我执行的',
|
||||
name: 'ExecuteList',
|
||||
comp: ExecuteList,
|
||||
taskRole: '1'
|
||||
},
|
||||
{
|
||||
label: '我发起的',
|
||||
name: 'InitiatorList',
|
||||
comp: InitiatorList,
|
||||
taskRole: '0'
|
||||
},
|
||||
{
|
||||
label: '我督办的',
|
||||
name: 'ExecuteList',
|
||||
comp: InitiatorList,
|
||||
taskRole: '2'
|
||||
},
|
||||
{
|
||||
label: '抄送我的',
|
||||
name: 'ExecuteList',
|
||||
comp: InitiatorList,
|
||||
taskRole: '3'
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
// 监听
|
||||
watch: {},
|
||||
// 实例创建后
|
||||
created() {},
|
||||
// 实例渲染后
|
||||
mounted() {},
|
||||
// 方法
|
||||
methods: {
|
||||
handleClick() {
|
||||
this.taskRole = this.tabList[this.currIndex].taskRole
|
||||
},
|
||||
changePage(data) {
|
||||
if (data.type == 'Add') {
|
||||
this.componentName = 'Add'
|
||||
this.showlist = false
|
||||
this.params = data.params
|
||||
}
|
||||
if (data.type == 'Detail') {
|
||||
this.componentName = 'Detail'
|
||||
this.showlist = false
|
||||
this.params = data.params,
|
||||
this.detailType = this.currIndex
|
||||
}
|
||||
if (data.type == 'SonDetail') {
|
||||
this.componentName = 'SonDetail'
|
||||
this.showlist = false
|
||||
this.params = data.params,
|
||||
this.detailType = this.currIndex
|
||||
}
|
||||
if (data.type == 'list') {
|
||||
this.showlist = true
|
||||
this.componentName = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss"></style>
|
||||
290
packages/conv/AppWorkTask/components/Add.vue
Normal file
290
packages/conv/AppWorkTask/components/Add.vue
Normal file
@@ -0,0 +1,290 @@
|
||||
<template>
|
||||
<ai-detail>
|
||||
<template #title>
|
||||
<ai-title :title="parentTaskCode ? '创建子任务' : '创建任务'" isShowBottomBorder isShowBack @onBackClick="onBack(true)"> </ai-title>
|
||||
</template>
|
||||
<template #content>
|
||||
<ai-card title="任务信息">
|
||||
<template slot="content">
|
||||
<el-form ref="formData" :rules="rules" :model="formData" label-width="90px">
|
||||
<!-- 任务类型 -->
|
||||
<el-form-item label="任务类型:" prop="type" style="width: 30%">
|
||||
<ai-select v-model="formData.type" placeholder="任务类型" :selectList="$dict.getDict('workTaskType')"></ai-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 发起人 -->
|
||||
<!-- <div class="especial">
|
||||
<span class="icon">*</span>
|
||||
<span class="people">发起人:</span>
|
||||
<ai-wechat-selecter isShowUser :instance="instance" v-model="formData.sponsorUserList" :isMultiple="false" :disable="sponsorUserListDisable">
|
||||
</ai-wechat-selecter>
|
||||
<span class="hint">(只能选择一人)</span>
|
||||
</div> -->
|
||||
|
||||
<!-- 任务标题 -->
|
||||
<el-form-item label="任务标题:" prop="taskTitle">
|
||||
<el-input v-model="formData.taskTitle" placeholder="请输入任务标题" clearable :maxlength="30" show-word-limit></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 任务说明 -->
|
||||
<el-form-item label="任务说明:" prop="taskDescription">
|
||||
<el-input v-model="formData.taskDescription" placeholder="请输入任务说明" clearable :maxlength="1000" type="textarea" show-word-limit :rows="3"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 截止日期 -->
|
||||
<el-form-item label="截止日期:" prop="lastTime">
|
||||
<el-date-picker v-model="formData.lastTime" :picker-options="pickerOptions0" type="date" placeholder="请选择" value-format="yyyy-MM-dd HH:mm:ss"></el-date-picker>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 任务通知 -->
|
||||
<el-form-item label="任务通知:" prop="isNofity">
|
||||
<el-radio-group v-model="formData.isNofity">
|
||||
<el-radio :label="item.label" v-for="(item, i) in isNofityList" :key="i">{{ item.name }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 任务文件 -->
|
||||
<el-form-item label="任务文件:" prop="taskFiles">
|
||||
<ai-uploader :instance="instance" @change="handleChange" isShowTip fileType="file"
|
||||
acceptType=".zip,.rar,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt,.jpg,.png" :limit="9"></ai-uploader>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 执行人 -->
|
||||
<div class="especial">
|
||||
<span class="icon">*</span>
|
||||
<span class="people">执行人:</span>
|
||||
<ai-user-selecter slot="append" isShowUser :instance="instance" v-model="formData.userInfoList" :disable="userInfoListDisable"></ai-user-selecter>
|
||||
</div>
|
||||
|
||||
<!-- 督办人 -->
|
||||
<div class="especial">
|
||||
<span class="icon"> </span>
|
||||
<span class="people">督办人:</span>
|
||||
<ai-user-selecter slot="append" isShowUser :instance="instance" v-model="formData.checkUserList" :disable="checkUserListDisable"></ai-user-selecter>
|
||||
</div>
|
||||
|
||||
<div class="especial">
|
||||
<span class="icon"> </span>
|
||||
<span class="people">抄送人:</span>
|
||||
<ai-user-selecter slot="append" isShowUser :instance="instance" v-model="formData.sendUserList" :disable="sendUserListDisable"></ai-user-selecter>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
</ai-card>
|
||||
</template>
|
||||
<template #footer>
|
||||
<el-button class="delete-btn footer-btn" @click="onBack">取消</el-button>
|
||||
<el-button class="footer-btn" type="primary" @click="submit('formData')">提交</el-button>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Add',
|
||||
// 组件
|
||||
components: {},
|
||||
props: {
|
||||
instance: Function,
|
||||
params: Object,
|
||||
dict: Object,
|
||||
parentTaskCode: String, //创建子任务 父任务code
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formData: {
|
||||
type: '',
|
||||
taskTitle: '',
|
||||
taskDescription: '',
|
||||
lastTime: '',
|
||||
isNofity: '0',
|
||||
taskFiles: [],
|
||||
checkUserList: [], //督办人
|
||||
id: '',
|
||||
parentTaskCode: '', //上级任务编号
|
||||
sponsorUserList: [], // 发起人列表
|
||||
userInfoList: [], // 执行人列表
|
||||
sendUserList: [], //抄送人列表
|
||||
},
|
||||
rules: {
|
||||
type: [{ required: true, message: '请输入任务标题', trigger: 'change' }],
|
||||
taskTitle: [{ required: true, message: '请输入任务标题', trigger: 'change' }],
|
||||
taskDescription: [{ required: true, message: '请输入任务说明', trigger: 'change' }],
|
||||
lastTime: [{required: true, message: '请选择', trigger: 'change'}],
|
||||
isNofity: [{ required: true, message: '请选择任务通知', trigger: 'change' }],
|
||||
},
|
||||
isAdd: true,
|
||||
showDetail: false,
|
||||
pickerOptions0: {
|
||||
disabledDate(time) {
|
||||
return time.getTime() < Date.now() - 8.64e7;
|
||||
}
|
||||
},
|
||||
showEdit1: false
|
||||
}
|
||||
},
|
||||
// 计算
|
||||
computed: {
|
||||
isNofityList() {
|
||||
return [
|
||||
{ name: '是', label: '1' },
|
||||
{ name: '否', label: '0' },
|
||||
]
|
||||
},
|
||||
sponsorUserListDisable() {
|
||||
return this.formData.userInfoList.concat(this.formData.checkUserList).concat(this.formData.sendUserList)
|
||||
},
|
||||
userInfoListDisable() {
|
||||
return this.formData.sponsorUserList.concat(this.formData.checkUserList).concat(this.formData.sendUserList)
|
||||
},
|
||||
checkUserListDisable() {
|
||||
return this.formData.userInfoList.concat(this.formData.sponsorUserList).concat(this.formData.sendUserList)
|
||||
},
|
||||
sendUserListDisable() {
|
||||
return this.formData.userInfoList.concat(this.formData.checkUserList).concat(this.formData.sponsorUserList)
|
||||
}
|
||||
},
|
||||
// 监听
|
||||
watch: {},
|
||||
// 实例创建后
|
||||
created() {
|
||||
this.dict.load('workTaskType').then(() => {})
|
||||
},
|
||||
mounted() {
|
||||
if(this.params.id) {
|
||||
this.getDetail()
|
||||
}
|
||||
},
|
||||
// 方法
|
||||
methods: {
|
||||
handleChange(e) {
|
||||
this.formData.taskFiles = e
|
||||
},
|
||||
// 提交
|
||||
submit() {
|
||||
var fileIds = []
|
||||
if(this.formData.taskFiles.length) {
|
||||
this.formData.taskFiles.map((item) => {
|
||||
fileIds.push(item.id)
|
||||
})
|
||||
}
|
||||
this.$refs['formData'].validate((valid) => {
|
||||
if (valid) {
|
||||
if(!this.formData.userInfoList.length) {
|
||||
this.$message.error('请选择执行人')
|
||||
return
|
||||
}
|
||||
this.formData.lastTime =this.formData.lastTime?this.formData.lastTime.substring(0,10) + ' 23:59:59':"";
|
||||
this.instance.post(`/app/appworktaskinfo/addOrUpdate`, {
|
||||
...this.formData,
|
||||
fileIds: fileIds,
|
||||
taskFiles: '',
|
||||
id: null,
|
||||
parentTaskCode: this.parentTaskCode || ''
|
||||
}).then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('提交成功')
|
||||
setTimeout(() => {
|
||||
this.onBack(true)
|
||||
}, 600)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
getDetail() {
|
||||
this.instance.post(`/app/appworktaskinfo/queryDetailById?id=${this.params.id}`, null).then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.showDetail = true
|
||||
this.formData = {...res.data}
|
||||
this.formData.taskFiles = this.formData.fileList || []
|
||||
|
||||
//选人置空 避免字段不一致
|
||||
this.formData.checkUserList = []
|
||||
this.formData.sponsorUserList = []
|
||||
this.formData.userInfoList = []
|
||||
this.formData.sendUserList = []
|
||||
this.formData.isNofity = '0'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 返回按钮
|
||||
onBack(isRefresh) {
|
||||
if(this.parentTaskCode) {
|
||||
this.$emit('back')
|
||||
}else {
|
||||
this.$emit('change', {
|
||||
type: 'list',
|
||||
isRefresh: !!isRefresh,
|
||||
})
|
||||
}
|
||||
},
|
||||
downFileAll () {
|
||||
if (this.form.files.length > 0) {
|
||||
this.instance.post('/app/appofficialdocumentinfo/downLoadAllFileForDetail', null, {
|
||||
responseType: 'blob',
|
||||
params: {
|
||||
id: this.form.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;
|
||||
}
|
||||
}
|
||||
.AiWechatSelecter{
|
||||
width: calc(100% - 120px);
|
||||
}
|
||||
</style>
|
||||
378
packages/conv/AppWorkTask/components/Detail.vue
Normal file
378
packages/conv/AppWorkTask/components/Detail.vue
Normal file
@@ -0,0 +1,378 @@
|
||||
<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>
|
||||
168
packages/conv/AppWorkTask/components/ExecuteList.vue
Normal file
168
packages/conv/AppWorkTask/components/ExecuteList.vue
Normal file
@@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<ai-list isTabs>
|
||||
<template slot="content">
|
||||
<ai-search-bar class="ai-search">
|
||||
<template slot="left">
|
||||
<ai-select v-model="search.status" placeholder="请选择状态" clearable @change=";(page.current = 1), getList()"
|
||||
:selectList="dict.getDict('workTaskDoStatus')"></ai-select>
|
||||
<el-row class="dateRange" type="flex" align="middle">
|
||||
<span class="dateLabel">创建日期</span>
|
||||
<el-date-picker size="small" v-model="search.startTime" placeholder="开始日期"
|
||||
@change=";(page.current = 1), getList()" value-format="yyyy-MM-dd"/>
|
||||
<el-date-picker size="small" v-model="search.lastTime" placeholder="结束日期"
|
||||
@change=";(page.current = 1), getList()" value-format="yyyy-MM-dd"/>
|
||||
</el-row>
|
||||
</template>
|
||||
<template slot="right">
|
||||
<el-input placeholder="任务标题" v-model="search.taskTitle" size="small" @change="(page.current = 1), getList()"
|
||||
clearable prefix-icon="iconfont iconSearch"/>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<el-button style="margin-bottom: 10px;" class="el-button" type="primary" icon="iconfont iconAdd" size="small"
|
||||
@click="toDetail('', 'Add')">创建任务
|
||||
</el-button>
|
||||
<ai-table class="ai-table" :tableData="tableData" :col-configs="colConfigs" :total="page.total"
|
||||
:current.sync="page.current" :size.sync="page.size" @getList="getList" :dict="dict">
|
||||
<el-table-column slot="lastTime" label="截止日期" width="240">
|
||||
<template slot-scope="{ row }">
|
||||
<span>{{ row.lastTime }}<i :style="row.isOverTime==0?'color:#FF8822;':'color:#FF4466;'"
|
||||
style="margin-left:8px;font-style:inherit"
|
||||
v-if="row.overTimeStatus">({{ row.overTimeStatus }})</i></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column slot="percent" label="当前进度" align="center" width="120">
|
||||
<template slot-scope="{ row }">
|
||||
<div>{{ row.percent + '%' }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column slot="options" label="操作" align="center" width="200">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click="toDetail(row.id, 'Detail')">详情</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ExecuteList',
|
||||
components: {},
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableData: [],
|
||||
colConfigs: [
|
||||
{prop: 'taskTitle', label: '任务标题'},
|
||||
{
|
||||
prop: "type",
|
||||
label: "任务类型",
|
||||
width: 120,
|
||||
align: "center",
|
||||
format: (type) =>
|
||||
this.$dict.getLabel("workTaskType", type),
|
||||
},
|
||||
{prop: 'createTime', label: '创建日期', width: 120},
|
||||
{slot: 'lastTime', label: '截止日期'},
|
||||
{
|
||||
prop: "doStatus",
|
||||
label: "任务状态",
|
||||
width: 120,
|
||||
align: "center",
|
||||
format: (doStatus) =>
|
||||
this.$dict.getLabel("workTaskDoStatus", doStatus),
|
||||
},
|
||||
{slot: 'percent', label: '当前进度', align: "center"},
|
||||
],
|
||||
page: {
|
||||
size: 10,
|
||||
current: 1,
|
||||
total: 0,
|
||||
},
|
||||
search: {
|
||||
status: '',
|
||||
startTime: '',
|
||||
lastTime: '',
|
||||
taskTitle: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.dict.load('workTaskDoStatus', 'workTaskType').then(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.instance
|
||||
.post(`/app/appworktaskinfo/list`, null, {
|
||||
params: {
|
||||
...this.page,
|
||||
...this.search,
|
||||
taskRole: 1,
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.tableData = res.data.records
|
||||
this.page.total = res.data.total
|
||||
if (this.tableData.length) {
|
||||
this.tableData.map((item) => {
|
||||
if (item.createTime) {
|
||||
item.createTime = item.createTime.substring(0, 10)
|
||||
}
|
||||
if (item.lastTime) {
|
||||
item.lastTime = item.lastTime.substring(0, 10)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
toDetail(id, type) {
|
||||
this.$emit('change', {
|
||||
type: type,
|
||||
params: {
|
||||
type: type,
|
||||
taskRole: '1',
|
||||
id,
|
||||
}
|
||||
})
|
||||
},
|
||||
// changePage(){}
|
||||
|
||||
reset() {
|
||||
Object.keys(this.search).forEach((e) => {
|
||||
this.search[e] = ''
|
||||
})
|
||||
this.search.startTime = null
|
||||
this.search.lastTime = null
|
||||
this.getList()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.ai-search {
|
||||
:deep( .dateRange ){
|
||||
display: flex;
|
||||
|
||||
.dateLabel {
|
||||
height: 32px;
|
||||
border: 1px solid #d0d4dc;
|
||||
line-height: 32px;
|
||||
padding: 0 8px;
|
||||
background: #f5f5f5;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
171
packages/conv/AppWorkTask/components/InitiatorList.vue
Normal file
171
packages/conv/AppWorkTask/components/InitiatorList.vue
Normal file
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<ai-list isTabs>
|
||||
<template slot="content">
|
||||
<ai-search-bar class="ai-search">
|
||||
<template slot="left">
|
||||
<ai-select v-model="search.status" placeholder="请选择状态" clearable @change=";(page.current = 1), getList()" :selectList="dict.getDict('workTaskStatus')"></ai-select>
|
||||
<el-row class="dateRange" type="flex" align="middle">
|
||||
<span class="dateLabel">创建日期</span>
|
||||
<el-date-picker size="small" v-model="search.startTime" placeholder="开始日期" @change=";(page.current = 1), getList()" value-format="yyyy-MM-dd" />
|
||||
<el-date-picker size="small" v-model="search.lastTime" placeholder="结束日期" @change=";(page.current = 1), getList()" value-format="yyyy-MM-dd" />
|
||||
</el-row>
|
||||
</template>
|
||||
<template slot="right">
|
||||
<el-input placeholder="任务标题" v-model="search.taskTitle" size="small" @change="(page.current = 1), getList()" clearable prefix-icon="iconfont iconSearch"/>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<el-button style="margin-bottom: 10px;" class="el-button" type="primary" icon="iconfont iconAdd" size="small" @click="toAdd('', 'Add')">创建任务</el-button>
|
||||
|
||||
<ai-table class="ai-table" :tableData="tableData" :col-configs="colConfigs" :total="page.total" :current.sync="page.current" :size.sync="page.size" @getList="getList" :dict="dict">
|
||||
<el-table-column slot="taskTitle" label="任务标题">
|
||||
<template slot-scope="{ row }">
|
||||
<span>{{row.parentTaskCode ? '[子任务]' + row.taskTitle : row.taskTitle}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column slot="lastTime" label="截止日期" width="240">
|
||||
<template slot-scope="{ row }">
|
||||
<span>{{row.lastTime}}<i :style="row.isOverTime==0?'color:#FF8822;':'color:#FF4466;'" style="margin-left:8px;font-style:inherit" v-if="row.overTimeStatus">({{row.overTimeStatus}})</i></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column slot="percent" label="当前进度" align="center" width="120">
|
||||
<template slot-scope="{ row }">
|
||||
<div>{{row.percent + '%'}}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column slot="options" label="操作" align="center" width="200">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click="toDetail(row)">详情</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'InitiatorList',
|
||||
components: {},
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object,
|
||||
taskRole: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableData: [],
|
||||
colConfigs: [
|
||||
{ slot: 'taskTitle', label: '任务标题'},
|
||||
{
|
||||
prop: "type",
|
||||
label: "任务类型",
|
||||
width: 120,
|
||||
align: "center",
|
||||
format: (type) =>
|
||||
this.$dict.getLabel("workTaskType", type),
|
||||
},
|
||||
{ prop: 'createTime', label: '创建日期', width: 120},
|
||||
{ slot: 'lastTime', label: '截止日期'},
|
||||
{
|
||||
prop: "status",
|
||||
label: "任务状态",
|
||||
width: 120,
|
||||
align: "center",
|
||||
format: (status) =>
|
||||
this.$dict.getLabel("workTaskStatus", status),
|
||||
},
|
||||
{ slot: 'percent', label: '当前进度',align: "center" },
|
||||
],
|
||||
page: {
|
||||
size: 10,
|
||||
current: 1,
|
||||
total: 0,
|
||||
},
|
||||
search: {
|
||||
status: '',
|
||||
startTime: '',
|
||||
lastTime: '',
|
||||
taskTitle: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.dict.load('workTaskStatus', 'workTaskType').then(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.instance
|
||||
.post(`/app/appworktaskinfo/list`, null, {
|
||||
params: {
|
||||
...this.page,
|
||||
...this.search,
|
||||
taskRole: this.taskRole,
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.tableData = res.data.records
|
||||
this.page.total = res.data.total
|
||||
if(this.tableData.length) {
|
||||
this.tableData.map((item) => {
|
||||
if(item.createTime) {
|
||||
item.createTime = item.createTime.substring(0, 10)
|
||||
}
|
||||
if(item.lastTime) {
|
||||
item.lastTime = item.lastTime.substring(0, 10)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
toDetail(item) {
|
||||
this.$emit('change', {
|
||||
type: 'SonDetail',
|
||||
params: item
|
||||
})
|
||||
},
|
||||
toAdd() {
|
||||
this.$emit('change', {
|
||||
type: 'Add',
|
||||
params: {
|
||||
type: 'Add',
|
||||
taskRole: '1',
|
||||
id: '',
|
||||
}
|
||||
})
|
||||
},
|
||||
// changePage(){}
|
||||
|
||||
reset() {
|
||||
Object.keys(this.search).forEach((e) => {
|
||||
this.search[e] = ''
|
||||
})
|
||||
this.search.startTime = null
|
||||
this.search.lastTime = null
|
||||
this.getList()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.ai-search {
|
||||
:deep( .dateRange ){
|
||||
display: flex;
|
||||
.dateLabel {
|
||||
height: 32px;
|
||||
border: 1px solid #d0d4dc;
|
||||
line-height: 32px;
|
||||
padding: 0 8px;
|
||||
background: #f5f5f5;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
1065
packages/conv/AppWorkTask/components/SonDetail.vue
Normal file
1065
packages/conv/AppWorkTask/components/SonDetail.vue
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user