优化任务编辑功能,仿真流程点击事件开发,仿真策划选择用户功能优化

This commit is contained in:
weibl
2025-11-07 09:15:14 +08:00
parent 8e25730f59
commit 516a85e49f
12 changed files with 167 additions and 68 deletions

View File

@@ -13,7 +13,7 @@ export const queryTaskListApi = (params: any) => {
};
export const updateTaskStatusApi = (params: any) => {
return get(`${PREFIX}task/operation`, params);
return post(`${PREFIX}task/operation`, params);
};
export const attentionTaskApi = (params: any) => {

View File

@@ -17,9 +17,12 @@
</div>
<slot name="otherLeftOptions"></slot>
</template>
<!-- <template #eMemberList="{row}">
<template #eMemberList="{row}">
{{ disposeMemberList(row,'eMemberList') }}
</template> -->
</template>
<template #pMemberList="{row}">
{{ disposeMemberList(row,'pMemberList') }}
</template>
<template #tableActions="{ row }">
<div class="gl-table-actions" v-if="!readonly">
<el-link type="primary" @click="editTableRowFun(row)">编辑</el-link>
@@ -338,9 +341,10 @@ const onNodeDetailOkFun = (formData: any) => {
if (addRow.nodeType === NODE_TYPE.TASK) {
addRow.exeStatus = TASK_PROCESS_STATUS.NO_STARTED;
addRow.achieveStatus = TASK_CALCULATE_STATUS.NO_CALCULATE;
addRow.eMemberListStr = addRow.eMemberList;
addRow.eMemberList = addRow.eMemberListArr;
addRow.pMemberList = addRow.pMemberListArr;
}
console.log('addRow', addRow);
// 给新增节点赋值tagKeyMapList
// const tagKeyList = disposeTagKey(addRow, checkRowData[0]?.tagKeyList || [], tagKeyMapList.value);
// if (addRow?.nodeType === NodeTaskType.ROUNDS || addRow.type === TaskType.PERFORMANCE) {
@@ -387,9 +391,13 @@ const onNodeDetailOkFun = (formData: any) => {
// for (const key in formData) {
// item[key] = formData[key];
// }
getVxeRef().setRow(item, formData).then(res => {
const rowInfo = {
...formData,
eMemberList: formData.eMemberListArr,
pMemberList: formData.pMemberListArr,
};
getVxeRef().setRow(item, rowInfo).then(res => {
console.log('res', res);
});
}
});

View File

@@ -8,10 +8,10 @@
:diaTitle="diaTitle"
@show="onShowFun"
:confirm-closable="false"
width="800"
width="400"
>
<template #default>
<TableForm :colNum="2" ref="tableFormRef" :tableName="tableName" @change="onFormChangeFun">
<TableForm :colNum="detail.nodeType === NODE_TYPE.TASK?2:1" ref="tableFormRef" :tableName="tableName" @change="onFormChangeFun">
<template #form-standard>
<el-cascader
v-model="standard"
@@ -41,6 +41,7 @@ import TableForm from '@/components/common/table/tableForm.vue';
import { dataListDirApi, dataQueryDirApi } from '@/api/data/data';
import { cloneDeep } from 'lodash-es';
import type { CascaderProps } from 'element-plus';
import { NODE_TYPE } from '@/utils/enum/node';
interface Props {
modelValue: boolean;
@@ -79,6 +80,9 @@ const onFormChangeFun = (data:any) => {
if (data.key === 'eMemberList') {
data.data.eMemberListArr = data.val;
}
if (data.key === 'pMemberList') {
data.data.pMemberListArr = data.val;
}
};
const onCancelFun = () => {
visible.value = false;

View File

@@ -8,3 +8,7 @@ export const getUserData = () => {
export const getUserId = () => {
return getUserData().user_id;
};
export const getUserTenantId = () => {
return getUserData().tenant_id;
};

View File

@@ -9,7 +9,7 @@ export const keyboardEvents = (graph:any) => {
graph.bindKey('ctrl+v', () => {
if (!graph.isClipboardEmpty()) {
const cells = graph.paste({ offset: 32 });
const cells = graph.paste({ offset: 20 });
graph.cleanSelection();
graph.select(cells);
}

View File

@@ -0,0 +1,59 @@
import { reactive, ref } from 'vue';
const showPorts = (ports: NodeListOf<SVGElement>, show: boolean) => {
for (let i = 0, len = ports.length; i < len; i += 1) {
ports[i].style.visibility = show ? 'visible' : 'hidden';
}
};
export const initNodeEvents = (graph: any) => {
graph.on('node:mouseenter', () => {
const container = document.getElementById('container')!;
const ports = container.querySelectorAll(
'.x6-port-body'
) as NodeListOf<SVGElement>;
showPorts(ports, true);
});
graph.on('node:mouseleave', () => {
const container = document.getElementById('container')!;
const ports = container.querySelectorAll(
'.x6-port-body'
) as NodeListOf<SVGElement>;
showPorts(ports, false);
});
graph.on('node:selected', ({ node }:any) => {
console.log('node', node);
node.addTools({
name: 'boundary',
args: {
attrs: {
// fill: '#7c68fc',
stroke: '#333',
'stroke-width': 1,
'fill-opacity': 0.2,
},
},
});
});
graph.on('node:unselected', ({ node }:any) => {
console.log('node', node);
node.removeTools();
const container = document.getElementById('container')!;
const ports = container.querySelectorAll(
'.x6-port-body'
) as NodeListOf<SVGElement>;
showPorts(ports, false);
});
};
export const nodeAttributeRef:any = ref({
name: '',
type: '',
value: '',
});
export const setNodeAttribute = (property:any) => {
console.log('setNodeAttribute', property);
for (const key in property) {
nodeAttributeRef.value[key] = property[key];
}
};

View File

@@ -5,11 +5,18 @@
<div class="app-name">{{ appProperty.name }}</div>
<div class="app-tag">{{ appProperty.type }}</div>
</div>
<div>
<span @click="attributeFun">属性</span>
<span @click="paramFun">参数</span>
</div>
</div>
</template>
<script lang="ts" setup>
import { inject, onMounted, reactive } from 'vue';
import { setNodeAttribute } from './nodeEvents';
const emits = defineEmits(['attribute', 'param']);
const appProperty = reactive({
name: '',
@@ -18,6 +25,21 @@ const appProperty = reactive({
});
const getNode:any = inject('getNode');
const attributeFun = () => {
console.log('click attributeFun');
setNodeAttribute(appProperty);
// const store = CommonStore();
// console.log('store', nodeRef, store);
// console.log('attributeFun');
// emits('attribute', appProperty);
};
const paramFun = () => {
console.log('paramFun');
emits('param', appProperty);
};
onMounted(() => {
if (getNode) {
const node = getNode();

View File

@@ -16,10 +16,11 @@ import { Snapline } from '@antv/x6-plugin-snapline';
import { Keyboard } from '@antv/x6-plugin-keyboard';
import { Clipboard } from '@antv/x6-plugin-clipboard';
import { History } from '@antv/x6-plugin-history';
import { onMounted } from 'vue';
import { onMounted, watch } from 'vue';
import { getTeleport } from '@antv/x6-vue-shape';
import { keyboardEvents } from './components/keyboard';
import { stencilRegister } from './components/stencil';
import { initNodeEvents, nodeAttributeRef } from './components/nodeEvents';
// 注册连线
Graph.registerConnector(
@@ -176,25 +177,8 @@ const initGraph = () => {
true
);
// 控制连接桩显示/隐藏
const showPorts = (ports: NodeListOf<SVGElement>, show: boolean) => {
for (let i = 0, len = ports.length; i < len; i += 1) {
ports[i].style.visibility = show ? 'visible' : 'hidden';
}
};
graph.on('node:mouseenter', () => {
const container = document.getElementById('container')!;
const ports = container.querySelectorAll(
'.x6-port-body'
) as NodeListOf<SVGElement>;
showPorts(ports, true);
});
graph.on('node:mouseleave', () => {
const container = document.getElementById('container')!;
const ports = container.querySelectorAll(
'.x6-port-body'
) as NodeListOf<SVGElement>;
showPorts(ports, false);
});
initNodeEvents(graph);
graph.use(
new Snapline({
@@ -287,6 +271,15 @@ const initGraph = () => {
// const importJson = () => {
// };
watch(
() => nodeAttributeRef.value,
(val) => {
console.log('nodeAttributeRef', val);
},
{ deep: true }
);
onMounted(() => {
initGraph();
// document.addEventListener('keydown', (e) => {

View File

@@ -6,22 +6,20 @@ const commonStore = CommonStore();
/** 将用户数组转换成用户名字符串显示 */
export const disposeMemberList = (row:any, key:string = 'memberList') => {
if (row) {
const managerNames:string[] = [];
if (row[key]?.length) {
row[key].forEach((item: {
const managerNames:string[] = [];
if (Array.isArray(row[key]) && row[key]?.length) {
row[key].forEach(
(item: {
name: string;
realName: string;
nickname: string;
}) => {
}) => {
managerNames.push(item.nickname || item.realName || item.name);
});
}
const nameStr = managerNames.join(',');
row.hoverTitle = nameStr;
return nameStr;
}
return row;
const nameStr = managerNames.join(',');
row.hoverTitle = nameStr;
return nameStr;
};
export const fakeUserList = [

View File

@@ -165,6 +165,8 @@ import { modifyNodeTaskPerformanceApi } from '@/api/project/node';
import { TASK_CALCULATE_STATUS, TASK_PROCESS_STATUS } from '@/utils/enum/task';
import dayjs from 'dayjs';
import loadCaseTable from '@/components/common/treeCaseTable/loadCaseTable.vue';
import { getMemberListStr } from '@/utils/task';
import { getUserTenantId } from '@/utils/user';
const props = defineProps<{
showTaskDialog: boolean;
@@ -485,6 +487,8 @@ const addOrEditTaskFun = async() => {
const insertList = cloneDeep(insertRecords).map((item: any) => {
return {
...item,
tenantId: getUserTenantId(),
eMemberList: getMemberListStr(item.eMemberList),
analyseSoftware: Array.isArray(item.analyseSoftware) ? item.analyseSoftware?.join() : item.analyseSoftware,
};
});
@@ -492,6 +496,8 @@ const addOrEditTaskFun = async() => {
const updateList = cloneDeep(updateRecords).map((item: any) => {
return {
...item,
tenantId: getUserTenantId(),
eMemberList: getMemberListStr(item.eMemberList),
analyseSoftware: Array.isArray(item.analyseSoftware) ? item.analyseSoftware?.join() : item.analyseSoftware,
};
});
@@ -523,6 +529,7 @@ const updateTreeDataApi = async (insertList: any[], deleteList: any[], updateLis
// });
const deleteNodeList = getDeleteListIds(deleteList, []);
const addList = disposeTreeTagKey(insertList);
console.log('updateTreeDataApi', {
addNodeList: addList,
editNodeList: updateList,

View File

@@ -91,15 +91,19 @@ const loadingInterface = ref(false);
// ]);
const changeTaskStatus = async(row: any, status: string) => {
const params:{
taskId: string;
exeStatus: string;
finishTime?: string;
} = {
taskId: row.uuid,
exeStatus: status,
taskIds: any[];
req: {
exeStatus: string;
finishTime?:string;
};
} = {
taskIds: [row.uuid],
req: {
exeStatus: status,
},
};
if (status === TASK_PROCESS_STATUS.COMPLETED) {
params.finishTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
params.req.finishTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
}
const res:any = await updateTaskStatusApi(params);
if (res.code === 200) {
@@ -182,19 +186,23 @@ const confirmFun = async() => {
const fromData:any = tableFormRef.value.getFormDataFun();
// console.log('tableFormRef.value.getFormDataFun()', fromData);
const params:{
taskId: string;
exeStatus: string;
achieveStatus: string;
process: number;
finishTime?: string;
taskIds: string[];
req:{
exeStatus: string;
achieveStatus: string;
progress: number;
finishTime?: string;
}
} = {
taskId: fromData.uuid,
exeStatus: fromData.exeStatus,
achieveStatus: fromData.achieveStatus,
process: fromData.progress,
taskIds: [fromData.uuid],
req: {
exeStatus: fromData.exeStatus,
achieveStatus: fromData.achieveStatus,
progress: fromData.progress,
},
};
if (fromData.exeStatus === TASK_PROCESS_STATUS.COMPLETED) {
params.finishTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
params.req.finishTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
}
const res:any = await updateTaskStatusApi(params);
if (res.code === 200) {

View File

@@ -161,21 +161,17 @@ const confirmFun = async() => {
loadingInterface.value = true;
const fromData:any = tableFormRef.value.getFormDataFun();
// console.log('tableFormRef.value.getFormDataFun()', fromData);
const params:{
taskId: string;
exeStatus: string;
achieveStatus: string;
process: number;
finishTime?: string;
} = {
const params:any = {
...fromData,
taskId: fromData.uuid,
exeStatus: fromData.exeStatus,
achieveStatus: fromData.achieveStatus,
process: fromData.progress,
taskIds: [fromData.uuid],
req: {
exeStatus: fromData.exeStatus,
achieveStatus: fromData.achieveStatus,
process: fromData.progress,
},
};
if (fromData.exeStatus === TASK_PROCESS_STATUS.COMPLETED) {
params.finishTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
params.req.finishTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
}
const res:any = await updateTaskStatusApi(params);
if (res.code === 200) {