mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-12-01 11:38:57 +08:00
feat(功能用例): 脑图保存
This commit is contained in:
parent
14dc8d1d56
commit
06d3a96ef5
@ -90,7 +90,7 @@ import type {
|
|||||||
DeleteDependencyParams,
|
DeleteDependencyParams,
|
||||||
DemandItem,
|
DemandItem,
|
||||||
DragCase,
|
DragCase,
|
||||||
FeatureCaseMinder,
|
FeatureCaseMinderUpdateParams,
|
||||||
ImportExcelType,
|
ImportExcelType,
|
||||||
ModulesTreeType,
|
ModulesTreeType,
|
||||||
OperationFile,
|
OperationFile,
|
||||||
@ -182,7 +182,7 @@ export function batchCopyToModules(data: BatchMoveOrCopyType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 保存脑图
|
// 保存脑图
|
||||||
export function saveCaseMinder(data: FeatureCaseMinder) {
|
export function saveCaseMinder(data: FeatureCaseMinderUpdateParams) {
|
||||||
return MSR.post({ url: `${SaveCaseMinderUrl}`, data });
|
return MSR.post({ url: `${SaveCaseMinderUrl}`, data });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
loading: boolean;
|
loading: boolean;
|
||||||
}>();
|
}>();
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
(e: 'initTemplate', id: string): void;
|
||||||
(e: 'cancel'): void;
|
(e: 'cancel'): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
@ -118,6 +119,7 @@
|
|||||||
});
|
});
|
||||||
formRules.value = result.filter((e: any) => e);
|
formRules.value = result.filter((e: any) => e);
|
||||||
baseInfoLoading.value = false;
|
baseInfoLoading.value = false;
|
||||||
|
emit('initTemplate', id);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@ -129,6 +131,22 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
const saveLoading = ref(false);
|
const saveLoading = ref(false);
|
||||||
|
|
||||||
|
function makeParams() {
|
||||||
|
return {
|
||||||
|
...baseInfoForm.value,
|
||||||
|
id: props.activeCase.id,
|
||||||
|
projectId: appStore.currentProjectId,
|
||||||
|
caseEditType: props.activeCase.caseEditType,
|
||||||
|
customFields: formItem.value.map((item: any) => {
|
||||||
|
return {
|
||||||
|
fieldId: item.field,
|
||||||
|
value: Array.isArray(item.value) ? JSON.stringify(item.value) : item.value,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function handleSave() {
|
function handleSave() {
|
||||||
baseInfoFormRef.value?.validate((errors) => {
|
baseInfoFormRef.value?.validate((errors) => {
|
||||||
if (!errors) {
|
if (!errors) {
|
||||||
@ -136,20 +154,8 @@
|
|||||||
if (valid === true) {
|
if (valid === true) {
|
||||||
try {
|
try {
|
||||||
saveLoading.value = true;
|
saveLoading.value = true;
|
||||||
const data = {
|
|
||||||
...baseInfoForm.value,
|
|
||||||
id: props.activeCase.id,
|
|
||||||
projectId: appStore.currentProjectId,
|
|
||||||
caseEditType: props.activeCase.caseEditType,
|
|
||||||
customFields: formItem.value.map((item: any) => {
|
|
||||||
return {
|
|
||||||
fieldId: item.field,
|
|
||||||
value: Array.isArray(item.value) ? JSON.stringify(item.value) : item.value,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
await updateCaseRequest({
|
await updateCaseRequest({
|
||||||
request: data,
|
request: makeParams(),
|
||||||
fileList: [],
|
fileList: [],
|
||||||
});
|
});
|
||||||
const selectedNode: MinderJsonNode = window.minder.getSelectedNode();
|
const selectedNode: MinderJsonNode = window.minder.getSelectedNode();
|
||||||
@ -181,6 +187,10 @@
|
|||||||
immediate: true,
|
immediate: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
makeParams,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
@ -13,14 +13,18 @@
|
|||||||
single-tag
|
single-tag
|
||||||
tag-enable
|
tag-enable
|
||||||
sequence-enable
|
sequence-enable
|
||||||
|
@content-change="handleContentChange"
|
||||||
@node-select="handleNodeSelect"
|
@node-select="handleNodeSelect"
|
||||||
|
@action="handleAction"
|
||||||
@save="handleMinderSave"
|
@save="handleMinderSave"
|
||||||
>
|
>
|
||||||
<template #extractTabContent>
|
<template #extractTabContent>
|
||||||
<baseInfo
|
<baseInfo
|
||||||
v-if="activeExtraKey === 'baseInfo'"
|
v-if="activeExtraKey === 'baseInfo'"
|
||||||
|
ref="baseInfoRef"
|
||||||
:loading="baseInfoLoading"
|
:loading="baseInfoLoading"
|
||||||
:active-case="activeCase"
|
:active-case="activeCase"
|
||||||
|
@init-template="(id) => (templateId = id)"
|
||||||
@cancel="handleBaseInfoCancel"
|
@cancel="handleBaseInfoCancel"
|
||||||
/>
|
/>
|
||||||
<attachment
|
<attachment
|
||||||
@ -54,9 +58,16 @@
|
|||||||
} from '@/api/modules/case-management/featureCase';
|
} from '@/api/modules/case-management/featureCase';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import useAppStore from '@/store/modules/app';
|
import useAppStore from '@/store/modules/app';
|
||||||
import { getGenerateId, mapTree } from '@/utils';
|
import { MinderEvent } from '@/store/modules/components/minder-editor/types';
|
||||||
|
import { filterTree, getGenerateId, mapTree } from '@/utils';
|
||||||
|
|
||||||
|
import {
|
||||||
|
FeatureCaseMinderEditType,
|
||||||
|
FeatureCaseMinderStepItem,
|
||||||
|
FeatureCaseMinderUpdateParams,
|
||||||
|
} from '@/models/caseManagement/featureCase';
|
||||||
import { TableQueryParams } from '@/models/common';
|
import { TableQueryParams } from '@/models/common';
|
||||||
|
import { MinderEventName } from '@/enums/minderEnum';
|
||||||
|
|
||||||
import { convertToFile, initFormCreate } from '@/views/case-management/caseManagementFeature/components/utils';
|
import { convertToFile, initFormCreate } from '@/views/case-management/caseManagementFeature/components/utils';
|
||||||
|
|
||||||
@ -72,7 +83,12 @@
|
|||||||
const caseTag = t('common.case');
|
const caseTag = t('common.case');
|
||||||
const moduleTag = t('common.module');
|
const moduleTag = t('common.module');
|
||||||
const topTags = [moduleTag, caseTag];
|
const topTags = [moduleTag, caseTag];
|
||||||
const descTags = [t('ms.minders.stepDesc'), t('ms.minders.textDesc')];
|
const stepTag = t('ms.minders.stepDesc');
|
||||||
|
const textTag = t('ms.minders.textDesc');
|
||||||
|
const prerequisiteTag = t('ms.minders.precondition');
|
||||||
|
const remarkTag = t('common.remark');
|
||||||
|
const descTags = [stepTag, textTag];
|
||||||
|
const caseChildTags = [prerequisiteTag, stepTag, textTag, remarkTag];
|
||||||
const importJson = ref<MinderJson>({
|
const importJson = ref<MinderJson>({
|
||||||
root: {} as MinderJsonNode,
|
root: {} as MinderJsonNode,
|
||||||
template: 'default',
|
template: 'default',
|
||||||
@ -80,6 +96,14 @@
|
|||||||
});
|
});
|
||||||
const caseTree = ref<MinderJsonNode[]>([]);
|
const caseTree = ref<MinderJsonNode[]>([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
const tempMinderParams = ref<FeatureCaseMinderUpdateParams>({
|
||||||
|
projectId: appStore.currentProjectId,
|
||||||
|
versionId: '',
|
||||||
|
updateCaseList: [],
|
||||||
|
updateModuleList: [],
|
||||||
|
deleteResourceList: [],
|
||||||
|
});
|
||||||
|
const templateId = ref('');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化用例模块树
|
* 初始化用例模块树
|
||||||
@ -99,6 +123,7 @@
|
|||||||
resource: e.data?.id === 'fakeNode' ? [] : [moduleTag],
|
resource: e.data?.id === 'fakeNode' ? [] : [moduleTag],
|
||||||
expandState: e.level === 1 ? 'expand' : 'collapse',
|
expandState: e.level === 1 ? 'expand' : 'collapse',
|
||||||
count: props.modulesCount[e.id],
|
count: props.modulesCount[e.id],
|
||||||
|
isNew: false,
|
||||||
},
|
},
|
||||||
children:
|
children:
|
||||||
props.modulesCount[e.id] > 0 && !e.children?.length
|
props.modulesCount[e.id] > 0 && !e.children?.length
|
||||||
@ -108,6 +133,7 @@
|
|||||||
id: 'fakeNode',
|
id: 'fakeNode',
|
||||||
text: 'fakeNode',
|
text: 'fakeNode',
|
||||||
resource: ['fakeNode'],
|
resource: ['fakeNode'],
|
||||||
|
isNew: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -140,11 +166,19 @@
|
|||||||
projectId: appStore.currentProjectId,
|
projectId: appStore.currentProjectId,
|
||||||
moduleId: props.moduleId === 'all' ? '' : props.moduleId,
|
moduleId: props.moduleId === 'all' ? '' : props.moduleId,
|
||||||
});
|
});
|
||||||
importJson.value.root.children = res;
|
importJson.value.root.children = mapTree(res, (node) => {
|
||||||
|
return {
|
||||||
|
...node,
|
||||||
|
data: {
|
||||||
|
...node.data,
|
||||||
|
isNew: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
importJson.value.root.data = {
|
importJson.value.root.data = {
|
||||||
id: props.moduleId === 'all' ? '' : props.moduleId,
|
id: props.moduleId === 'all' ? '' : props.moduleId,
|
||||||
text: props.moduleName,
|
text: props.moduleName,
|
||||||
resource: [t('common.module')],
|
resource: [moduleTag],
|
||||||
};
|
};
|
||||||
window.minder.importJson(importJson.value);
|
window.minder.importJson(importJson.value);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -163,15 +197,83 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
async function handleMinderSave(data: any) {
|
const baseInfoRef = ref<InstanceType<typeof baseInfo>>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析用例节点信息
|
||||||
|
* @param node 用例节点
|
||||||
|
*/
|
||||||
|
function getCaseNodeInfo(node: MinderJsonNode) {
|
||||||
|
let textStep: MinderJsonNode | undefined;
|
||||||
|
let prerequisiteNode: MinderJsonNode | undefined;
|
||||||
|
let remarkNode: MinderJsonNode | undefined;
|
||||||
|
const stepNodes: MinderJsonNode[] = [];
|
||||||
|
node.children?.forEach((item) => {
|
||||||
|
if (item.data.resource?.includes(textTag)) {
|
||||||
|
textStep = item;
|
||||||
|
} else if (item.data.resource?.includes(stepTag)) {
|
||||||
|
stepNodes.push(item);
|
||||||
|
} else if (item.data.resource?.includes(prerequisiteTag)) {
|
||||||
|
prerequisiteNode = item;
|
||||||
|
} else if (item.data.resource?.includes(remarkTag)) {
|
||||||
|
remarkNode = item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const steps: FeatureCaseMinderStepItem[] = stepNodes.map((child, i) => {
|
||||||
|
return {
|
||||||
|
id: child.data.id,
|
||||||
|
num: i,
|
||||||
|
desc: child.data.text,
|
||||||
|
result: child.children?.[0].data.text || '',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
prerequisite: prerequisiteNode?.data.text || '',
|
||||||
|
caseEditType: steps.length > 0 ? 'STEP' : ('TEXT' as FeatureCaseMinderEditType),
|
||||||
|
steps,
|
||||||
|
textDescription: textStep?.data.text || '',
|
||||||
|
expectedResult: textStep?.children?.[0]?.data.text || '',
|
||||||
|
description: remarkNode?.data.text || '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成脑图保存的入参
|
||||||
|
*/
|
||||||
|
function makeMinderParams(): FeatureCaseMinderUpdateParams {
|
||||||
|
const fullJson: MinderJson = window.minder.exportJson();
|
||||||
|
filterTree(fullJson.root.children, (node) => {
|
||||||
|
if (node.data.isNew !== false || node.data.changed === true) {
|
||||||
|
if (node.data.resource?.includes(moduleTag)) {
|
||||||
|
tempMinderParams.value.updateModuleList.push({
|
||||||
|
id: node.data.id,
|
||||||
|
name: node.data.text,
|
||||||
|
parentId: node.parent?.data.id || '',
|
||||||
|
type: node.data.isNew ? 'ADD' : 'UPDATE',
|
||||||
|
});
|
||||||
|
} else if (node.data.resource?.includes(caseTag)) {
|
||||||
|
const caseNodeInfo = getCaseNodeInfo(node as MinderJsonNode);
|
||||||
|
tempMinderParams.value.updateCaseList.push({
|
||||||
|
id: node.data.id,
|
||||||
|
name: node.data.text,
|
||||||
|
moduleId: node.parent?.data.id || '',
|
||||||
|
type: node.data.isNew ? 'ADD' : 'UPDATE',
|
||||||
|
templateId: templateId.value,
|
||||||
|
tags: node.data.resource || [],
|
||||||
|
customFields: baseInfoRef.value?.makeParams().customFields || [],
|
||||||
|
...caseNodeInfo,
|
||||||
|
});
|
||||||
|
return false; // 用例的子孙节点已经处理过,跳过
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return tempMinderParams.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleMinderSave() {
|
||||||
try {
|
try {
|
||||||
await saveCaseMinder({
|
await saveCaseMinder(makeMinderParams());
|
||||||
projectId: appStore.currentProjectId,
|
|
||||||
versionId: '',
|
|
||||||
updateCaseList: data,
|
|
||||||
updateModuleList: [],
|
|
||||||
deleteResourceList: [],
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@ -196,21 +298,24 @@
|
|||||||
if (node.data?.resource?.some((e) => descTags.includes(e))) {
|
if (node.data?.resource?.some((e) => descTags.includes(e))) {
|
||||||
// 选中节点属于描述节点,可替换为除自身外的描述标签
|
// 选中节点属于描述节点,可替换为除自身外的描述标签
|
||||||
if (
|
if (
|
||||||
node.data.resource.includes(t('ms.minders.stepDesc')) &&
|
node.data.resource.includes(stepTag) &&
|
||||||
(node.parent?.children?.filter((e) => e.data?.resource?.includes(t('ms.minders.stepDesc'))) || []).length > 1
|
(node.parent?.children?.filter((e) => e.data?.resource?.includes(stepTag)) || []).length > 1
|
||||||
) {
|
) {
|
||||||
// 如果当前节点是步骤描述,则需要判断是否有其他步骤描述节点,如果有,则不可替换为文本描述
|
// 如果当前节点是步骤描述,则需要判断是否有其他步骤描述节点,如果有,则不可替换为文本描述
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return descTags.filter((tag) => !node.data?.resource?.includes(tag));
|
return descTags.filter((tag) => !node.data?.resource?.includes(tag));
|
||||||
}
|
}
|
||||||
|
if ((!node.data?.resource || node.data.resource.length === 0) && node.parent?.data?.resource?.includes(caseTag)) {
|
||||||
|
// 选中节点无标签,且父节点为用例节点,可替换用例下级标签
|
||||||
|
return caseChildTags;
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
(!node.data?.resource || node.data.resource.length === 0) &&
|
(!node.data?.resource || node.data.resource.length === 0) &&
|
||||||
(!node.parent?.data?.resource ||
|
(!node.parent?.data?.resource ||
|
||||||
node.parent?.data?.resource.length === 0 ||
|
node.parent?.data?.resource.length === 0 ||
|
||||||
node.parent?.data?.resource?.some((e) => topTags.includes(e)))
|
node.parent?.data?.resource?.some((e) => topTags.includes(e)))
|
||||||
) {
|
) {
|
||||||
// 选中节点无标签,且父节点为顶级节点,可替换为顶级标签
|
|
||||||
// 如果选中节点子级含有用例节点或模块节点,则不可将选中节点标记为用例
|
// 如果选中节点子级含有用例节点或模块节点,则不可将选中节点标记为用例
|
||||||
return node.children &&
|
return node.children &&
|
||||||
(node.children.some((e) => e.data?.resource?.includes(caseTag)) ||
|
(node.children.some((e) => e.data?.resource?.includes(caseTag)) ||
|
||||||
@ -242,24 +347,14 @@
|
|||||||
parent: node,
|
parent: node,
|
||||||
data: {
|
data: {
|
||||||
id: getGenerateId(),
|
id: getGenerateId(),
|
||||||
text: t('ms.minders.precondition'),
|
text: prerequisiteTag,
|
||||||
resource: [t('ms.minders.precondition')],
|
resource: [prerequisiteTag],
|
||||||
expandState: 'expand',
|
expandState: 'expand',
|
||||||
|
isNew: true,
|
||||||
},
|
},
|
||||||
children: [],
|
children: [],
|
||||||
};
|
};
|
||||||
const sibling = {
|
|
||||||
parent: child,
|
|
||||||
data: {
|
|
||||||
id: getGenerateId(),
|
|
||||||
text: '',
|
|
||||||
resource: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
execInert(type, child.data);
|
execInert(type, child.data);
|
||||||
nextTick(() => {
|
|
||||||
execInert('AppendChildNode', sibling.data);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -272,38 +367,15 @@
|
|||||||
parent: node,
|
parent: node,
|
||||||
data: {
|
data: {
|
||||||
id: getGenerateId(),
|
id: getGenerateId(),
|
||||||
text: t('common.remark'),
|
text: remarkTag,
|
||||||
resource: [t('common.remark')],
|
resource: [remarkTag],
|
||||||
|
isNew: true,
|
||||||
},
|
},
|
||||||
children: [],
|
children: [],
|
||||||
};
|
};
|
||||||
execInert(type, child.data);
|
execInert(type, child.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// function insertTextDesc(node: MinderJsonNode, type: string) {
|
|
||||||
// const child = {
|
|
||||||
// parent: node,
|
|
||||||
// data: {
|
|
||||||
// id: getGenerateId(),
|
|
||||||
// text: t('ms.minders.textDesc'),
|
|
||||||
// resource: [t('ms.minders.textDesc')],
|
|
||||||
// },
|
|
||||||
// children: [],
|
|
||||||
// };
|
|
||||||
// const sibling = {
|
|
||||||
// parent: child,
|
|
||||||
// data: {
|
|
||||||
// id: getGenerateId(),
|
|
||||||
// text: t('ms.minders.stepExpect'),
|
|
||||||
// resource: [t('ms.minders.stepExpect')],
|
|
||||||
// },
|
|
||||||
// };
|
|
||||||
// execInert(type, {
|
|
||||||
// ...child,
|
|
||||||
// children: [sibling],
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插入步骤描述
|
* 插入步骤描述
|
||||||
* @param node 目标节点
|
* @param node 目标节点
|
||||||
@ -316,6 +388,7 @@
|
|||||||
id: getGenerateId(),
|
id: getGenerateId(),
|
||||||
text: t('ms.minders.stepDesc'),
|
text: t('ms.minders.stepDesc'),
|
||||||
resource: [t('ms.minders.stepDesc')],
|
resource: [t('ms.minders.stepDesc')],
|
||||||
|
isNew: true,
|
||||||
},
|
},
|
||||||
children: [],
|
children: [],
|
||||||
};
|
};
|
||||||
@ -325,6 +398,7 @@
|
|||||||
id: getGenerateId(),
|
id: getGenerateId(),
|
||||||
text: t('ms.minders.stepExpect'),
|
text: t('ms.minders.stepExpect'),
|
||||||
resource: [t('ms.minders.stepExpect')],
|
resource: [t('ms.minders.stepExpect')],
|
||||||
|
isNew: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
execInert(type, child.data);
|
execInert(type, child.data);
|
||||||
@ -345,6 +419,7 @@
|
|||||||
id: getGenerateId(),
|
id: getGenerateId(),
|
||||||
text: t('ms.minders.stepExpect'),
|
text: t('ms.minders.stepExpect'),
|
||||||
resource: [t('ms.minders.stepExpect')],
|
resource: [t('ms.minders.stepExpect')],
|
||||||
|
isNew: true,
|
||||||
},
|
},
|
||||||
children: [],
|
children: [],
|
||||||
};
|
};
|
||||||
@ -373,11 +448,11 @@
|
|||||||
let hasRemark = false;
|
let hasRemark = false;
|
||||||
for (let i = 0; i < node.children.length; i++) {
|
for (let i = 0; i < node.children.length; i++) {
|
||||||
const child = node.children[i];
|
const child = node.children[i];
|
||||||
if (child.data?.resource?.includes(t('ms.minders.precondition'))) {
|
if (child.data?.resource?.includes(prerequisiteTag)) {
|
||||||
hasPreCondition = true;
|
hasPreCondition = true;
|
||||||
} else if (child.data?.resource?.includes(t('ms.minders.textDesc'))) {
|
} else if (child.data?.resource?.includes(textTag)) {
|
||||||
hasTextDesc = true;
|
hasTextDesc = true;
|
||||||
} else if (child.data?.resource?.includes(t('common.remark'))) {
|
} else if (child.data?.resource?.includes(remarkTag)) {
|
||||||
hasRemark = true;
|
hasRemark = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -393,20 +468,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
(node.data?.resource?.includes(t('ms.minders.stepDesc')) ||
|
(node.data?.resource?.includes(stepTag) || node.data?.resource?.includes(textTag)) &&
|
||||||
node.data?.resource?.includes(t('ms.minders.textDesc'))) &&
|
|
||||||
(!node.children || node.children.length === 0)
|
(!node.children || node.children.length === 0)
|
||||||
) {
|
) {
|
||||||
// 当前节点是步骤描述或文本描述,且没有子节点,则默认添加一个预期结果
|
// 当前节点是步骤描述或文本描述,且没有子节点,则默认添加一个预期结果
|
||||||
insertExpect(node, 'AppendChildNode');
|
insertExpect(node, 'AppendChildNode');
|
||||||
} else if (node.data?.resource?.includes(t('ms.minders.precondition'))) {
|
} else if (node.data?.resource?.includes(prerequisiteTag) && (!node.children || node.children.length === 0)) {
|
||||||
// 当前节点是前置条件,则默认添加一个文本节点
|
// 当前节点是前置条件,则默认添加一个文本节点
|
||||||
execInert('AppendChildNode');
|
execInert('AppendChildNode');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'AppendParentNode':
|
|
||||||
execInert('AppendParentNode');
|
|
||||||
break;
|
|
||||||
case 'AppendSiblingNode':
|
case 'AppendSiblingNode':
|
||||||
if (node.parent?.data?.resource?.includes(caseTag) && node.parent?.children) {
|
if (node.parent?.data?.resource?.includes(caseTag) && node.parent?.children) {
|
||||||
// 当前节点的父节点是用例
|
// 当前节点的父节点是用例
|
||||||
@ -415,11 +486,11 @@
|
|||||||
let hasRemark = false;
|
let hasRemark = false;
|
||||||
for (let i = 0; i < node.parent.children.length; i++) {
|
for (let i = 0; i < node.parent.children.length; i++) {
|
||||||
const sibling = node.parent.children[i];
|
const sibling = node.parent.children[i];
|
||||||
if (sibling.data?.resource?.includes(t('ms.minders.precondition'))) {
|
if (sibling.data?.resource?.includes(prerequisiteTag)) {
|
||||||
hasPreCondition = true;
|
hasPreCondition = true;
|
||||||
} else if (sibling.data?.resource?.includes(t('common.remark'))) {
|
} else if (sibling.data?.resource?.includes(remarkTag)) {
|
||||||
hasRemark = true;
|
hasRemark = true;
|
||||||
} else if (sibling.data?.resource?.includes(t('ms.minders.textDesc'))) {
|
} else if (sibling.data?.resource?.includes(textTag)) {
|
||||||
hasTextDesc = true;
|
hasTextDesc = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -460,10 +531,39 @@
|
|||||||
*/
|
*/
|
||||||
function afterTagEdit(node: MinderJsonNode, tag: string) {
|
function afterTagEdit(node: MinderJsonNode, tag: string) {
|
||||||
if (tag === moduleTag && node.data) {
|
if (tag === moduleTag && node.data) {
|
||||||
|
// 排除是从用例节点切换到模块节点的数据
|
||||||
|
tempMinderParams.value.updateCaseList = tempMinderParams.value.updateCaseList.filter(
|
||||||
|
(e) => e.id !== node.data.id
|
||||||
|
);
|
||||||
|
// tempMinderParams.value.updateModuleList.push({
|
||||||
|
// id: node.data.id,
|
||||||
|
// name: node.data.text,
|
||||||
|
// type: 'ADD',
|
||||||
|
// parentId: node.parent?.data.id || '',
|
||||||
|
// });
|
||||||
window.minder.execCommand('priority');
|
window.minder.execCommand('priority');
|
||||||
|
} else if (node.data.resource?.includes(caseTag)) {
|
||||||
|
// 排除是从模块节点切换到用例节点的数据
|
||||||
|
tempMinderParams.value.updateModuleList = tempMinderParams.value.updateModuleList.filter(
|
||||||
|
(e) => e.id !== node.data.id
|
||||||
|
);
|
||||||
|
// tempMinderParams.value.updateCaseList.push({
|
||||||
|
// id: node.data.id,
|
||||||
|
// name: node.data.text,
|
||||||
|
// moduleId: node.parent?.data.id || '',
|
||||||
|
// type: 'ADD',
|
||||||
|
// templateId: templateId.value,
|
||||||
|
// prerequisite: '',
|
||||||
|
// caseEditType: 'STEP',
|
||||||
|
// steps: [],
|
||||||
|
// textDescription: '',
|
||||||
|
// expectedResult: '',
|
||||||
|
// description: '',
|
||||||
|
// tags: [],
|
||||||
|
// customFields: [],
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseInfoLoading = ref(false);
|
const baseInfoLoading = ref(false);
|
||||||
|
|
||||||
const formRules = ref<FormItem[]>([]);
|
const formRules = ref<FormItem[]>([]);
|
||||||
@ -562,6 +662,24 @@
|
|||||||
resetExtractInfo();
|
resetExtractInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleContentChange(node: MinderJsonNode) {
|
||||||
|
const { resource } = node.data;
|
||||||
|
// 用例下的子节点更改,触发用例更改
|
||||||
|
if (
|
||||||
|
resource?.includes(prerequisiteTag) ||
|
||||||
|
resource?.includes(stepTag) ||
|
||||||
|
resource?.includes(textTag) ||
|
||||||
|
resource?.includes(remarkTag)
|
||||||
|
) {
|
||||||
|
if (node.parent) {
|
||||||
|
node.parent.data.changed = true;
|
||||||
|
}
|
||||||
|
} else if (node.parent?.parent?.data.resource?.includes(caseTag)) {
|
||||||
|
// 用例下子节点的子节点更改,触发用例更改
|
||||||
|
node.parent.parent.data.changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理脑图节点激活/点击
|
* 处理脑图节点激活/点击
|
||||||
* @param node 被激活/点击的节点
|
* @param node 被激活/点击的节点
|
||||||
@ -594,15 +712,33 @@
|
|||||||
// TODO:递归渲染存在的子节点
|
// TODO:递归渲染存在的子节点
|
||||||
res.forEach((e) => {
|
res.forEach((e) => {
|
||||||
// 用例节点
|
// 用例节点
|
||||||
const child = window.minder.createNode(e.data, node);
|
const child = window.minder.createNode(
|
||||||
|
{
|
||||||
|
...e.data,
|
||||||
|
isNew: false,
|
||||||
|
},
|
||||||
|
node
|
||||||
|
);
|
||||||
child.render();
|
child.render();
|
||||||
e.children?.forEach((item) => {
|
e.children?.forEach((item) => {
|
||||||
// 前置/步骤/备注节点
|
// 前置/步骤/备注节点
|
||||||
const grandChild = window.minder.createNode(item.data, child);
|
const grandChild = window.minder.createNode(
|
||||||
|
{
|
||||||
|
...item.data,
|
||||||
|
isNew: false,
|
||||||
|
},
|
||||||
|
child
|
||||||
|
);
|
||||||
grandChild.render();
|
grandChild.render();
|
||||||
item.children?.forEach((subItem) => {
|
item.children?.forEach((subItem) => {
|
||||||
// 预期结果节点
|
// 预期结果节点
|
||||||
const greatGrandChild = window.minder.createNode(subItem.data, grandChild);
|
const greatGrandChild = window.minder.createNode(
|
||||||
|
{
|
||||||
|
...subItem.data,
|
||||||
|
isNew: false,
|
||||||
|
},
|
||||||
|
grandChild
|
||||||
|
);
|
||||||
greatGrandChild.render();
|
greatGrandChild.render();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -626,6 +762,37 @@
|
|||||||
resetExtractInfo();
|
resetExtractInfo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理脑图节点操作
|
||||||
|
* @param event 脑图事件对象
|
||||||
|
*/
|
||||||
|
function handleAction(event: MinderEvent) {
|
||||||
|
const { node, name } = event;
|
||||||
|
if (node) {
|
||||||
|
switch (name) {
|
||||||
|
case MinderEventName.DELETE_NODE:
|
||||||
|
tempMinderParams.value.deleteResourceList.push({
|
||||||
|
id: node.data.id,
|
||||||
|
type: node.data?.resource?.[0] || moduleTag,
|
||||||
|
});
|
||||||
|
if (node.data?.resource?.includes(caseTag)) {
|
||||||
|
// 删除用例节点
|
||||||
|
tempMinderParams.value.updateCaseList = tempMinderParams.value.updateCaseList.filter(
|
||||||
|
(e) => e.id !== node.data.id
|
||||||
|
);
|
||||||
|
} else if (node.data?.resource?.includes(moduleTag)) {
|
||||||
|
// 删除模块节点
|
||||||
|
tempMinderParams.value.updateModuleList = tempMinderParams.value.updateModuleList.filter(
|
||||||
|
(e) => e.id !== node.data.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
<style lang="less" scoped></style>
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
import { debounce } from 'lodash-es';
|
||||||
|
|
||||||
|
import useMinderStore from '@/store/modules/components/minder-editor/index';
|
||||||
|
import type { MinderEvent } from '@/store/modules/components/minder-editor/types';
|
||||||
|
|
||||||
|
import type { MinderJsonNode } from '../props';
|
||||||
|
|
||||||
|
export interface UseEventListenerProps {
|
||||||
|
handleContentChange?: (node: MinderJsonNode) => void;
|
||||||
|
handleSelectionChange?: (node: MinderJsonNode) => void;
|
||||||
|
handleMinderEvent?: (event: MinderEvent) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function useEventListener(listener: UseEventListenerProps) {
|
||||||
|
const { minder } = window;
|
||||||
|
const minderStore = useMinderStore();
|
||||||
|
|
||||||
|
// 监听脑图节点内容变化
|
||||||
|
minder.on('contentchange', () => {
|
||||||
|
const node: MinderJsonNode = minder.getSelectedNode();
|
||||||
|
if (listener.handleContentChange) {
|
||||||
|
listener.handleContentChange(node);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听脑图选中节点变化
|
||||||
|
minder.on(
|
||||||
|
'selectionchange',
|
||||||
|
debounce(() => {
|
||||||
|
const node: MinderJsonNode = minder.getSelectedNode();
|
||||||
|
if (listener.handleSelectionChange) {
|
||||||
|
listener.handleSelectionChange(node);
|
||||||
|
}
|
||||||
|
}, 300)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 监听脑图自定义事件
|
||||||
|
watch(
|
||||||
|
() => minderStore.event.timestamp,
|
||||||
|
() => {
|
||||||
|
if (listener.handleMinderEvent) {
|
||||||
|
listener.handleMinderEvent(minderStore.event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
export default function useShortCut() {}
|
@ -19,12 +19,6 @@
|
|||||||
<div class="ml-[4px] text-[var(--color-text-4)]">( / )</div>
|
<div class="ml-[4px] text-[var(--color-text-4)]">( / )</div>
|
||||||
</div>
|
</div>
|
||||||
</a-doption>
|
</a-doption>
|
||||||
<a-doption value="insetParent">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<div>{{ t('minder.hotboxMenu.insetParent') }}</div>
|
|
||||||
<div class="ml-[4px] text-[var(--color-text-4)]">(Shift + Tab)</div>
|
|
||||||
</div>
|
|
||||||
</a-doption>
|
|
||||||
<a-doption value="insetSon">
|
<a-doption value="insetSon">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div>{{ t('minder.hotboxMenu.insetSon') }}</div>
|
<div>{{ t('minder.hotboxMenu.insetSon') }}</div>
|
||||||
@ -94,7 +88,15 @@
|
|||||||
|
|
||||||
import { MinderEventName } from '@/enums/minderEnum';
|
import { MinderEventName } from '@/enums/minderEnum';
|
||||||
|
|
||||||
import { editMenuProps, insertProps, mainEditorProps, MinderJsonNode, priorityProps, tagProps } from '../props';
|
import {
|
||||||
|
editMenuProps,
|
||||||
|
insertProps,
|
||||||
|
mainEditorProps,
|
||||||
|
MinderJson,
|
||||||
|
MinderJsonNode,
|
||||||
|
priorityProps,
|
||||||
|
tagProps,
|
||||||
|
} from '../props';
|
||||||
import Editor from '../script/editor';
|
import Editor from '../script/editor';
|
||||||
import { markChangeNode, markDeleteNode } from '../script/tool/utils';
|
import { markChangeNode, markDeleteNode } from '../script/tool/utils';
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
@ -102,11 +104,10 @@
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const props = defineProps({ ...editMenuProps, ...insertProps, ...mainEditorProps, ...tagProps, ...priorityProps });
|
const props = defineProps({ ...editMenuProps, ...insertProps, ...mainEditorProps, ...tagProps, ...priorityProps });
|
||||||
|
|
||||||
const emit = defineEmits({
|
const emit = defineEmits<{
|
||||||
afterMount: () => ({}),
|
(e: 'afterMount'): void;
|
||||||
save: (json) => json,
|
(e: 'save', json: MinderJson): void;
|
||||||
enterNode: (data) => data,
|
}>();
|
||||||
});
|
|
||||||
|
|
||||||
const minderStore = useMinderStore();
|
const minderStore = useMinderStore();
|
||||||
const mec: Ref<HTMLDivElement | null> = ref(null);
|
const mec: Ref<HTMLDivElement | null> = ref(null);
|
||||||
@ -192,7 +193,7 @@
|
|||||||
'appendsiblingnode',
|
'appendsiblingnode',
|
||||||
]);
|
]);
|
||||||
if (selectNodes && !notChangeCommands.has(env.commandName.toLocaleLowerCase())) {
|
if (selectNodes && !notChangeCommands.has(env.commandName.toLocaleLowerCase())) {
|
||||||
selectNodes.forEach((node: any) => {
|
selectNodes.forEach((node: MinderJsonNode) => {
|
||||||
markChangeNode(node);
|
markChangeNode(node);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -233,6 +234,7 @@
|
|||||||
innerImportJson.value.data.expandState = 'expand';
|
innerImportJson.value.data.expandState = 'expand';
|
||||||
window.minder.importJson(innerImportJson.value);
|
window.minder.importJson(innerImportJson.value);
|
||||||
window.minder.execCommand('template', Object.keys(window.kityminder.Minder.getTemplateList())[minderStore.mold]);
|
window.minder.execCommand('template', Object.keys(window.kityminder.Minder.getTemplateList())[minderStore.mold]);
|
||||||
|
minderStore.dispatchEvent(MinderEventName.ENTER_NODE, undefined, undefined, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -280,27 +282,35 @@
|
|||||||
} else {
|
} else {
|
||||||
window.minder.execCommand('Collapse');
|
window.minder.execCommand('Collapse');
|
||||||
}
|
}
|
||||||
|
minderStore.dispatchEvent(MinderEventName.EXPAND, undefined, undefined, selectedNode);
|
||||||
break;
|
break;
|
||||||
case 'insetParent':
|
case 'insetParent':
|
||||||
execInsertCommand('AppendParentNode');
|
execInsertCommand('AppendParentNode');
|
||||||
|
minderStore.dispatchEvent(MinderEventName.INSERT_PARENT, undefined, undefined, selectedNode);
|
||||||
break;
|
break;
|
||||||
case 'insetSon':
|
case 'insetSon':
|
||||||
execInsertCommand('AppendChildNode');
|
execInsertCommand('AppendChildNode');
|
||||||
|
minderStore.dispatchEvent(MinderEventName.INSERT_CHILD, undefined, undefined, selectedNode);
|
||||||
break;
|
break;
|
||||||
case 'insetBrother':
|
case 'insetBrother':
|
||||||
execInsertCommand('AppendSiblingNode');
|
execInsertCommand('AppendSiblingNode');
|
||||||
|
minderStore.dispatchEvent(MinderEventName.INSERT_SIBLING, undefined, undefined, selectedNode);
|
||||||
break;
|
break;
|
||||||
case 'copy':
|
case 'copy':
|
||||||
window.minder.execCommand('Copy');
|
window.minder.execCommand('Copy');
|
||||||
|
minderStore.dispatchEvent(MinderEventName.COPY_NODE, undefined, undefined, selectedNode);
|
||||||
break;
|
break;
|
||||||
case 'cut':
|
case 'cut':
|
||||||
window.minder.execCommand('Cut');
|
window.minder.execCommand('Cut');
|
||||||
|
minderStore.dispatchEvent(MinderEventName.CUT_NODE, undefined, undefined, selectedNode);
|
||||||
break;
|
break;
|
||||||
case 'paste':
|
case 'paste':
|
||||||
window.minder.execCommand('Paste');
|
window.minder.execCommand('Paste');
|
||||||
|
minderStore.dispatchEvent(MinderEventName.PASTE_NODE, undefined, undefined, selectedNode);
|
||||||
break;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
window.minder.execCommand('RemoveNode');
|
window.minder.execCommand('RemoveNode');
|
||||||
|
minderStore.dispatchEvent(MinderEventName.DELETE_NODE, undefined, undefined, selectedNode);
|
||||||
break;
|
break;
|
||||||
case 'enterNode':
|
case 'enterNode':
|
||||||
switchNode(selectedNode.data);
|
switchNode(selectedNode.data);
|
||||||
|
@ -15,10 +15,15 @@
|
|||||||
<script lang="ts" name="TagBox" setup>
|
<script lang="ts" name="TagBox" setup>
|
||||||
import { nextTick, onMounted, reactive, ref } from 'vue';
|
import { nextTick, onMounted, reactive, ref } from 'vue';
|
||||||
|
|
||||||
|
import useMinderStore from '@/store/modules/components/minder-editor';
|
||||||
|
|
||||||
|
import { MinderEventName } from '@/enums/minderEnum';
|
||||||
|
|
||||||
import { MinderJsonNode, tagProps } from '../../props';
|
import { MinderJsonNode, tagProps } from '../../props';
|
||||||
import { isDisableNode, isTagEnable } from '../../script/tool/utils';
|
import { isDisableNode, isTagEnable } from '../../script/tool/utils';
|
||||||
|
|
||||||
const props = defineProps(tagProps);
|
const props = defineProps(tagProps);
|
||||||
|
const minderStore = useMinderStore();
|
||||||
|
|
||||||
let minder = reactive<any>({});
|
let minder = reactive<any>({});
|
||||||
const commandDisabled = ref(true);
|
const commandDisabled = ref(true);
|
||||||
@ -94,6 +99,7 @@
|
|||||||
}
|
}
|
||||||
window.minder.execCommand('resource', origin);
|
window.minder.execCommand('resource', origin);
|
||||||
const node: MinderJsonNode = minder.getSelectedNode();
|
const node: MinderJsonNode = minder.getSelectedNode();
|
||||||
|
minderStore.dispatchEvent(MinderEventName.SET_TAG, undefined, undefined, node);
|
||||||
if (props.replaceableTags) {
|
if (props.replaceableTags) {
|
||||||
tagList.value = props.replaceableTags(node);
|
tagList.value = props.replaceableTags(node);
|
||||||
}
|
}
|
||||||
|
@ -63,14 +63,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" name="minderEditor" setup>
|
<script lang="ts" name="minderEditor" setup>
|
||||||
import { debounce } from 'lodash-es';
|
|
||||||
|
|
||||||
import MsTab from '@/components/pure/ms-tab/index.vue';
|
import MsTab from '@/components/pure/ms-tab/index.vue';
|
||||||
import minderHeader from './main/header.vue';
|
import minderHeader from './main/header.vue';
|
||||||
import mainEditor from './main/mainEditor.vue';
|
import mainEditor from './main/mainEditor.vue';
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import { MinderEvent } from '@/store/modules/components/minder-editor/types';
|
||||||
|
|
||||||
|
import useEventListener from './hooks/useEventListener';
|
||||||
import {
|
import {
|
||||||
delProps,
|
delProps,
|
||||||
editMenuProps,
|
editMenuProps,
|
||||||
@ -88,8 +88,10 @@
|
|||||||
(e: 'moldChange', data: number): void;
|
(e: 'moldChange', data: number): void;
|
||||||
(e: 'save', data: Record<string, any>): void;
|
(e: 'save', data: Record<string, any>): void;
|
||||||
(e: 'afterMount'): void;
|
(e: 'afterMount'): void;
|
||||||
(e: 'enterNode', data: any): void;
|
(e: 'enterNode', data: MinderJsonNode): void;
|
||||||
(e: 'nodeSelect', data: any): void;
|
(e: 'nodeSelect', data: MinderJsonNode): void;
|
||||||
|
(e: 'contentChange', data: MinderJsonNode): void;
|
||||||
|
(e: 'action', event: MinderEvent): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -133,18 +135,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
nextTick(() => {
|
useEventListener({
|
||||||
if (window.minder.on) {
|
handleSelectionChange: () => {
|
||||||
window.minder.on(
|
const selectedNode: MinderJsonNode = window.minder.getSelectedNode();
|
||||||
'selectionchange',
|
if (Object.keys(window.minder).length > 0 && selectedNode) {
|
||||||
debounce(() => {
|
emit('nodeSelect', selectedNode);
|
||||||
const selectedNode: MinderJsonNode = window.minder.getSelectedNode();
|
}
|
||||||
if (Object.keys(window.minder).length > 0 && selectedNode) {
|
},
|
||||||
emit('nodeSelect', selectedNode);
|
handleContentChange: (node: MinderJsonNode) => {
|
||||||
}
|
emit('contentChange', node);
|
||||||
}, 300)
|
},
|
||||||
);
|
handleMinderEvent: (event) => {
|
||||||
}
|
emit('action', event);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -16,6 +16,8 @@ export interface MinderJsonNodeData {
|
|||||||
expandState?: 'collapse' | 'expand';
|
expandState?: 'collapse' | 'expand';
|
||||||
priority?: number;
|
priority?: number;
|
||||||
// 前端渲染字段
|
// 前端渲染字段
|
||||||
|
isNew?: boolean; // 是否脑图新增节点,需要在初始化脑图数据时标记已存在节点为 false 以区分是否新增节点
|
||||||
|
changed?: boolean; // 脑图节点是否发生过变化
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
export interface MinderJsonNode {
|
export interface MinderJsonNode {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import type { MinderJsonNode } from '../../props';
|
||||||
|
|
||||||
export function isDisableNode(minder: any) {
|
export function isDisableNode(minder: any) {
|
||||||
let node;
|
let node;
|
||||||
if (minder && minder.getSelectedNode) {
|
if (minder && minder.getSelectedNode) {
|
||||||
@ -20,7 +22,7 @@ export function isDeleteDisableNode(minder: any) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isTagEnableNode(node: any) {
|
export function isTagEnableNode(node: MinderJsonNode) {
|
||||||
if (node && (node.data.tagEnable === true || node.data.allowDisabledTag === true)) {
|
if (node && (node.data.tagEnable === true || node.data.allowDisabledTag === true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -38,19 +40,13 @@ export function isTagEnable(minder: any) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function markChangeNode(node: any) {
|
export function markChangeNode(node: MinderJsonNode) {
|
||||||
if (node && node.data) {
|
if (node.data) {
|
||||||
// 修改的该节点标记为 contextChanged
|
node.data.changed = true;
|
||||||
node.data.contextChanged = true;
|
|
||||||
while (node) {
|
|
||||||
// 该路径上的节点都标记为 changed
|
|
||||||
node.data.changed = true;
|
|
||||||
node = node.parent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function markDelNode(node: any, deleteChild: any) {
|
function markDelNode(node: MinderJsonNode, deleteChild: any) {
|
||||||
deleteChild.push(node.data);
|
deleteChild.push(node.data);
|
||||||
if (node.children) {
|
if (node.children) {
|
||||||
node.children.forEach((child: any) => {
|
node.children.forEach((child: any) => {
|
||||||
@ -63,7 +59,7 @@ function markDelNode(node: any, deleteChild: any) {
|
|||||||
export function markDeleteNode(minder: any) {
|
export function markDeleteNode(minder: any) {
|
||||||
if (minder) {
|
if (minder) {
|
||||||
const nodes = minder.getSelectedNodes();
|
const nodes = minder.getSelectedNodes();
|
||||||
nodes.forEach((node: any) => {
|
nodes.forEach((node: MinderJsonNode) => {
|
||||||
if (node && node.parent) {
|
if (node && node.parent) {
|
||||||
const pData = node.parent.data;
|
const pData = node.parent.data;
|
||||||
if (!pData.deleteChild) {
|
if (!pData.deleteChild) {
|
||||||
@ -118,7 +114,7 @@ export function resetNodes(nodes: any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isDisableForNode(node: any) {
|
export function isDisableForNode(node: MinderJsonNode) {
|
||||||
if (node && node.data.disable === true) {
|
if (node && node.data.disable === true) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,14 @@ export enum MinderEventName {
|
|||||||
'DELETE_NODE' = 'DELETE_NODE', // 删除节点
|
'DELETE_NODE' = 'DELETE_NODE', // 删除节点
|
||||||
'HOTBOX' = 'HOTBOX', // 热键菜单
|
'HOTBOX' = 'HOTBOX', // 热键菜单
|
||||||
'ENTER_NODE' = 'ENTER_NODE', // 进入节点
|
'ENTER_NODE' = 'ENTER_NODE', // 进入节点
|
||||||
|
'EXPAND' = 'EXPAND', // 展开节点
|
||||||
|
'INSERT_PARENT' = 'INSERT_PARENT', // 插入父节点
|
||||||
|
'INSERT_CHILD' = 'INSERT_CHILD', // 插入子节点
|
||||||
|
'INSERT_SIBLING' = 'INSERT_SIBLING', // 插入同级节点
|
||||||
|
'COPY_NODE' = 'COPY_NODE', // 复制节点
|
||||||
|
'PASTE_NODE' = 'PASTE_NODE', // 粘贴节点
|
||||||
|
'CUT_NODE' = 'CUT_NODE', // 剪切节点
|
||||||
|
'SET_TAG' = 'SET_TAG', // 设置节点标签
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {};
|
export default {};
|
||||||
|
@ -365,7 +365,7 @@ export interface ContentTabsMap {
|
|||||||
backupTabList: TabItemType[];
|
backupTabList: TabItemType[];
|
||||||
}
|
}
|
||||||
// 脑图删除的模块/用例的集合
|
// 脑图删除的模块/用例的集合
|
||||||
export interface FeatureCaseMinderDeleteResourceList {
|
export interface FeatureCaseMinderDeleteResourceItem {
|
||||||
id: string;
|
id: string;
|
||||||
type: string;
|
type: string;
|
||||||
}
|
}
|
||||||
@ -374,7 +374,7 @@ export type FeatureCaseMinderActionType = 'ADD' | 'UPDATE';
|
|||||||
// 脑图用例编辑模式
|
// 脑图用例编辑模式
|
||||||
export type FeatureCaseMinderEditType = 'STEP' | 'TEXT';
|
export type FeatureCaseMinderEditType = 'STEP' | 'TEXT';
|
||||||
// 脑图新增/修改的模块集合(只记录操作的节点,节点下的子节点不需要记录)
|
// 脑图新增/修改的模块集合(只记录操作的节点,节点下的子节点不需要记录)
|
||||||
export interface FeatureCaseMinderUpdateModuleList {
|
export interface FeatureCaseMinderUpdateModuleItem {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
parentId: string;
|
parentId: string;
|
||||||
@ -395,7 +395,7 @@ export interface FeatureCaseMinderStepItem {
|
|||||||
result?: string;
|
result?: string;
|
||||||
}
|
}
|
||||||
// 脑图新增/修改的用例对象集合
|
// 脑图新增/修改的用例对象集合
|
||||||
export interface FeatureCaseMinderUpdateCaseList {
|
export interface FeatureCaseMinderUpdateCaseItem {
|
||||||
id: string; // 用例id(新增的时候前端传UUid,更新的时候必填)
|
id: string; // 用例id(新增的时候前端传UUid,更新的时候必填)
|
||||||
templateId: string; // 模板id
|
templateId: string; // 模板id
|
||||||
type: FeatureCaseMinderActionType;
|
type: FeatureCaseMinderActionType;
|
||||||
@ -403,7 +403,7 @@ export interface FeatureCaseMinderUpdateCaseList {
|
|||||||
moduleId: string;
|
moduleId: string;
|
||||||
moveMode?: MoveMode; // 移动方式(节点移动或新增时需要)
|
moveMode?: MoveMode; // 移动方式(节点移动或新增时需要)
|
||||||
targetId?: string;
|
targetId?: string;
|
||||||
prerequisite: string;
|
prerequisite: string; // 前置条件
|
||||||
caseEditType: FeatureCaseMinderEditType;
|
caseEditType: FeatureCaseMinderEditType;
|
||||||
steps: FeatureCaseMinderStepItem[];
|
steps: FeatureCaseMinderStepItem[];
|
||||||
textDescription: string; // 文本描述
|
textDescription: string; // 文本描述
|
||||||
@ -413,10 +413,10 @@ export interface FeatureCaseMinderUpdateCaseList {
|
|||||||
customFields: CustomField[];
|
customFields: CustomField[];
|
||||||
}
|
}
|
||||||
// 脑图
|
// 脑图
|
||||||
export interface FeatureCaseMinder {
|
export interface FeatureCaseMinderUpdateParams {
|
||||||
projectId: string;
|
projectId: string;
|
||||||
versionId?: string;
|
versionId?: string;
|
||||||
updateCaseList: FeatureCaseMinderUpdateCaseList[];
|
updateCaseList: FeatureCaseMinderUpdateCaseItem[];
|
||||||
updateModuleList: FeatureCaseMinderUpdateModuleList[];
|
updateModuleList: FeatureCaseMinderUpdateModuleItem[];
|
||||||
deleteResourceList: FeatureCaseMinderDeleteResourceList[];
|
deleteResourceList: FeatureCaseMinderDeleteResourceItem[];
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,14 @@
|
|||||||
@refresh="fetchData()"
|
@refresh="fetchData()"
|
||||||
>
|
>
|
||||||
<template #right>
|
<template #right>
|
||||||
<!-- <a-radio-group v-model:model-value="showType" type="button" size="small" class="list-show-type">
|
<a-radio-group v-model:model-value="showType" type="button" size="small" class="list-show-type">
|
||||||
<a-radio value="list" class="show-type-icon !m-[2px]">
|
<a-radio value="list" class="show-type-icon !m-[2px]">
|
||||||
<MsIcon :size="14" type="icon-icon_view-list_outlined" />
|
<MsIcon :size="14" type="icon-icon_view-list_outlined" />
|
||||||
</a-radio>
|
</a-radio>
|
||||||
<a-radio value="xMind" class="show-type-icon !m-[2px]">
|
<a-radio value="xMind" class="show-type-icon !m-[2px]">
|
||||||
<MsIcon :size="14" type="icon-icon_mindnote_outlined" />
|
<MsIcon :size="14" type="icon-icon_mindnote_outlined" />
|
||||||
</a-radio>
|
</a-radio>
|
||||||
</a-radio-group> -->
|
</a-radio-group>
|
||||||
</template>
|
</template>
|
||||||
</MsAdvanceFilter>
|
</MsAdvanceFilter>
|
||||||
<ms-base-table
|
<ms-base-table
|
||||||
|
@ -64,31 +64,29 @@
|
|||||||
width: 400px;
|
width: 400px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-qrcode {
|
.login-qrcode {
|
||||||
min-width: 480px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
|
min-width: 480px;
|
||||||
|
flex-direction: column;
|
||||||
.qrcode {
|
.qrcode {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: #fff;
|
background: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin: 0px 0 16px 0;
|
align-items: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
margin: 0 0 16px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-style: normal;
|
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
line-height: 26px;
|
line-height: 26px;
|
||||||
.ed-icon {
|
.ed-icon {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
|
@ -39,10 +39,10 @@
|
|||||||
state: 'fit2cloud-wecom-qr',
|
state: 'fit2cloud-wecom-qr',
|
||||||
redirect_type: WWLoginRedirectType.callback,
|
redirect_type: WWLoginRedirectType.callback,
|
||||||
},
|
},
|
||||||
onCheckWeComLogin({ isWeComLogin }) {
|
onCheckWeComLogin({ isWeComLogin }: any) {
|
||||||
console.log(isWeComLogin);
|
console.log(isWeComLogin);
|
||||||
},
|
},
|
||||||
async onLoginSuccess({ code }) {
|
async onLoginSuccess({ code }: any) {
|
||||||
const weComCallback = getWeComCallback(code);
|
const weComCallback = getWeComCallback(code);
|
||||||
userStore.qrCodeLogin(await weComCallback);
|
userStore.qrCodeLogin(await weComCallback);
|
||||||
Message.success(t('login.form.login.success'));
|
Message.success(t('login.form.login.success'));
|
||||||
@ -71,7 +71,7 @@
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onLoginFail(err) {
|
onLoginFail(err: any) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user