first commit
This commit is contained in:
@@ -0,0 +1,502 @@
|
||||
<template>
|
||||
<a-card style="margin-top: 10px">
|
||||
<template #title> <audit-outlined /><span style="margin-left: 10px">我的审批</span> </template>
|
||||
<a-spin :spinning="loading">
|
||||
<a-list itemLayout="vertical">
|
||||
<a-list-item>
|
||||
<div style="width: 100%">
|
||||
<div style="margin-bottom: 5px">
|
||||
处理意见:
|
||||
<a-select
|
||||
style="width: 300px"
|
||||
placeholder="常用审批语"
|
||||
:getPopupContainer="(target) => target.parentNode"
|
||||
@change="changeReasonSelection"
|
||||
>
|
||||
<a-select-option v-for="(item, key) in remarksDictOptions" :key="key" :value="item.value">{{ item.text }}</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<a-textarea :rows="3" v-model:value="model.reason" />
|
||||
</div>
|
||||
</a-list-item>
|
||||
|
||||
<a-list-item>
|
||||
<j-upload text="添加文件" bizPath="bpm" :returnUrl="false" v-model:value="model.fileList"></j-upload>
|
||||
</a-list-item>
|
||||
|
||||
<!-- 选择分支 -->
|
||||
<a-list-item>
|
||||
<div style="width: 100%">
|
||||
<a-radio-group v-model:value="model.processModel">
|
||||
<a-radio :checked="true" :value="1">单分支模式</a-radio>
|
||||
<a-radio :value="2">多分支模式</a-radio>
|
||||
<a-radio :value="3" v-if="historyCount > 0 && allowReject">驳回</a-radio>
|
||||
</a-radio-group>
|
||||
|
||||
<span v-show="model.processModel == 2">
|
||||
<span style="color: red">多分支模式默认执行所有分支:</span>
|
||||
<template v-for="(item, index) in branchList">
|
||||
<a-checkbox :checked="true" :value="item.nextnode">{{ item.Transition }}</a-checkbox>
|
||||
</template>
|
||||
</span>
|
||||
|
||||
<span v-show="model.processModel == 3" v-if="historyCount > 0">
|
||||
<a-select v-model:value="model.rejectModelNode" :getPopupContainer="(target) => target?.parentNode" style="width: 150px">
|
||||
<template v-for="(item, index) in historyList">
|
||||
<a-select-option v-if="item.NAME_ != currentTaskName" :value="item.TASK_DEF_KEY_">{{ item.NAME_ }}</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
</span>
|
||||
</div>
|
||||
</a-list-item>
|
||||
|
||||
<!-- 下一步操作人 -->
|
||||
<a-list-item class="flex-center" v-if="buttonStatus.selnextUserStatus || buttonStatus.ccStatus || allowAddSign || allowCounterSignAddUser">
|
||||
<a-checkbox v-if="buttonStatus.selnextUserStatus" :checked="checkedNext" @change="handleCheckedNext">指定下一步操作人(指定下一步会签人员)</a-checkbox>
|
||||
<a-checkbox v-if="buttonStatus.ccStatus" :checked="checkedCc" @change="handleCheckedCc">是否抄送</a-checkbox>
|
||||
<a-dropdown v-if="allowAddSign || allowCounterSignAddUser" :trigger="['click']" :overlayStyle="{ width: '120px' }" placement="bottomRight">
|
||||
<div class="dot-more" title="更多操作"> <div></div><div></div><div></div> </div>
|
||||
<template #overlay>
|
||||
<a-menu @click="onMoreAction">
|
||||
<a-menu-item key="add-sign" v-if="allowAddSign">
|
||||
<div class="flex-center">
|
||||
<Icon icon="ant-design:sisternode-outlined" size="22" />
|
||||
<span style="margin-left: 10px">动态加签</span>
|
||||
</div>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="add-user" v-if="allowCounterSignAddUser">
|
||||
<div class="flex-center">
|
||||
<Icon icon="ant-design:usergroup-add-outlined" size="22" />
|
||||
<span style="margin-left: 10px">追加审批人</span>
|
||||
</div>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-list-item>
|
||||
|
||||
<a-list-item style="line-height: 32px" v-show="checkedNext">
|
||||
<span>指定下一步操作人(指定下一步会签人员):</span>
|
||||
<bpm-select-user style="display: inline-block" placeholder="请选择下一步操作人" @change="handleSelectNextUser"></bpm-select-user>
|
||||
</a-list-item>
|
||||
|
||||
<!-- 抄送 -->
|
||||
<a-list-item style="line-height: 32px" v-show="checkedCc">
|
||||
<span>抄送给:</span>
|
||||
<bpm-select-user style="display: inline-block" placeholder="请选择抄送人" @change="handleSelectCcUser"></bpm-select-user>
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
|
||||
<!-- 流转按钮 -->
|
||||
<div style="margin-top: 20px; text-align: center">
|
||||
<template v-if="model.processModel == 1">
|
||||
<template v-for="(item, index) in branchList">
|
||||
<a-button type="primary" @click="handleProcessComplete(item.nextnode)">{{ item.Transition }}</a-button>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-button type="primary" @click="handleManyProcessComplete()">确认提交</a-button>
|
||||
</template>
|
||||
</div>
|
||||
<br />
|
||||
</a-spin>
|
||||
</a-card>
|
||||
<!-- 加签节点弹窗 -->
|
||||
<add-sign-task-modal @register="registerAddSignTaskModal" @selected="selectedAddSignTask" />
|
||||
<!-- 审批人选择人员 -->
|
||||
<user-select-modal :multi="multiSelectUser" @register="registerUserModal" @selected="onSelectedUserOk" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, reactive, computed, toRaw, unref, watchEffect } from 'vue';
|
||||
import { initDictOptions } from '/@/utils/dict';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { taskComplaint, taskComplete, beforeAddSignTask, afterAddSignTask, addMultiInstance} from "../task.handle.api";
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { JSelectUserByDept } from '/@/components/Form';
|
||||
import { AuditOutlined } from '@ant-design/icons-vue';
|
||||
import { JUpload } from '/@/components/Form/src/jeecg/components/JUpload';
|
||||
import BpmSelectUser from '/@/views/super/bpm/process/components/bpmSelectUser/index.vue';
|
||||
import AddSignTaskModal from '/@/views/super/bpm/process/personalOffice/myHandleTask/modal/AddSignTaskModal.vue';
|
||||
import UserSelectModal from '/@/components/Form/src/jeecg/components/userSelect/UserSelectModal.vue';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { isString } from '/@/utils/is';
|
||||
|
||||
export default {
|
||||
name: 'MyHandleContent',
|
||||
components: {
|
||||
UserSelectModal,
|
||||
AddSignTaskModal,
|
||||
JSelectUserByDept,
|
||||
JUpload,
|
||||
AuditOutlined,
|
||||
BpmSelectUser,
|
||||
},
|
||||
props: {
|
||||
historyList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
branchList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
currentTaskName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
taskId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
ccStatus:{
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
allowAddSign:{
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
allowCounterSignAddUser: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
allowReject: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
turnbackTaskId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
selnextUserStatus:{
|
||||
type: Boolean,
|
||||
default: true,
|
||||
}
|
||||
},
|
||||
emits: ['success'],
|
||||
setup(props, { emit }) {
|
||||
console.log('进入MyHandleContent');
|
||||
const loading = ref(false);
|
||||
const { createMessage: $message, createConfirm: $confirm } = useMessage();
|
||||
const userStore = useUserStore();
|
||||
// 转办
|
||||
const [registerAddSignTaskModal, { openModal: openAddSignTaskModal }] = useModal();
|
||||
// 选择用户
|
||||
const [registerUserModal, { openModal: openUserModal, closeModal: closeUserModal }] = useModal();
|
||||
/**
|
||||
* 转审(change-user)和添加审批人(add-user) 都需要选择用户,此处记录不同的类型
|
||||
*/
|
||||
const selectUserType = ref('');
|
||||
const remarksDictOptions = ref([]);
|
||||
const historyCount = computed(() => {
|
||||
return props.historyList.length;
|
||||
});
|
||||
|
||||
const buttonStatus = computed(()=>{
|
||||
return {
|
||||
ccStatus: props.ccStatus,
|
||||
selnextUserStatus: props.selnextUserStatus
|
||||
}
|
||||
})
|
||||
const model = reactive({
|
||||
taskId: '',
|
||||
nextnode: '',
|
||||
nextCodeCount: '',
|
||||
reason: '',
|
||||
processModel: 1,
|
||||
rejectModelNode: '',
|
||||
nextUserName: '',
|
||||
nextUserId: '',
|
||||
ccUserIds: '',
|
||||
ccUserRealNames: '',
|
||||
fileList: '',
|
||||
});
|
||||
//审批人用户是否多选
|
||||
const multiSelectUser = computed(() => {
|
||||
return unref(selectUserType) == 'change-user' ? false : true;
|
||||
});
|
||||
//监听返回节点变化
|
||||
watchEffect(() => {
|
||||
props.turnbackTaskId && (model.rejectModelNode = props.turnbackTaskId);
|
||||
});
|
||||
// 选择下一步操作人
|
||||
const checkedNext = ref(false);
|
||||
const nextPersonList = ref([]);
|
||||
function handleCheckedNext(e) {
|
||||
checkedNext.value = e.target.checked;
|
||||
nextPersonList.value = [];
|
||||
}
|
||||
|
||||
// 选择抄送人
|
||||
const checkedCc = ref(false);
|
||||
const ccPersonList = ref([]);
|
||||
function handleCheckedCc(e) {
|
||||
checkedCc.value = e.target.checked;
|
||||
ccPersonList.value = [];
|
||||
}
|
||||
|
||||
function changeReasonSelection(value) {
|
||||
model.reason = value;
|
||||
}
|
||||
|
||||
function handleProcessComplete(nextnode) {
|
||||
if (!model.reason || model.reason.length == 0) {
|
||||
//update-begin-author:taoyan date:2022-9-5 for: VUEN-2157 2. 意见允许为空
|
||||
//$message.warning('请填写处理意见');
|
||||
//return;
|
||||
//update-end-author:taoyan date:2022-9-5 for: VUEN-2157 2. 意见允许为空
|
||||
}
|
||||
if (nextnode) {
|
||||
model.nextnode = nextnode;
|
||||
}
|
||||
//设置下个节点的数量
|
||||
if (props.branchList) {
|
||||
model.nextCodeCount = props.branchList.length;
|
||||
}
|
||||
|
||||
$confirm({
|
||||
title: '提示',
|
||||
content: '确认提交审批吗?',
|
||||
onOk: commitTaskHandleInfo,
|
||||
});
|
||||
}
|
||||
|
||||
function handleManyProcessComplete() {
|
||||
if (model.processModel == 3) {
|
||||
if (!model.rejectModelNode || model.rejectModelNode.length == 0) {
|
||||
$message.warning('请选择驳回节点');
|
||||
return;
|
||||
}
|
||||
}
|
||||
handleProcessComplete();
|
||||
}
|
||||
|
||||
// 加签——弹出选择界面
|
||||
function handleAddSignTask() {
|
||||
openAddSignTaskModal(true, {
|
||||
taskId: props.taskId
|
||||
});
|
||||
}
|
||||
|
||||
// 加签——回调处理
|
||||
async function selectedAddSignTask(params,addSignType) {
|
||||
console.log('加签', params);
|
||||
console.log('加签', addSignType);
|
||||
if(addSignType=='after'){
|
||||
await afterAddSignTask(params);
|
||||
}
|
||||
if(addSignType=='before'){
|
||||
await beforeAddSignTask(params);
|
||||
}
|
||||
|
||||
//加签完,关闭办理弹窗
|
||||
emit('success');
|
||||
}
|
||||
|
||||
//================[20230707会签节点增加审批人]begin=============================
|
||||
/**
|
||||
* 更多操作
|
||||
*/
|
||||
function onMoreAction(e) {
|
||||
selectUserType.value = 'add-user';
|
||||
if ('add-user' == e.key) {
|
||||
//多实例加签(支持串行和并行会签)
|
||||
onAddHandlePerson();
|
||||
} else if ('add-sign' == e.key) {
|
||||
//加签
|
||||
handleAddSignTask();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 添加审批人 事件
|
||||
*/
|
||||
function onAddHandlePerson() {
|
||||
let id = userStore.getUserInfo.id;
|
||||
selectUserType.value = 'add-user';
|
||||
openUserModal(true, {
|
||||
list: [],
|
||||
excludeUserIdList: [id],
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 人员选中事件
|
||||
* @param data
|
||||
*/
|
||||
async function onSelectedUserOk(data) {
|
||||
console.log('onSelectedUserOk', data);
|
||||
if (data && data.length > 0) {
|
||||
if (!props.taskId) {
|
||||
console.error('节点信息不存在');
|
||||
return;
|
||||
}
|
||||
if (selectUserType.value === 'change-user') {
|
||||
//await doChangeHandlePerson(node.taskId, data)
|
||||
} else if (selectUserType.value === 'add-user') {
|
||||
await doAddHandlePerson(props.taskId, data);
|
||||
} else {
|
||||
console.error('不识别的类型', selectUserType.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 添加审批人 请求
|
||||
*/
|
||||
async function doAddHandlePerson(taskId, userList) {
|
||||
let usernameList = userList.map((item) => item.username);
|
||||
let params = {
|
||||
taskId: taskId,
|
||||
assignees: usernameList,
|
||||
//简流模式,串行会签专用变量值
|
||||
assigneeListKey: 'loopAssigneeCollection',
|
||||
};
|
||||
const result = await addMultiInstance(params);
|
||||
if (result.success) {
|
||||
closeUserModal();
|
||||
emit('success');
|
||||
$message.success('操作成功!');
|
||||
} else {
|
||||
$message.warning(result.message);
|
||||
}
|
||||
}
|
||||
//================[20230707会签节点增加审批人]end=============================
|
||||
/**
|
||||
* 流程处理提交
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function commitTaskHandleInfo() {
|
||||
loading.value = true;
|
||||
const params = toRaw(model);
|
||||
params.taskId = props.taskId;
|
||||
if (params.fileList) {
|
||||
params.fileList = isString(params.fileList) ? params.fileList : JSON.stringify(params.fileList);
|
||||
}
|
||||
try {
|
||||
console.log('流程提交->params', params);
|
||||
let json = await taskComplete(params);
|
||||
console.log('流程提交-result', json);
|
||||
loading.value = false;
|
||||
emit('success');
|
||||
} catch (e) {
|
||||
console.error('流程处理失败', e);
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function initDict() {
|
||||
const dictData = await initDictOptions('approval_remarks');
|
||||
console.log('dic', dictData);
|
||||
remarksDictOptions.value = dictData;
|
||||
}
|
||||
|
||||
function handleSelectNextUser(arr) {
|
||||
let { usernames, realnames } = getInfo(arr);
|
||||
model.nextUserId = usernames.join(',');
|
||||
model.nextUserName = realnames.join(',');
|
||||
}
|
||||
|
||||
function handleSelectCcUser(arr) {
|
||||
let { usernames, realnames } = getInfo(arr);
|
||||
model.ccUserIds = usernames.join(',');
|
||||
model.ccUserRealNames = realnames.join(',');
|
||||
}
|
||||
|
||||
function getInfo(arr) {
|
||||
let usernames = [];
|
||||
let realnames = [];
|
||||
if (arr && arr.length > 0) {
|
||||
for (let item of arr) {
|
||||
usernames.push(item.username);
|
||||
realnames.push(item.realname);
|
||||
}
|
||||
}
|
||||
return {
|
||||
usernames,
|
||||
realnames,
|
||||
};
|
||||
}
|
||||
initDict();
|
||||
return {
|
||||
handleSelectNextUser,
|
||||
handleSelectCcUser,
|
||||
model,
|
||||
remarksDictOptions,
|
||||
changeReasonSelection,
|
||||
historyCount,
|
||||
|
||||
checkedNext,
|
||||
nextPersonList,
|
||||
handleCheckedNext,
|
||||
|
||||
checkedCc,
|
||||
ccPersonList,
|
||||
handleCheckedCc,
|
||||
|
||||
loading,
|
||||
handleManyProcessComplete,
|
||||
handleProcessComplete,
|
||||
buttonStatus,
|
||||
registerAddSignTaskModal,
|
||||
selectedAddSignTask,
|
||||
handleAddSignTask,
|
||||
|
||||
onMoreAction,
|
||||
openUserModal,
|
||||
closeUserModal,
|
||||
registerUserModal,
|
||||
onSelectedUserOk,
|
||||
multiSelectUser
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.ant-card-head-title) {
|
||||
padding: 10px 0;
|
||||
}
|
||||
:deep(.ant-collapse-header) {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
:deep(.ant-card-head) {
|
||||
padding-left: 12px;
|
||||
}
|
||||
html[data-theme='light'] {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
:deep(.ant-card-body) {
|
||||
padding-top: 6px;
|
||||
}
|
||||
//会签节点增加审批人下拉显示更多样式begin
|
||||
.flex-center {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
.dot-more {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
padding: 0 4px;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-left: 8px;
|
||||
& > div {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
background-color: #9e9e9e;
|
||||
margin: 0 1px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
&:hover {
|
||||
background-color: #f7f7f7;
|
||||
& > div {
|
||||
background-color: #0a9fe5;
|
||||
}
|
||||
}
|
||||
}
|
||||
//会签节点增加审批人下拉显示更多样式end
|
||||
</style>
|
||||
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<a-collapse v-model:activeKey="activeKey" style="margin-top: 10px">
|
||||
<a-collapse-panel key="1" header="意见信息">
|
||||
<a-list itemLayout="vertical">
|
||||
<template v-for="(item, index) in bpmLogList">
|
||||
<a-list-item>
|
||||
<a-list-item-meta :description="item.remarks||'无意见信息'">
|
||||
<template #title>
|
||||
{{ item.opUserName }}
|
||||
<span style="color: #ff6d75">[{{ item.taskName }}]</span>
|
||||
{{ item.opTime }}
|
||||
</template>
|
||||
|
||||
<template #avatar>
|
||||
<a-avatar :size="36" style="background-color: #51cbff"
|
||||
><template #icon><UserOutlined /></template
|
||||
></a-avatar>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
|
||||
<template v-for="(file, index) in item.bpmFiles">
|
||||
<div class="ant-upload-list ant-upload-list-text">
|
||||
<div class="ant-upload-list-item ant-upload-list-item-done">
|
||||
<div class="ant-upload-list-item-info">
|
||||
<span>
|
||||
<paper-clip-outlined />
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
:title="file.fileName"
|
||||
:href="getFileDownloadUrl(file.filePath)"
|
||||
class="ant-upload-list-item-name"
|
||||
>{{ file.fileName }}</a
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { UserOutlined, PaperClipOutlined } from '@ant-design/icons-vue';
|
||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { ref, watch } from 'vue';
|
||||
export default {
|
||||
name: 'TaskCommentList',
|
||||
components: {
|
||||
UserOutlined,
|
||||
PaperClipOutlined,
|
||||
},
|
||||
props: {
|
||||
bpmLogList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const activeKey = ref('1');
|
||||
|
||||
watch(
|
||||
() => props.bpmLogList,
|
||||
() => {
|
||||
if (props.bpmLogList.length > 0) {
|
||||
activeKey.value = '1';
|
||||
} else {
|
||||
activeKey.value = '';
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function getFileDownloadUrl(path) {
|
||||
return getFileAccessHttpUrl(path);
|
||||
}
|
||||
|
||||
return {
|
||||
activeKey,
|
||||
getFileDownloadUrl,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<div class="jeecg-task-handle-content">
|
||||
<!-- 横向步骤条,显示节点 -->
|
||||
<task-node-step-list :taskStepList="taskStepList" :stepCount="bpmLogList.length" :currentNode="currentNode"></task-node-step-list>
|
||||
|
||||
<!-- 意见信息 -->
|
||||
<task-comment-list :bpmLogList="bpmLogList"></task-comment-list>
|
||||
|
||||
<!-- 填写处理意见并提交 -->
|
||||
<my-handle-content
|
||||
v-if="isRunningTask"
|
||||
@success="handleSuccess"
|
||||
:taskId="taskId"
|
||||
:historyList="historyList"
|
||||
:turnbackTaskId="turnbackTaskId"
|
||||
:branchList="branchList"
|
||||
:selnextUserStatus="selnextUserStatus"
|
||||
:ccStatus="ccStatus"
|
||||
:allowAddSign="allowAddSign"
|
||||
:allowCounterSignAddUser="allowCounterSignAddUser"
|
||||
:allowReject="allowReject"
|
||||
:currentTaskName="currentNode.taskName">
|
||||
</my-handle-content>
|
||||
|
||||
<!-- 签收 -->
|
||||
<div v-if="claim" style="width: 100%;text-align: center; padding-top: 10px">
|
||||
<a-button type="primary" @click="handleClaim" :loading="loading"><AuditOutlined/>确认签收</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { taskTransInfo, taskComplete, taskClaim } from '../task.handle.api';
|
||||
import { ref, watch } from 'vue';
|
||||
import TaskNodeStepList from './TaskNodeStepList.vue';
|
||||
import TaskCommentList from './TaskCommentList.vue';
|
||||
import MyHandleContent from './MyHandleContent.vue';
|
||||
import { pick } from 'lodash-es';
|
||||
import { AuditOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
export default {
|
||||
name: 'TaskHandleInnerContent',
|
||||
components: {
|
||||
TaskNodeStepList,
|
||||
TaskCommentList,
|
||||
MyHandleContent,
|
||||
AuditOutlined
|
||||
},
|
||||
props: {
|
||||
formData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
//签收状态
|
||||
claim:{
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
emits: ['success', 'claimSuccess'],
|
||||
setup(props, { emit }) {
|
||||
console.log('进入tab panel-content');
|
||||
const taskId = ref('');
|
||||
// 任务步骤条
|
||||
const taskStepList = ref([]);
|
||||
// 当前任务节点
|
||||
const currentNode = ref({});
|
||||
// 审批记录/意见信息
|
||||
const bpmLogList = ref([]);
|
||||
// 历史节点
|
||||
const historyList = ref([]);
|
||||
// 获取上一步的节点
|
||||
const turnbackTaskId = ref('');
|
||||
// 任务分支
|
||||
const branchList = ref([]);
|
||||
const isRunningTask = ref(true);
|
||||
const allowAddSign = ref(false);
|
||||
//允许驳回
|
||||
const allowReject = ref(true);
|
||||
const allowCounterSignAddUser = ref(false);
|
||||
const loading = ref(false);
|
||||
// 选择下一步处理人
|
||||
const selnextUserStatus = ref(true);
|
||||
// 选择抄送人
|
||||
const ccStatus = ref(true);
|
||||
|
||||
getTaskTransInfo();
|
||||
|
||||
async function getTaskTransInfo(type?) {
|
||||
let taskType = props.formData['PROCESS_TAB_TYPE'];
|
||||
console.log('taskType>>', taskType)
|
||||
if(type){
|
||||
taskType = type;
|
||||
}
|
||||
isRunningTask.value = taskType == 'run';
|
||||
//查询条件-run只需要taskId, history只需要procInstId
|
||||
let params = { taskId: props.formData.taskId, procInstId: props.formData.procInsId };
|
||||
let data = await taskTransInfo(params, taskType);
|
||||
console.log('获取流程流转信息', data);
|
||||
|
||||
//update-begin-author:taoyan date:2022-7-5 for:
|
||||
//选择下一步操作人
|
||||
if(!data.selnextUserStatus || data.selnextUserStatus=='1'){
|
||||
//如果没有该值 或是该值为1
|
||||
selnextUserStatus.value = true;
|
||||
}else{
|
||||
selnextUserStatus.value = false;
|
||||
}
|
||||
|
||||
// 选择抄送人
|
||||
if(!data.ccStatus || data.ccStatus=='1'){
|
||||
//如果没有该值 或是该值为1
|
||||
ccStatus.value = true;
|
||||
}else{
|
||||
ccStatus.value = false;
|
||||
}
|
||||
//是否允许加签
|
||||
allowAddSign.value= data.allowAddSign;
|
||||
//是否允许驳回
|
||||
allowReject.value= data?.rejectStatus && data?.rejectStatus =='0'?false:true;
|
||||
//是否多实例- 会签加签 是否允许会签节点加人0否、1允许
|
||||
allowCounterSignAddUser.value = (data?.allowCounterSignAddUser && data.allowCounterSignAddUser =='1');
|
||||
taskStepList.value = data.bpmLogStepList;
|
||||
bpmLogList.value = data.bpmLogList;
|
||||
|
||||
let nodeObject = pick(data, 'taskName', 'taskNameStartTime', 'taskAssigneeName');
|
||||
if (isRunningTask.value === false) {
|
||||
// 'taskName', 'taskNameStartTime', 'taskAssigneeName' 是正在运行流程的当前节点信息
|
||||
// 'currTaskName', 'currTaskNameAssignee', 'currTaskNameStartTime'这三个是历史查看中的节点信息
|
||||
nodeObject['taskName'] = data['currTaskName'];
|
||||
nodeObject['taskNameStartTime'] = data['currTaskNameStartTime'];
|
||||
nodeObject['taskAssigneeName'] = data['currTaskNameAssignee'];
|
||||
}
|
||||
currentNode.value = nodeObject;
|
||||
|
||||
historyList.value = data.histListNode;
|
||||
branchList.value = data.transitionList;
|
||||
|
||||
turnbackTaskId.value = data.turnbackTaskId;
|
||||
|
||||
taskId.value = props.formData.taskId;
|
||||
}
|
||||
|
||||
function handleSuccess() {
|
||||
emit('success');
|
||||
}
|
||||
|
||||
/**
|
||||
* 签收调用
|
||||
*/
|
||||
async function handleClaim(){
|
||||
loading.value = true;
|
||||
let params = { taskId: taskId.value };
|
||||
await taskClaim(params);
|
||||
await getTaskTransInfo('run');
|
||||
emit('claimSuccess')
|
||||
setTimeout(()=>{
|
||||
loading.value = false;
|
||||
}, 200)
|
||||
}
|
||||
|
||||
watch(()=>props.claim, (val)=>{
|
||||
if(val===true){
|
||||
// 如果是签收状态 则定义isRunningTask为false
|
||||
isRunningTask.value = false
|
||||
}else{
|
||||
let taskType = props.formData['PROCESS_TAB_TYPE'];
|
||||
isRunningTask.value = taskType == 'run';
|
||||
}
|
||||
}, {immediate: true})
|
||||
|
||||
return {
|
||||
taskId,
|
||||
bpmLogList,
|
||||
taskStepList,
|
||||
currentNode,
|
||||
historyList,
|
||||
branchList,
|
||||
handleSuccess,
|
||||
isRunningTask,
|
||||
handleClaim,
|
||||
loading,
|
||||
ccStatus,
|
||||
allowAddSign,
|
||||
allowCounterSignAddUser,
|
||||
allowReject,
|
||||
selnextUserStatus,
|
||||
turnbackTaskId
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.jeecg-task-handle-content {
|
||||
|
||||
.task-info {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.task-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.task-date {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.task-date span {
|
||||
/* color: #ff6d75;*/
|
||||
}
|
||||
|
||||
.ant-steps-item-description {
|
||||
max-width: 200px !important;
|
||||
}
|
||||
|
||||
/** Button按钮间距 */
|
||||
|
||||
.ant-btn {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
/** 标题和描述对齐 */
|
||||
|
||||
.ant-steps-item-content {
|
||||
text-align: left;
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
/** 描述的样式 */
|
||||
|
||||
.descriptionDiv {
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.jee-cust-selector .ant-select-selection__choice {
|
||||
padding-right: 10px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<a-card>
|
||||
<a-steps progressDot :current="stepIndex" style="padding: 10px" size="default">
|
||||
<template v-if="stepCount > 3">
|
||||
<a-step>
|
||||
<template #title>
|
||||
<div class="task-title">...</div>
|
||||
</template>
|
||||
</a-step>
|
||||
</template>
|
||||
|
||||
<template v-for="(item, index) in taskStepList">
|
||||
<a-step>
|
||||
<template #title>
|
||||
<div class="task-title">{{ item.taskName }}</div>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="descriptionDiv">
|
||||
<span>
|
||||
<!--#40a9ff-->
|
||||
<a-avatar shape="square" style="background-color: #40a9ff"
|
||||
><template #icon><UserOutlined /></template
|
||||
></a-avatar>
|
||||
</span>
|
||||
|
||||
<span style="margin-left: 5px">
|
||||
<div class="task-date" style="text-align: left">
|
||||
<a-tooltip placement="top">
|
||||
<template #title>
|
||||
<span>{{ item.opTime }}</span>
|
||||
</template>
|
||||
|
||||
<span> {{ item.opTime ? item.opTime.substr(0, 10) : item.opTime }}</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div class="task-user" style="text-align: left">
|
||||
<span> {{ item.opUserName }}</span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</a-step>
|
||||
</template>
|
||||
|
||||
<a-step v-if="currentNode.taskName && currentNode.taskName != ''">
|
||||
<template #title>
|
||||
<div class="task-title">{{ currentNode.taskName }}</div>
|
||||
</template>
|
||||
<template #description
|
||||
><!--#faad14eb-->
|
||||
<div class="descriptionDiv">
|
||||
<span>
|
||||
<a-avatar style="background-color: #faad14eb"
|
||||
><template #icon><UserOutlined /></template
|
||||
></a-avatar>
|
||||
</span>
|
||||
<span style="margin-left: 5px">
|
||||
<div class="task-date" style="text-align: left">
|
||||
<a-tooltip placement="top">
|
||||
<template #title>
|
||||
<span>{{ currentNode.taskNameStartTime }}</span>
|
||||
</template>
|
||||
|
||||
<span style="color: #ff6d75">
|
||||
{{ currentNode.taskNameStartTime ? currentNode.taskNameStartTime.substr(0, 10) : currentNode.taskNameStartTime }}
|
||||
</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div class="task-user" style="text-align: left">
|
||||
<span> {{ currentNode.taskAssigneeName }}</span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</a-step>
|
||||
<a-step>
|
||||
<template #title>
|
||||
<div class="task-title">...</div>
|
||||
</template>
|
||||
</a-step>
|
||||
</a-steps>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* top上节点步骤
|
||||
*/
|
||||
import { computed } from 'vue';
|
||||
import { UserOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
export default {
|
||||
name: 'TaskNodeStepList',
|
||||
components: {
|
||||
UserOutlined,
|
||||
},
|
||||
props: {
|
||||
stepCount: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
taskStepList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
currentNode: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const stepIndex = computed(() => {
|
||||
if (props.taskStepList.length > 3) {
|
||||
return props.taskStepList.length + 1;
|
||||
}
|
||||
return props.taskStepList.length;
|
||||
});
|
||||
|
||||
return {
|
||||
stepIndex,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="margin-bottom: 20px; height: 400px; overflow: hidden; overflow-y: auto; overflow-x: auto">
|
||||
<bpm-graphic :instanceId="formData.procInsId" @task="getTaskList"></bpm-graphic>
|
||||
</div>
|
||||
<a-card title="流程历史跟踪">
|
||||
<BasicTable @register="registerTable">
|
||||
<template #remarks="{ record }">
|
||||
<j-ellipsis :value="getNodeInfo(record)" :length="25" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 历史任务跟踪-查看历史节点-流程图
|
||||
*/
|
||||
import BpmGraphic from '/@/views/super/bpm/process/components/BpmGraphic.vue';
|
||||
import { BasicTable } from '/@/components/Table';
|
||||
import { taskTraceColumns } from '../task.handle.data';
|
||||
import { taskTraceList } from '../task.handle.api';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import JEllipsis from '/@/components/Form/src/jeecg/components/JEllipsis.vue';
|
||||
import { ref } from 'vue';
|
||||
|
||||
export default {
|
||||
name: 'TaskTraceContent',
|
||||
components: {
|
||||
BpmGraphic,
|
||||
BasicTable,
|
||||
JEllipsis,
|
||||
},
|
||||
props: {
|
||||
formData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
console.log('进入TaskTraceContent>>');
|
||||
const { tableContext } = useListPage({
|
||||
designScope: 'task-trace-content',
|
||||
pagination: true,
|
||||
tableProps: {
|
||||
title: '',
|
||||
api: taskTraceList,
|
||||
columns: taskTraceColumns,
|
||||
showIndexColumn: true,
|
||||
showTableSetting: false,
|
||||
canResize: false,
|
||||
showActionColumn: false,
|
||||
useSearchForm: false,
|
||||
beforeFetch: (params) => {
|
||||
return addQueryParams(params);
|
||||
},
|
||||
},
|
||||
});
|
||||
const [registerTable] = tableContext;
|
||||
|
||||
function addQueryParams(params) {
|
||||
params.processInstanceId = props.formData.procInsId;
|
||||
return params;
|
||||
}
|
||||
|
||||
const taskList = ref([]);
|
||||
function getTaskList(arr) {
|
||||
console.log('aaa', arr);
|
||||
taskList.value = arr;
|
||||
}
|
||||
|
||||
function getNodeInfo(record) {
|
||||
let arr = taskList.value;
|
||||
if (arr && arr.length > 0) {
|
||||
for (let item of arr) {
|
||||
if (item.id == record.id) {
|
||||
return item.remarks;
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
return {
|
||||
registerTable,
|
||||
getTaskList,
|
||||
getNodeInfo,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user