jeecgBootUniapp/src/pages-process/components/taskDeal.vue
2025-05-27 17:31:39 +08:00

625 lines
17 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>
<view class="containerTask">
<view class="cu-bar bg-white solid-bottom height">
<view class="action">
当前环节
<text class="text-bold">[{{resultObj.taskName}}]</text>
</view>
</view>
<view class="margin-top-sm">
<wd-collapse style="width: 100%;" v-model="value1">
<wd-collapse-item name="item1">
<template #title="{expanded,disabled, isFirst }">
<view class="header">
<wd-img class="taskImg" src="/static/user27.png" />
<text class="text-collapse">委托人办理</text>
<wd-icon v-if="expanded" style="float: right;color: #d8d8d8;" name="arrow-down"
size="22px"></wd-icon>
<wd-icon v-else style="float: right;color: #d8d8d8;" name="arrow-up" size="22px"></wd-icon>
</view>
</template>
<view
style="position: relative; display: inline-block; min-width: 60px; margin: 2px 5px;text-align: center;">
<wd-img v-if="!model.entrust" @click="showSelectuser('show1')"
style="width: 32px; height: 32px; margin: 0px auto;margin-top: 10px;"
src="/static/add.png" />
<view v-if="!model.entrust" style="margin-bottom: 10px;">选择</view>
<view @click="reset('show1')">
<wd-img v-if="model.entrust"
style="width: 32px; height: 32px; margin: 0px auto;margin-top: 10px;"
:src="getFileAccessHttpUrl(modelShow.avatar1)" />
<view v-if="model.entrust" style="margin-bottom: 10px;">
{{modelShow.text1}}
</view>
</view>
<SelectUserModal v-if="modelShow.show1" :selected="model.entrust"
@change="(val)=>{show1Change(val,'show1')}" modalTitle="用户选择" :multi="false"
@close="() => (modelShow.show1 = false)"></SelectUserModal>
</view>
</wd-collapse-item>
</wd-collapse>
</view>
<view>
<view class="cu-bar bg-white solid-bottom margin-top-sm">
<view class="action">
<text>
<span>处理意见</span>
</text>
<wd-picker :columns="dropOptions" label="单列选项" v-model="model.reason" use-default-slot>
<view class="cu-tag line-blue margin-left-sm">
<span>选择常用审批语</span>
</view>
</wd-picker>
</view>
</view>
<view class="bg-white" style="height: 100px;">
<wd-textarea v-model="model.reason" placeholder="请输入审批语句" />
</view>
<view class="cu-bar bg-white solid-top">
<view class="action">
<view>
<text class="text" style="font-size: 15px;">
<span>上传附件</span>
</text>
</view>
</view>
</view>
<view class="grid col-4 grid-square padding bg-white ">
<Mupload v-model="fileListTemp" :path="usePath"></Mupload>
</view>
<view class="bg-white solid-top">
<radio-group :value="model.processModel" @change="radioChange">
<label class="uni-list-cell uni-list-cell-pd uni-label-pointer">
<!-- 点击的文字 -->
<radio value="1" style="transform: scale(0.7);" :checked="true"></radio>
<view class="margin-left-sm text-sm">单分支模式</view>
</label>
<label class="uni-list-cell uni-list-cell-pd uni-label-pointer" v-if="resultObj.histListSize>0 ">
<!-- 点击的文字 -->
<radio value="3" style="transform: scale(0.7);"></radio>
<view class="margin-left-sm text-sm">驳回</view>
</label>
<label class="uni-list-cell uni-list-cell-pd uni-label-pointer" v-if="model.processModel=='3'">
<wd-picker :columns="rejectColumns" label="单列选项" v-model="model.rejectModelNode"
use-default-slot>
<view>
<text class="text-lg margin-tb-sm">
<span>{{model.rejectModelNode?dictRejctModel(model.rejectModelNode):'选择驳回节点'}}</span>
</text>
</view>
</wd-picker>
</label>
</radio-group>
</view>
</view>
<view class="margin-top-sm">
<wd-collapse style="width: 100%;" v-model="value2">
<wd-collapse-item name="item1">
<template #title="{expanded,disabled, isFirst }">
<view class="header">
<wd-img class="taskImg" src="/static/user27.png" />
<text class="text-collapse">指定下一步操作人</text>
<wd-icon v-if="expanded" style="float: right;color: #d8d8d8;" name="arrow-down"
size="22px"></wd-icon>
<wd-icon v-else style="float: right;color: #d8d8d8;" name="arrow-up" size="22px"></wd-icon>
</view>
</template>
<view
style="position: relative; display: inline-block; min-width: 60px; margin: 2px 5px;text-align: center;">
<wd-img v-if="!model.nextUserName" @click="showSelectuser('show2')"
style="width: 32px; height: 32px; margin: 0px auto;margin-top: 10px;"
src="/static/add.png" />
<view v-if="!model.nextUserName" style="margin-bottom: 10px;">选择</view>
<view @click="reset('show2')">
<wd-img v-if="model.nextUserName"
style="width: 32px; height: 32px; margin: 0px auto;margin-top: 10px;"
:src="getFileAccessHttpUrl(modelShow.avatar2)" />
<view v-if="model.nextUserName" style="margin-bottom: 10px;">
{{modelShow.text2}}
</view>
</view>
<SelectUserModal v-if="modelShow.show2" :selected="model.nextUserName"
@change="(val)=>{show1Change(val,'show2')}" modalTitle="用户选择" :multi="false"
@close="() => (modelShow.show2 = false)"></SelectUserModal>
</view>
</wd-collapse-item>
</wd-collapse>
</view>
<view class="margin-top-sm">
<wd-collapse style="width: 100%;" v-model="value3">
<wd-collapse-item name="item1">
<template #title="{expanded,disabled, isFirst }">
<view class="header">
<wd-img class="taskImg" src="/static/user27.png" />
<text class="text-collapse">指定抄送人</text>
<wd-icon v-if="expanded" style="float: right;color: #d8d8d8;" name="arrow-down"
size="22px"></wd-icon>
<wd-icon v-else style="float: right;color: #d8d8d8;" name="arrow-up" size="22px"></wd-icon>
</view>
</template>
<view
style="position: relative; display: inline-block; min-width: 60px; margin: 2px 5px;text-align: center;">
<wd-img v-if="!model.ccUserIds" @click="showSelectuser('show3')"
style="width: 32px; height: 32px; margin: 0px auto;margin-top: 10px;"
src="/static/add.png" />
<view v-if="!model.ccUserIds" style="margin-bottom: 10px;">选择</view>
<view @click="reset('show3')">
<wd-img v-if="model.ccUserIds"
style="width: 32px; height: 32px; margin: 0px auto;margin-top: 10px;"
:src="getFileAccessHttpUrl(modelShow.avatar3)" />
<view v-if="model.ccUserIds" style="margin-bottom: 10px;">
{{modelShow.text3}}
</view>
</view>
<SelectUserModal v-if="modelShow.show3" :selected="model.ccUserIds"
@change="(val)=>{show1Change(val,'show3')}" modalTitle="用户选择" :multi="false"
@close="() => (modelShow.show3 = false)"></SelectUserModal>
</view>
</wd-collapse-item>
</wd-collapse>
</view>
<view class="padding text-center">
<view v-if="model.processModel==1">
<template v-for="(item,index) in resultObj.transitionList">
<wd-button class="cu-btn" style="margin-bottom: 3px;" @click="finishTask(item.nextnode)">
{{ item.Transition }}
</wd-button>
</template>
</view>
<view v-else>
<wd-button type="primary" @click="handleManyProcessComplete()">确认提交</wd-button>
</view>
</view>
<wd-toast></wd-toast>
<wd-message-box></wd-message-box>
</view>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, computed, watch, nextTick } from 'vue';
import SelectUserModal from '@/components/SelectUser/components/SelectUserModal.vue'
import { getFileAccessHttpUrl } from '@/common/uitls'
import { useQueue } from 'wot-design-uni'
import Mupload from '@/components/Mupload/Mupload.vue'
import { getProcessTaskTransInfo, processComplete, taskEntrust } from '@/api/process'
import { useToast, useMessage, useNotify, dayjs } from 'wot-design-uni'
defineOptions({
name: 'taskDeal',
options: {
styleIsolation: 'shared',
},
})
const fileListTemp = ref('')
const toast = useToast()
const message = useMessage()
const resultObj = ref({}) //流程信息
const rejectColumns = ref([]) //驳回节点信息
const value1 = ref([])
const value2 = ref([])
const value3 = ref([])
const modelShow = ref({
show1: false,
text1: '',
avatar1: '',
show2: false,
text2: '',
avatar2: '',
show3: false,
text3: '',
avatar3: '',
})
const model = ref({
taskId: '', //taskid
nextnode: '', //下一个节点
nextCodeCount: '',
reason: '同意', //原因
processModel: 1, //分支模式:单分支多分支
rejectModelNode: '', //驳回节点
nextUserName: '', //下一步会签人员
nextUserId: '', //下一步会签人员id
ccUserIds: '', //抄送人员ids
ccUserRealNames: '', //抄送人员usernames
fileList: '', //文件上传list
ysjqx: true, //压缩机数据权限
entrust: '', //委托人员
})
const { closeOutside } = useQueue()
const dropOptions = ref([ //审批语配置
{ label: '同意', value: '同意' },
{ label: '同意***的意见', value: '同意***的意见' },
{ label: '请指示', value: '请指示' },
{ label: '***阅示', value: '***阅示' },
{ label: '请处理', value: '请处理' },
{ label: '不同意', value: '不同意' },
{ label: '请审批', value: '请审批' },
{ label: '审核无误', value: '审核无误' },
])
const props = defineProps({
formData: {
type: Object,
default: () => { },
}
})
const usePath = ref('流程办理附件')
watch( //监听文件路径更改
() => props.formData,
(val) => {//监听formdata 加载数据
if (val) {
console.log(val)
model.value.taskId = val.taskId;
rejectColumns.value = []; //清空驳回信息
model.value.rejectModelNode = '';
let tempArr = [];
getProcessTaskTransInfo({ taskId: model.value.taskId }).then(res => {
console.log(res)
if (res.success) {
resultObj.value = res.result;
res.result.histListNode.forEach(item => {
if (item.NAME_ != res.result.taskName) {//不是当前节点
tempArr.push({ label: item.NAME_, value: item.TASK_DEF_KEY_ })
}
})
rejectColumns.value = tempArr; //赋值驳回信息
}
})
}
},
{ immediate: true, deep: true },
)
const radioChange = (val) => {
model.value.processModel = val.detail.value
if (val.detail.value != 3) {
//清空驳回信息
model.value.rejectModelNode = '';
}
}
const showSelectuser = (val : string) => { //选人组件
modelShow.value[val] = true;
console.log(props.formData)
}
const show1Change = (val, type) => {
let selectUser = val[0]
switch (type) {
case 'show1':
model.value.entrust = selectUser.username
modelShow.value['text1'] = selectUser.realname
modelShow.value['avatar1'] = selectUser.avatar
break;
case 'show2':
model.value.nextUserId = selectUser.username
model.value.nextUserName = selectUser.realname
modelShow.value['text2'] = selectUser.realname
modelShow.value['avatar2'] = selectUser.avatar
break;
case 'show3':
model.value.ccUserIds = selectUser.username
model.value.ccUserRealNames = selectUser.realname
modelShow.value['text3'] = selectUser.realname
modelShow.value['avatar3'] = selectUser.avatar
break;
default:
break;
}
}
const reset = (val : string) => { //重置
switch (val) {
case 'show1':
model.value.entrust = ''
modelShow.value['text1'] = ''
modelShow.value['avatar1'] = ''
break;
case 'show2':
model.value.nextUserName = ''
model.value.nextUserId = ''
modelShow.value['text2'] = ''
modelShow.value['avatar2'] = ''
break;
case 'show3':
model.value.ccUserIds = ''
model.value.ccUserRealNames = '';
modelShow.value['text3'] = ''
modelShow.value['avatar3'] = ''
break;
default:
break;
}
}
const dictRejctModel = (val) => {//翻译驳回
return rejectColumns.value.filter(item => {
return item.value = val
})[0].label;
}
const finishTask = (nextNode) => {//完成任务
console.log(nextNode)
if (nextNode) {
handleProcessComplete(nextNode)
return;
}
if (resultObj.value.transitionList.length == 1) {
handleProcessComplete(resultObj.value.transitionList[0].nextnode)
} else {
toast.error("存在多分支,请手动选择分支!")
}
}
const handleProcessComplete = (nextNode) => {
if (!model.value.reason || model.value.reason.length == 0) {
toast.error("请填写处理意见!")
return
}
if (nextNode) { // true
model.value.nextnode = nextNode;
}
if (model.value.entrust) { //如果有委托,不办理流程
var params = {
taskId: model.value.taskId,
taskAssignee: model.value.entrust
};//查询条件
taskEntrust(params).then(res => {
if (res.success) {
toast.success(res.message)
setTimeout(() => { //延迟0.5s
uni.navigateBack()
}, 1000)
} else {
toast.error(res.message)
}
})
return;
}
message
.confirm({
msg: '确认提交审批吗?',
title: '提示',
})
.then(() => {
console.log(model.value)
model.fileList = JSON.stringify(fileListTemp.value)
processComplete(model.value).then(res => {
if (res.success) {//跳转页面或加载下一个任务
toast.success(res.message)
setTimeout(() => { //延迟0.5s
uni.navigateBack()
}, 1000)
} else {
toast.error(res.message)
}
})
})
}
const handleManyProcessComplete = () => { //驳回任务提交
if (model.value.processModel == 3) {
if (!model.value.rejectModelNode || model.value.rejectModelNode.length == 0) {
toast.error("请选择驳回节点!")
return
}
// else{
// //添加判断在这个item.TASK_DEF_KEY_的参数下面
// //如果是驳回这个item.TASK_DEF_KEY_参数传递给提交流程
// this.handleProcessComplete();
// }
}
handleProcessComplete('');
}
onMounted(() => {
let yy = new Date().getFullYear();
let mm = new Date().getMonth() + 1;
usePath.value = yy + '-' + mm + '-' + '流程办理附件';
console.log(usePath)
})
</script>
<style lang="scss" scoped>
.bg-white {
background-color: #fff;
color: #666;
}
.height {
height: 48px;
}
.cu-bar {
display: flex;
position: relative;
align-items: center;
min-height: 50px;
justify-content: space-between;
}
.cu-bar .action:last-child {
margin-right: 15px;
}
.cu-bar .action:first-child {
margin-left: 15px;
font-size: 15px;
}
.cu-bar .action {
display: flex;
align-items: center;
height: 100%;
justify-content: center;
max-width: 100%;
}
.margin-top-sm {
margin-top: 10px;
}
.containerTask {
background-color: #f7f7f7;
}
.text-bold {
font-weight: 700;
}
.text-collapse {
flex: 1;
font-size: 14px;
white-space: nowrap;
color: inherit;
overflow: hidden;
text-overflow: ellipsis;
}
.taskImg {
height: 17px;
width: 17px;
margin-right: 10px;
vertical-align: -15%
}
.solid-bottom::after {
border-bottom: 1px solid rgba(0, 0, 0, .1);
}
.text-blue,
.line-blue,
.lines-blue {
color: #0081ff;
}
.margin-left-sm {
margin-left: 10px;
}
.cu-tag {
font-size: 12px;
vertical-align: middle;
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 0px 8px;
height: 24px;
font-family: Helvetica Neue, Helvetica, sans-serif;
white-space: nowrap;
}
.cu-tag[class*="line-"]::after {
border-radius: 0;
}
.cu-tag[class*="line-"]::after {
content: " ";
width: 200%;
height: 200%;
position: absolute;
top: 0;
left: 0;
border: 1px solid currentColor;
-webkit-transform: scale(.5);
transform: scale(.5);
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
box-sizing: border-box;
border-radius: inherit;
z-index: 1;
pointer-events: none;
}
.grid.grid-square {
overflow: hidden;
}
.bg-white {
background-color: #fff;
color: #666;
}
.padding {
padding: 17px;
display: block;
}
.grid {
display: flex;
flex-wrap: wrap;
}
.text-sm {
font-size: 13px;
}
.uni-list-cell {
position: relative;
display: flex;
-webkit-box-pack: justify;
-webkit-justify-content: flex-start;
justify-content: flex-start;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
border-bottom: 1px solid #f0f0f0;
}
.uni-list-cell-pd {
padding: 8px 15px;
}
.uni-label-pointer {
cursor: pointer;
}
.cu-btn {
position: relative;
border: 0px;
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 0 15px;
font-size: 14px;
height: 32px;
line-height: 1;
text-align: center;
text-decoration: none;
overflow: visible;
margin-left: 0;
-webkit-transform: translate(0px, 0px);
transform: translate(0px, 0px);
margin-right: 0;
}
.text-lg {
font-size: 16px;
}
.margin-tb-sm {
margin-top: 10px;
margin-bottom: 10px;
}
</style>