Merge branch 'dev' of https://fcd.gdyditc.com/itc-framework/ma/2024/front into dev-zhaoDN/global-workflow-setting

This commit is contained in:
lvjunzhao
2025-03-26 10:28:59 +08:00
43 changed files with 7722 additions and 420 deletions

View File

@ -0,0 +1,119 @@
<template>
<a-button class="mr-2" @click="show">{{ t('加签或减签') }}</a-button>
<a-modal :width="1000" :visible="data.visible" :title="t('加签或减签')" :maskClosable="false" @ok="submit" @cancel="cancel"
@close="cancel()">
<div class="p-5 box">
<SelectApproveUser :schemaId="props.schemaId" :taskId="props.taskId" :selectedUser="props.selectedUser"
@update:selectIds="handleSelectIds" @update:addUserIds="handleAddIds" @update:subUserIds="handleSubIds" />
</div>
</a-modal>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
import SelectApproveUser from './SelectApproveUser.vue';
import { postSetSign } from '/@/api/workflow/adminOperation';
import { notification } from 'ant-design-vue';
import { useI18n } from '/@/hooks/web/useI18n';
import { message } from 'ant-design-vue';
const { t } = useI18n();
const props = defineProps({
schemaId: {
type: String,
// required: true,
},
processId: {
type: String,
// required: true,
},
taskId: {
type: String,
// required: true,
},
selectedUser: Array
});
let data: {
visible: boolean;
selectedIds: Array<number>;
addUserIds: Array<number>;
subUserIds: Array<number>;
} = reactive({
visible: false,
selectedIds: [],
addUserIds: [],
subUserIds: []
});
function show() {
data.selectedIds = [];
data.addUserIds = [];
data.subUserIds = [];
data.visible = true;
}
function cancel() {
data.selectedIds = [];
data.addUserIds = [];
data.subUserIds = [];
data.visible = false;
}
function handleSelectIds(ids) {
ids.forEach((ele) => {
data.selectedIds.push(ele as number);
})
// data.selectedIds = ids;
}
function handleAddIds(ids) {
ids.forEach((ele) => {
data.addUserIds.push(ele as number);
})
// data.addUserIds = ids;
}
function handleSubIds(ids) {
ids.forEach((ele) => {
data.subUserIds.push(ele as number);
})
// data.subUserIds = ids;
}
async function submit() {
let msgs: Array<string> = [];
if (msgs.length > 0) {
msgs.forEach((msg) => {
notification.open({
type: 'error',
message: t('加签减签'),
description: msg,
});
});
} else {
try {
if (props.schemaId && props.taskId) {
const msg = await postSetSign(props.schemaId, props.taskId, data.selectedIds, data.addUserIds, data.subUserIds);
if (msg) {
message.info("加减签成功!")
} else {
message.info("加减签失败!")
}
cancel();
}
} catch (_error) {
notification.open({
type: 'error',
message: t('加签减签'),
description: t('选择加签减签失败'),
});
}
}
}
</script>
<style lang="less" scoped>
.box {
height: 500px;
}
.list-page-box {
display: flex;
flex-wrap: wrap;
overflow-y: auto;
padding: 10px 0;
}
</style>

View File

@ -1,26 +1,15 @@
<template>
<a-modal
:width="800"
:visible="true"
:title="t('指派审核人')"
:maskClosable="false"
@ok="submit"
@cancel="close"
>
<a-modal :width="800" :visible="true" :title="t('指派审核人')" :maskClosable="false" @ok="submit" @cancel="close">
<div class="p-5">
<div class="mt-2"
><div>{{ title }}{{ t('【当前】:') }}</div>
<div class="mt-2">
<div>{{ title }}{{ t('【当前】:') }}</div>
<a-input :value="data.currentUserNames" disabled />
</div>
<div class="mt-2"
><div>{{ title }}{{ t('【指派给】:') }}</div>
<div class="mt-2">
<div>{{ title }}{{ t('【指派给】:') }}</div>
<SelectUser
:selectedIds="selectedIds"
:disabledIds="data.currentUserIds"
:multiple="true"
@change="getUserList"
>
<SelectUser :selectedIds="selectedIds" :disabledIds="data.currentUserIds" :multiple="false"
@change="getUserList">
<a-input :value="data.selectedNames" />
</SelectUser>
</div>
@ -29,90 +18,109 @@
</template>
<script setup lang="ts">
import { computed, onMounted, reactive } from 'vue';
import { getApproveUserList, postSetAssignee } from '/@/api/workflow/task';
import { SelectUser } from '/@/components/SelectOrganizational/index';
import { getUserMulti } from '/@/api/system/user';
import { notification } from 'ant-design-vue';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
const props = defineProps({
schemaId: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
taskId: {
type: String,
required: true,
},
});
let emits = defineEmits(['close']);
let data: {
currentUserNames: string;
currentUserIds: Array<string>;
selectedNames: string;
selectedList: Array<{ id: string; name: string }>;
} = reactive({
selectedList: [],
currentUserIds: [],
currentUserNames: '',
selectedNames: '',
});
const selectedIds = computed(() => {
return data.selectedList.map((ele) => {
return ele.id;
});
});
onMounted(async () => {
if (props.schemaId && props.taskId) {
try {
let userList = await getApproveUserList(props.schemaId, props.taskId);
data.currentUserNames = userList
.map((ele) => {
return ele.name;
})
.join(',');
data.currentUserIds = userList.map((ele) => {
return ele.id;
});
} catch (_error) {}
}
});
async function getUserList(list: Array<string>) {
data.selectedList = await getUserMulti(list.join(','));
data.selectedNames = data.selectedList
import { computed, onMounted, reactive } from 'vue';
import { getApproveUserList } from '/@/api/workflow/task';
import { postSetAssignee } from '/@/api/workflow/adminOperation';
import { SelectUser } from '/@/components/SelectOrganizational/index';
import { getUserMulti } from '/@/api/system/user';
import { notification } from 'ant-design-vue';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
const props = defineProps({
schemaId: {
type: String,
// required: true,
},
title: {
type: String,
// required: true,
},
taskId: {
type: String,
// required: true,
},
userList: {
type: Array,
}
});
let emits = defineEmits(['close']);
let data: {
currentUserNames: string;
currentUserIds: Array<string>;
selectedNames: string;
selectedList: Array<{ id: string; name: string }>;
} = reactive({
selectedList: [],
currentUserIds: [],
currentUserNames: '',
selectedNames: '',
});
const selectedIds = computed(() => {
return data.selectedList.map((ele) => {
return ele.id;
});
});
onMounted(async () => {
if (props.schemaId && props.taskId) {
try {
let userList = await getApproveUserList(props.schemaId, props.taskId);
data.currentUserNames = userList
.map((ele) => {
return ele.name;
})
.join(',');
data.currentUserIds = userList.map((ele) => {
return ele.id;
});
data.selectedList = userList.map((ele) => {
return { 'id': ele.id, 'name': ele.name }
})
} catch (_error) { }
} else {
data.currentUserNames = props.userList.assigneeVoList.map((ele) => {
return ele.name;
});
data.currentUserIds = props.userList.assigneeVoList.map((ele) => {
return ele.id;
});
data.selectedList = props.userList.assigneeVoList.map((ele) => {
return { 'id': ele.id, 'name': ele.name }
})
}
});
async function getUserList(list: Array<string>) {
data.selectedList = await getUserMulti(list.join(','));
data.selectedNames = data.selectedList
.map((ele) => {
return ele.name;
})
.join(',');
}
async function submit() {
try {
let res = await postSetAssignee({ 'taskId': props.taskId, 'assignees': selectedIds.value });
// let res = await postSetAssignee(props.taskId, selectedIds.value);
if (res) {
notification.open({
type: 'success',
message: t('修改审核人'),
description: t('修改审核人成功'),
});
emits('close', data.selectedList);
// close();
} else {
notification.open({
type: 'error',
message: t('修改审核人'),
description: t('修改审核人失败'),
});
}
async function submit() {
try {
let res = await postSetAssignee(props.taskId, selectedIds.value);
if (res) {
notification.open({
type: 'success',
message: t('指派审核人'),
description: t('指派审核人成功'),
});
close();
} else {
notification.open({
type: 'error',
message: t('指派审核人'),
description: t('指派审核人失败'),
});
}
} catch (error) {}
}
function close() {
emits('close');
}
} catch (error) { }
}
function close() {
emits('close');
}
</script>
<style lang="less" scoped></style>

View File

@ -2,7 +2,9 @@
<a-tabs :tab-position="props.position" v-model:activeKey="activeKey">
<a-tab-pane :key="1" :tab="t('表单信息')" force-render><slot></slot></a-tab-pane>
<a-tab-pane :key="2" :tab="t('流程信息')">
<ProcessInformation :xml="xml" :processId="processId"
<ProcessInformation :xml="xml" :processId="processId" :schemaId="schemaId"
:currentTaskAssigneeNames="currentTaskAssigneeNames" :currentTaskAssignees="currentTaskAssignees"
:canClick="true"
/></a-tab-pane>
<a-tab-pane :key="3" :tab="t('流转记录')" style="overflow: auto"
><FlowRecord :list="taskRecords" :processId="processId"
@ -10,9 +12,15 @@
<a-tab-pane :key="4" :tab="t('附件汇总')"
><SummaryOfAttachments :processId="processId"
/></a-tab-pane>
<a-tab-pane :key="5 + index" v-for="(item, index) in predecessorTasks" :tab="item.schemaName">
<a-tab-pane :key="5" :tab="t('流程变更记录')">
<ChangeRecord :processId="processId" :formDataId="formDataId" :formInfos="formInfos" />
</a-tab-pane>
<a-tab-pane :key="6" :tab="t('审批记录')">
<AuditRecord :processId="processId" :schemaId="schemaId" :xml="xml" />
</a-tab-pane>
<a-tab-pane :key="7 + index" v-for="(item, index) in predecessorTasks" :tab="item.schemaName">
<LookRelationTask
v-if="activeKey === 5 + index"
v-if="activeKey === 7 + index"
:taskId="item.taskId"
:processId="item.processId"
position="left"
@ -29,6 +37,8 @@
import { ref } from 'vue';
import { SchemaTaskItem } from '/@/model/workflow/bpmnConfig';
import { useI18n } from '/@/hooks/web/useI18n';
import ChangeRecord from '/@/views/formChange/formChangeLog/index.vue';
import AuditRecord from '/@/views/auditOpt/auditRecord/index.vue'
const { t } = useI18n();
let props = withDefaults(
defineProps<{
@ -37,6 +47,12 @@
taskRecords: Array<any> | undefined;
processId: string | undefined;
predecessorTasks: Array<SchemaTaskItem> | undefined;
currentTaskAssignees: any;
currentTaskAssigneeNames: string;
currentTaskInfo: any;
schemaId: string;
formDataId: number;
formInfos: Array<any>;
}>(),
{
xml: '',
@ -44,6 +60,14 @@
predecessorTasks: () => {
return [];
},
currentTaskAssigneeNames: '无',
currentTaskAssignees: {},
currentTaskInfo: {},
schemaId: '',
formDataId: 0,
formInfos: () => {
return [];
}
},
);

View File

@ -28,6 +28,16 @@
<div v-for="(item, index) in forms.configs" :key="index" :tab="item.formName">
<div v-show="activeIndex == index">
<div class="page-bg-wrap">
<div class="top-toolbar" style="display: flex;margin-bottom: 10px">
<div id="adminButtons" v-show="activeIndex == index" style="margin-right:10px">
<a-button @click="handleCancel" v-if="forms.modes[index] == 'edit'">取消</a-button>
<a-button @click="handleSave" v-if="forms.modes[index] == 'edit'" type="primary" style="margin-left: 12px">保存</a-button>
<a-button @click="handleEdit" v-if="forms.modes[index] == 'view'">编辑</a-button>
<a-button @click="handleDelete" type="danger" style="margin-left: 12px">删除</a-button>
</div>
<div id="approveExtendButton"></div>
<div id="approveRightButton"></div>
</div>
<div class="top-toolbar">
<SystemForm
class="form-box"
@ -70,6 +80,8 @@
import { SystemForm } from '/@/components/SystemForm/index';
import { FormType } from '/@/enums/workflowEnum';
import { createFormEvent, loadFormEvent, submitFormEvent } from '/@/hooks/web/useFormEvent';
import { message } from "ant-design-vue";
import { updateWorkflow } from '/@/api/workflow/adminOperation';
const { t } = useI18n();
const props = withDefaults(
defineProps<{
@ -78,12 +90,14 @@
opinions?: Array<TaskApproveOpinion> | undefined;
opinionsComponents?: Array<string> | undefined;
formAssignmentData?: null | Recordable;
processId: string;
}>(),
{
disabled: false,
formInfos: () => {
return [];
},
processId: ''
},
);
@ -142,10 +156,12 @@
isOldSystem?: boolean;
}>;
formEventConfigs: FormEventColumnConfig[];
modes: string[];
} = reactive({
formModels: [],
configs: [],
formEventConfigs: [],
modes: []
});
onMounted(async () => {
for await (let element of props.formInfos) {
@ -160,6 +176,8 @@
}
}
forms.formModels.push(formModels);
// 默认赋值view
forms.modes.push('view');
// 系统表单
if (element.formType == FormType.SYSTEM) {
forms.configs.push({
@ -304,27 +322,32 @@
}
return formModes;
}
async function getFormModels(saveRowKey) {
async function getFormModels(saveRowKey,isOnlyActive) {
let formModes = {};
for (let index = 0; index < forms.configs.length; index++) {
const ele = forms.configs[index];
if (ele.formType == FormType.SYSTEM) {
let values = await itemRefs.value[index].workflowSubmit(saveRowKey);
formModes[ele.formKey] = values;
} else {
formModes[ele.formKey] = ele.formModel;
}
for (let index = 0; index < forms.configs.length; index++) {
if (isOnlyActive && index != activeIndex.value) {
continue;
}
const ele = forms.configs[index];
if (ele.formType == FormType.SYSTEM) {
let values = await itemRefs.value[index].workflowSubmit(saveRowKey);
formModes[ele.formKey] = values;
} else {
formModes[ele.formKey] = ele.formModel;
}
}
// forms.configs.forEach((ele) => {
// formModes[ele.formKey] = ele.formModel;
// });
forms.formEventConfigs.forEach(async (ele, i) => {
//此组件 获取数据 就是为了提交表单 所以 表单提交数据 事件 就此处执行
await submitFormEvent(ele, forms.configs[i]?.formModel);
});
return formModes;
// forms.configs.forEach((ele) => {
// formModes[ele.formKey] = ele.formModel;
// });
forms.formEventConfigs.forEach(async (ele, i) => {
if (isOnlyActive && i != activeIndex.value) {
return true;
}
//此组件 获取数据 就是为了提交表单 所以 表单提交数据 事件 就此处执行
await submitFormEvent(ele, forms.configs[i]?.formModel);
});
return formModes;
}
function getSystemType() {
let system = {};
@ -359,6 +382,34 @@
resize.releaseCapture && resize.releaseCapture();
};
}
function handleCancel() {
itemRefs.value[activeIndex.value].setDisabledForm(true);
forms.modes[activeIndex.value] = 'view';
itemRefs.value[activeIndex.value].setFieldsValue(forms.formModels[activeIndex.value]);
}
async function handleDelete() {
let formVal = await itemRefs.value[activeIndex.value].getFieldsValue();
await itemRefs.value[activeIndex.value].handleDelete(formVal.id)
}
async function handleSave() {
const params = await getFormModels(true, true);
const code = await updateWorkflow({ 'variables': params, 'processInstanceId': props.processId })
if (code) {
message.success(t('保存成功'));
} else {
message.success(t('保存失败,请稍后再试'));
}
itemRefs.value[activeIndex.value].setDisabledForm(true);
forms.modes[activeIndex.value] = 'view';
}
function handleEdit() {
itemRefs.value[activeIndex.value].setDisabledForm(false);
forms.modes[activeIndex.value] = 'edit';
}
defineExpose({
validateForm,
getFormModels,
@ -366,6 +417,10 @@
setFormData,
getUploadComponentIds,
getSystemType,
handleEdit,
handleSave,
handleCancel,
handleDelete
});
</script>

View File

@ -13,6 +13,7 @@
:opinions="data.opinions"
:formInfos="data.formInfos"
:disabled="true"
:processId="props.processId"
/>
</FlowPanel>
</template>

View File

@ -1,164 +1,201 @@
<template>
<div style="margin:20px;">
当前流程审批人{{currentTaskAssigneeNames.replaceAll(",","、")}}
</div>
<div style="margin:20px;" v-if="currentTaskAssignees">
节点审批人
<div v-for="(assignees,taskKey) in currentTaskAssignees" :key="taskKey">
<span>{{assignees[0].taskName}}{{currentTaskInfo?.taskDefinitionKey==taskKey?'(当前审批节点)':''}}</span>
<span v-for="(assignee,index) in assignees" :key="index">
{{assignee.assigneeNameStr?(assignee.assigneeNameStr?.replaceAll(",","/") + (index<assignees.length-1?'':'')):('')}}
</span>
</div>
</div>
<!-- 流程信息 -->
<div class="flow-record-box">
<div id="bpmnCanvas" class="canvas" ref="bpmnCanvas"></div>
<div style="margin:20px;">
当前流程审批人{{currentTaskAssigneeNames.replaceAll(",","、")}}
</div>
<div style="margin:20px;" v-if="currentTaskAssignees">
节点审批人
<div v-for="(assignees,taskKey) in currentTaskAssignees" :key="taskKey">
<span>{{assignees[0].taskName}}{{currentTaskInfo?.taskDefinitionKey==taskKey?'(当前审批节点)':''}}</span>
<span :class="canClick ? 'custom-cursor' : ''" v-for="(assignee,index) in assignees" :key="index" @click="openView(assignee)">
{{assignee.assigneeNameStr?(assignee.assigneeNameStr?.replaceAll(",","/") + (index<assignees.length-1?'':'')):('')}}
</span>
</div>
</div>
<!-- 流程信息 -->
<div class="flow-record-box">
<div id="bpmnCanvas" class="canvas" ref="bpmnCanvas"></div>
</div>
<div class="fixed-bottom">
<ZoomInOrOut @in="zoomViewport(false)" @out="zoomViewport(true)" />
</div>
<div class="fixed-bottom">
<ZoomInOrOut @in="zoomViewport(false)" @out="zoomViewport(true)" />
</div>
<a-modal v-if="visibleFlowRecordModal" :visible="true" :width="1000" title="编辑节点" @close="() => {
visibleFlowRecordModal = false;
}" @cancel="() => {
visibleFlowRecordModal = false;
}" @ok="() => {
visibleFlowRecordModal = false;
initBpmnModeler()
}">
<CurrentNode :schemaId="schemaId" :currentTaskAssigneeNames="currentTaskAssigneeNames"
:clickedTaskAssignees="clickedTaskAssignees" :processId="processId">
</CurrentNode>
</a-modal>
</template>
<script lang="ts" setup>
import CustomModeler from '/@bpmn/modeler';
import { ZoomInOrOut } from '/@/components/ModalPanel';
import { getFinishedTask } from '/@/api/workflow/task';
import { ref, reactive, onMounted } from 'vue';
import CustomModeler from '/@bpmn/modeler';
import { ZoomInOrOut } from '/@/components/ModalPanel';
import { getFinishedTask } from '/@/api/workflow/task';
import { ref, reactive, onMounted, provide } from 'vue';
import CurrentNode from '../../../../actHiTaskinst/components/Form.vue';
const props = withDefaults(
defineProps<{
xml: string;
processId: string;
currentTaskAssignees: any;
currentTaskAssigneeNames: string;
currentTaskInfo:any;
}>(),
{
xml: '',
processId: '',
currentTaskAssigneeNames:'无',
currentTaskAssignees: {},
currentTaskInfo:{}
},
);
const bpmnCanvas = ref();
let data: {
bpmnViewer: any;
zoom: number;
xmlString: string;
} = reactive({
bpmnViewer: null,
zoom: 1,
xmlString: '',
});
onMounted(() => {
data.xmlString = props.xml;
if (data.xmlString) initBpmnModeler();
});
const visibleFlowRecordModal = ref(false);
const props = withDefaults(
defineProps<{
xml: string;
processId: string;
currentTaskAssignees: any;
currentTaskAssigneeNames: string;
currentTaskInfo:any;
schemaId: string;
clickedTaskAssignees: any;
canClick: boolean;
}>(),
{
xml: '',
processId: '',
currentTaskAssigneeNames:'无',
currentTaskAssignees: {},
currentTaskInfo:{},
schemaId: '',
clickedTaskAssignees: {},
canClick: false
},
);
const taskNode = ref<Array<{ 'taskId': string, 'taskName': string }>>([]);
const bpmnCanvas = ref();
let data: {
bpmnViewer: any;
zoom: number;
xmlString: string;
} = reactive({
bpmnViewer: null,
zoom: 1,
xmlString: '',
});
onMounted(() => {
data.xmlString = props.xml;
if (data.xmlString) initBpmnModeler();
});
async function initBpmnModeler() {
data.bpmnViewer = await new CustomModeler({
container: bpmnCanvas.value,
additionalModules: [
{
labelEditingProvider: ['value', ''], //禁用节点编辑
paletteProvider: ['value', ''], //禁用/清空左侧工具栏
contextPadProvider: ['value', ''], //禁用图形菜单
bendpoints: ['value', {}], //禁用连线拖动
move: ['value', ''], //禁用单个图形拖动
},
],
async function initBpmnModeler() {
data.bpmnViewer = await new CustomModeler({
container: bpmnCanvas.value,
additionalModules: [
{
labelEditingProvider: ['value', ''], //禁用节点编辑
paletteProvider: ['value', ''], //禁用/清空左侧工具栏
contextPadProvider: ['value', ''], //禁用图形菜单
bendpoints: ['value', {}], //禁用连线拖动
move: ['value', ''], //禁用单个图形拖动
},
],
});
await redrawing();
if (props.processId) {
let res = await getFinishedTask(props.processId);
setColors(
res.finishedNodes ? res.finishedNodes : [],
res.currentNodes ? res.currentNodes : [],
);
}
}
async function redrawing() {
try {
await data.bpmnViewer.importXML(data.xmlString);
data.bpmnViewer.get('elementRegistry').getAll().forEach(ele => {
if ((ele.di.get('bpmnElement').id as String).startsWith('Activity')) {
taskNode.value.push({ 'taskName': ele.di.get('bpmnElement').name, 'taskId': ele.di.get('bpmnElement').id })
}
});
let canvas = data.bpmnViewer.get('canvas');
canvas.zoom('fit-viewport', 'auto');
} catch (err) {
console.log('err: ', err);
}
}
provide('taskNode', taskNode);
function setColors(finishedIds: Array<string>, currentIds: Array<string>) {
// finishedIds 完成的节点id
// currentIds 进行中节点id
let modeling = data.bpmnViewer.get('modeling');
const elementRegistry = data.bpmnViewer.get('elementRegistry');
if (finishedIds.length > 0) {
finishedIds.forEach((it) => {
let Event = elementRegistry.get(it);
modeling.setColor(Event, {
stroke: 'green',
fill: 'white',
});
});
await redrawing();
if (props.processId) {
let res = await getFinishedTask(props.processId);
setColors(
res.finishedNodes ? res.finishedNodes : [],
res.currentNodes ? res.currentNodes : [],
);
}
}
async function redrawing() {
try {
await data.bpmnViewer.importXML(data.xmlString);
let canvas = data.bpmnViewer.get('canvas');
canvas.zoom('fit-viewport', 'auto');
} catch (err) {
console.log('err: ', err);
}
if (currentIds.length > 0) {
currentIds.forEach((it) => {
let Event = elementRegistry.get(it);
modeling.setColor(Event, {
stroke: '#409eff',
fill: 'white',
});
});
}
function setColors(finishedIds: Array<string>, currentIds: Array<string>) {
// finishedIds 完成的节点id
// currentIds 进行中节点id
let modeling = data.bpmnViewer.get('modeling');
const elementRegistry = data.bpmnViewer.get('elementRegistry');
if (finishedIds.length > 0) {
finishedIds.forEach((it) => {
let Event = elementRegistry.get(it);
}
function zoomViewport(zoomIn = true) {
data.zoom = data.bpmnViewer.get('canvas').zoom();
data.zoom += zoomIn ? 0.1 : -0.1;
data.bpmnViewer.get('canvas').zoom(data.zoom);
}
modeling.setColor(Event, {
stroke: 'green',
fill: 'white',
});
});
}
if (currentIds.length > 0) {
currentIds.forEach((it) => {
let Event = elementRegistry.get(it);
modeling.setColor(Event, {
stroke: '#409eff',
fill: 'white',
});
});
}
}
function zoomViewport(zoomIn = true) {
data.zoom = data.bpmnViewer.get('canvas').zoom();
data.zoom += zoomIn ? 0.1 : -0.1;
data.bpmnViewer.get('canvas').zoom(data.zoom);
}
function openView(val) {
if (props.canClick) {
visibleFlowRecordModal.value = true;
props.clickedTaskAssignees.value = val;
}
}
</script>
<style lang="less">
@import '/@/assets/style/bpmn-js/diagram-js.css';
@import '/@/assets/style/bpmn-js/bpmn-font/css/bpmn.css';
@import '/@/assets/style/bpmn-js/bpmn-font/css/bpmn-codes.css';
@import '/@/assets/style/bpmn-js/bpmn-font/css/bpmn-embedded.css';
@import '/@/assets/style/bpmn-js/diagram-js.css';
@import '/@/assets/style/bpmn-js/bpmn-font/css/bpmn.css';
@import '/@/assets/style/bpmn-js/bpmn-font/css/bpmn-codes.css';
@import '/@/assets/style/bpmn-js/bpmn-font/css/bpmn-embedded.css';
.bjs-powered-by {
display: none !important;
}
.bjs-powered-by {
display: none !important;
}
.flow-record-box {
width: 100%;
height: 80vh;
position: relative;
margin-top: 50px;
}
.flow-record-box {
width: 100%;
height: 80vh;
position: relative;
margin-top: 50px;
}
/* 画布 */
.canvas {
width: 100%;
height: 100%;
}
/* 画布 */
.canvas {
width: 100%;
height: 100%;
}
/* 按钮(放大 缩小 清除) */
.fixed-bottom {
position: absolute;
top: 110px;
font-size: 30px;
left: 40%;
display: flex;
}
/* 按钮(放大 缩小 清除) */
.fixed-bottom {
position: absolute;
top: 110px;
font-size: 30px;
left: 40%;
display: flex;
}
.flow-record-box{
// 选择节点的蓝框
.djs-outline{
display: none;
}
// 编辑节点的按钮
.djs-overlay-container{
display: none;
}
.flow-record-box{
// 选择节点的蓝框
.djs-outline{
display: none;
}
// 编辑节点的按钮
.djs-overlay-container{
display: none;
}
}
</style>

View File

@ -1,46 +1,28 @@
<template>
<div v-if="data.visible">
<div v-if="true">
<a-tabs>
<a-tab-pane key="1" :tab="t('候选人')">
<div class="list-page-box" v-if="data.approvedList.length > 0">
<UserCard
:class="data.approvedIds.includes(user.id) ? 'picked' : 'not-picked'"
v-for="(user, userIndex) in data.approvedList"
:key="userIndex"
:item="user"
@click="checkApprovedId(user)"
:disabled="user.canRemove ? false : true"
>
<UserCard :class="data.approvedIds.includes(user.id) ? 'picked' : 'not-picked'"
v-for="(user, userIndex) in data.approvedList" :key="userIndex" :item="user" @click="checkApprovedId(user)"
:disabled="user.canRemove ? false : true">
<template #check>
<a-checkbox
size="small"
:checked="data.approvedIds.includes(user.id)"
:disabled="user.canRemove ? false : true"
/>
<a-checkbox size="small" :checked="data.approvedIds.includes(user.id)"
:disabled="user.canRemove ? false : true" />
</template>
</UserCard>
</div>
</a-tab-pane>
<a-tab-pane key="2" :tab="t('已选人员')">
<SelectUser
v-if="hasMoreBtn"
:selectedIds="data.selectedIds"
:disabledIds="data.disabledIds"
:multiple="true"
@change="changeList"
>
<SelectUser v-if="hasMoreBtn" :selectedIds="data.selectedIds" :disabledIds="data.disabledIds" :multiple="true"
@change="changeList">
<a-button type="primary">{{ t('更多人员添加') }}</a-button>
</SelectUser>
<div class="list-page-box" v-if="data.selectedList.length > 0">
<UserCard
:class="data.selectedIds.includes(user.id) ? 'picked' : 'not-picked'"
v-for="(user, userIndex) in data.selectedList"
:key="userIndex"
:item="user"
@click="checked(user)"
:disabled="data.disabledIds.includes(user.id)"
>
<UserCard :class="data.selectedIds.includes(user.id) ? 'picked' : 'not-picked'"
v-for="(user, userIndex) in data.selectedList" :key="userIndex" :item="user" @click="checked(user)"
:disabled="data.disabledIds.includes(user.id)">
<template #check>
<a-checkbox size="small" :checked="data.selectedIds.includes(user.id)" />
</template>
@ -52,144 +34,162 @@
</template>
<script setup lang="ts">
import { onMounted, reactive } from 'vue';
import { getUserMulti } from '/@/api/system/user';
import { getApproveUserList } from '/@/api/workflow/task';
import { SelectUser } from '/@/components/SelectOrganizational/index';
import { UserCard } from '/@/components/SelectOrganizational/index';
import { cloneDeep } from 'lodash-es';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
const props = defineProps({
schemaId: String,
taskId: String,
hasMoreBtn: {
type: Boolean,
default: true,
},
});
const emits = defineEmits(['update:selectIds']);
// const emits = defineEmits('change');
let data: {
visible: boolean;
approvedList: Array<{
[x: string]: any;
id: string;
name: string;
}>;
selectedList: Array<{ id: string; name: string }>;
approvedIds: Array<string>;
disabledIds: Array<string>;
selectedIds: Array<string>;
} = reactive({
visible: false,
approvedList: [],
selectedList: [],
approvedIds: [],
disabledIds: [],
selectedIds: [],
});
onMounted(async () => {
if (props.schemaId && props.taskId) {
try {
let userList = await getApproveUserList(props.schemaId, props.taskId);
data.approvedList = cloneDeep(userList);
data.approvedIds = data.approvedList.map((ele) => {
import { onMounted, reactive } from 'vue';
import { getUserMulti } from '/@/api/system/user';
import { getApproveUserList } from '/@/api/workflow/task';
import { SelectUser } from '/@/components/SelectOrganizational/index';
import { UserCard } from '/@/components/SelectOrganizational/index';
import { cloneDeep } from 'lodash-es';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
const props = defineProps({
schemaId: String,
taskId: String,
hasMoreBtn: {
type: Boolean,
default: true,
},
selectedUser: Array
});
const emits = defineEmits(['update:selectIds', 'update:addUserIds', 'update:subUserIds']);
// const emits = defineEmits('change');
let data: {
visible: boolean;
approvedList: Array<{
[x: string]: any;
id: string;
name: string;
}>;
selectedList: Array<{ id: string; name: string }>;
approvedIds: Array<string>;
disabledIds: Array<string>;
selectedIds: Array<string>;
addIds: Array<string>;
subIds: Array<string>;
} = reactive({
visible: true,
approvedList: [],
selectedList: [],
approvedIds: [],
disabledIds: [],
selectedIds: [],
addIds: [],
subIds: [],
});
onMounted(async () => {
if (props.schemaId && props.taskId) {
try {
let userList = await getApproveUserList(props.schemaId, props.taskId);
data.approvedList = cloneDeep(userList);
data.approvedIds = data.approvedList.map((ele) => {
return ele.id;
});
data.disabledIds = data.approvedList
.filter((ele) => {
return !ele.canRemove;
})
.map((ele) => {
return ele.id;
});
data.disabledIds = data.approvedList
.filter((ele) => {
return !ele.canRemove;
})
.map((ele) => {
return ele.id;
});
data.selectedList = cloneDeep(userList);
if (props.selectedUser?.length) {
props.selectedUser.forEach((ele) => {
ele.canRemove = ele.canRemove ? false : true;
data.selectedList.push(ele);
})
data.selectedIds = data.selectedList.map((ele) => {
return ele.id;
});
changeData();
data.visible = true;
} catch (_error) {}
}
changeData();
data.visible = true;
} catch (_error) { }
}
});
function checkApprovedId(user) {
if (data.disabledIds.includes(user.id)) {
return false;
}
if (data.approvedIds.includes(user.id)) {
data.approvedIds.splice(
data.approvedIds.findIndex((item) => item === user.id),
1,
);
data.selectedIds.splice(
data.selectedIds.findIndex((item) => item === user.id),
1,
);
data.selectedList.splice(
data.selectedList.findIndex((item) => item.id === user.id),
1,
);
data.subIds.push(user.id)
} else {
data.approvedIds.push(user.id);
data.selectedIds.push(user.id);
data.selectedList.push(user);
data.addIds.push(user.id);
}
changeData();
}
function checked(user) {
if (data.disabledIds.includes(user.id)) {
return false;
}
if (data.selectedIds.includes(user.id)) {
data.selectedList.splice(
data.selectedList.findIndex((item) => item.id === user.id),
1,
);
data.selectedIds = data.selectedIds.filter((o) => {
return o != user.id;
});
data.subIds.push(user.id);
} else {
data.selectedList.push(user);
data.selectedIds.push(user.id);
data.addIds.push(user.id);
}
if (data.approvedIds.includes(user.id)) {
data.approvedIds.splice(
data.approvedIds.findIndex((item) => item === user.id),
1,
);
} else {
data.approvedIds.push(user.id);
}
changeData();
}
async function changeList(userIds: Array<string>) {
data.selectedList = await getUserMulti(userIds.join(','));
data.selectedIds = userIds;
userIds.forEach((id) => {
if (!data.approvedIds.includes(id)) {
data.approvedIds.push(id);
data.addIds.push(id);
}
});
function checkApprovedId(user) {
if (data.disabledIds.includes(user.id)) {
return false;
}
if (data.approvedIds.includes(user.id)) {
data.approvedIds.splice(
data.approvedIds.findIndex((item) => item === user.id),
1,
);
data.selectedIds.splice(
data.selectedIds.findIndex((item) => item === user.id),
1,
);
data.selectedList.splice(
data.selectedList.findIndex((item) => item.id === user.id),
1,
);
} else {
data.approvedIds.push(user.id);
data.selectedIds.push(user.id);
data.selectedList.push(user);
}
changeData();
}
function checked(user) {
if (data.disabledIds.includes(user.id)) {
return false;
}
if (data.selectedIds.includes(user.id)) {
data.selectedList.splice(
data.selectedList.findIndex((item) => item.id === user.id),
1,
);
data.selectedIds = data.selectedIds.filter((o) => {
return o != user.id;
});
} else {
data.selectedList.push(user);
data.selectedIds.push(user.id);
}
if (data.approvedIds.includes(user.id)) {
data.approvedIds.splice(
data.approvedIds.findIndex((item) => item === user.id),
1,
);
} else {
data.approvedIds.push(user.id);
}
changeData();
}
async function changeList(userIds: Array<string>) {
data.selectedList = await getUserMulti(userIds.join(','));
data.selectedIds = userIds;
userIds.forEach((id) => {
if (!data.approvedIds.includes(id)) {
data.approvedIds.push(id);
}
});
changeData();
}
function changeData() {
emits('update:selectIds', data.selectedIds);
}
changeData();
}
function changeData() {
console.log(111111, data.addIds);
console.log(222222, data.subIds)
emits('update:selectIds', data.selectedIds);
emits('update:addUserIds', data.addIds);
emits('update:subUserIds', data.subIds);
}
</script>
<style lang="less" scoped>
.box {
height: 500px;
}
.box {
height: 500px;
}
.list-page-box {
display: flex;
flex-wrap: wrap;
overflow-y: auto;
padding: 10px 0;
}
.list-page-box {
display: flex;
flex-wrap: wrap;
overflow-y: auto;
padding: 10px 0;
}
</style>