update:树形表格组件优化

This commit is contained in:
2025-12-02 14:47:10 +08:00
parent a8eb6200ed
commit aac5333174
3 changed files with 440 additions and 220 deletions

View File

@@ -21,19 +21,34 @@ export default defineConfigWithVueTs(
skipFormatting,
{
rules: {
'arrow-spacing': ['error', { 'before': true, 'after': true }],
'comma-dangle': ['error', { arrays: 'always-multiline', objects: 'always-multiline', imports: 'always-multiline', exports: 'always-multiline', functions: 'never' }],
'comma-spacing': ['error', { 'before': false, 'after': true }],
'indent': ['error', 2, { 'SwitchCase': 1 }],
'key-spacing': ['error', {
'beforeColon': false,
'afterColon': true,
}],
'keyword-spacing': ['error', {
'before': true,
'after': true,
}],
'no-multiple-empty-lines': ['error', { 'max': 1 }],
'arrow-spacing': ['error', { before: true, after: true }],
'comma-dangle': [
'error',
{
arrays: 'always-multiline',
objects: 'always-multiline',
imports: 'always-multiline',
exports: 'always-multiline',
functions: 'never',
},
],
'comma-spacing': ['error', { before: false, after: true }],
indent: ['error', 2, { SwitchCase: 1 }],
'key-spacing': [
'error',
{
beforeColon: false,
afterColon: true,
},
],
'keyword-spacing': [
'error',
{
before: true,
after: true,
},
],
'no-multiple-empty-lines': ['error', { max: 1 }],
'no-multi-spaces': 'error',
'no-trailing-spaces': 'error',
'object-curly-spacing': ['error', 'always'],
@@ -42,18 +57,22 @@ export default defineConfigWithVueTs(
{ blankLine: 'always', prev: 'import', next: '*' },
{ blankLine: 'never', prev: 'import', next: 'import' },
],
'quotes': ['error', 'single'],
'semi': ['error', 'always'],
quotes: ['error', 'single'],
semi: ['error', 'always'],
'space-before-blocks': ['error', 'always'],
'spaced-comment': ['error', 'always', {
'line': { 'markers': ['/'], 'exceptions': ['/'] },
'block': { 'exceptions': ['*'], 'balanced': true },
}],
'space-infix-ops': ['error', { 'int32Hint': false }],
'vue/html-closing-bracket-newline': ['error', { singleline: 'never', multiline: 'always' }],
'vue/html-indent': ['error', 2],
'spaced-comment': [
'error',
'always',
{
line: { markers: ['/'], exceptions: ['/'] },
block: { exceptions: ['*'], balanced: true },
},
],
'space-infix-ops': ['error', { int32Hint: false }],
'vue/html-closing-bracket-newline': 'off',
'vue/html-indent': 'off',
'vue/first-attribute-linebreak': ['error', { singleline: 'ignore', multiline: 'below' }],
'vue/max-attributes-per-line': ['error', { singleline: { max: 10 }, multiline: { max: 1 } }],
'vue/max-attributes-per-line': 'off',
'vue/multi-word-component-names': 'off',
'vue/mustache-interpolation-spacing': ['error', 'always'],
'vue/no-multi-spaces': 'error',

View File

@@ -11,7 +11,7 @@
@change="changeFun"
@load="searchLoadFun"
>
<template v-for="(name) in Object.keys($slots)" :key="name" #[name]="scope">
<template v-for="name in Object.keys($slots)" :key="name" #[name]="scope">
<slot :name="name" v-bind="scope" />
</template>
</TableSearch>
@@ -22,21 +22,21 @@
<div class="item">
<div class="btns">
<slot name="leftOptions" />
<el-tooltip v-if="exportApi" :content="$t('表格.导出')" placement="top" >
<el-tooltip v-if="exportApi" :content="$t('表格.导出')" placement="top">
<div v-if="exportApi" class="icon-btn" @click="exportFun">
<el-icon :size="18">
<Download />
</el-icon>
</div>
</el-tooltip>
<el-tooltip v-if="showImport" :content="$t('表格.导入')" placement="top" >
<el-tooltip v-if="showImport" :content="$t('表格.导入')" placement="top">
<div v-if="showImport" class="icon-btn" @click="formDiaVisible = true">
<el-icon :size="18">
<Upload />
</el-icon>
</div>
</el-tooltip>
<el-tooltip :content="$t('表格.列表字段设置')" placement="top" >
<el-tooltip :content="$t('表格.列表字段设置')" placement="top">
<div class="icon-btn" @click="formDiaVisible = true">
<el-icon :size="18">
<Setting />
@@ -54,8 +54,8 @@
height="100%"
v-bind="$attrs"
keepSource
:seq-config="{startIndex: (current - 1) * size}"
:virtual-y-config="{enabled: true, gt: 0}"
:seq-config="{ startIndex: (current - 1) * size }"
:virtual-y-config="{ enabled: true, gt: 0 }"
:tree-config="{
transform: true,
expandAll: true,
@@ -65,7 +65,7 @@
}"
:checkbox-config="{
checkStrictly: true,
showHeader: false
showHeader: false,
}"
:column-config="{
drag: true,
@@ -73,13 +73,27 @@
}"
:column-drag-config="{
showIcon: false,
trigger: 'cell'
trigger: 'cell',
}"
>
<vxe-column v-if="showCheckbox" type="checkbox" width="60" align="left" header-align="left" fixed="left"></vxe-column>
<vxe-column v-if="showIndex" type="seq" width="80" align="left" header-align="left" fixed="left" />
<vxe-column
v-for="(item) in tableHeadVisible"
v-if="showCheckbox"
type="checkbox"
width="60"
align="left"
header-align="left"
fixed="left"
></vxe-column>
<vxe-column
v-if="showIndex"
type="seq"
width="80"
align="left"
header-align="left"
fixed="left"
/>
<vxe-column
v-for="item in tableHeadVisible"
:key="item.key"
:field="item.key"
:title="item.title"
@@ -93,25 +107,35 @@
<template #header="{ column }">
<span class="head-title">
{{ column.title }}
<el-popover
trigger="click"
:width="200"
>
<el-popover trigger="click" :width="200">
<template #default>
<div class="head-search">
<div class="search-item">
<el-input v-model="filterData[column.field]" size="small" placeholder="请输入" clearable />
<el-input
v-model="filterData[column.field]"
size="small"
placeholder="请输入"
clearable
/>
</div>
<div class="btns">
<el-button class="btn" size="small" @click="filterResetFun(column)">重置</el-button>
<el-button class="btn" type="primary" size="small" @click="filterFun(column)">确定</el-button>
<el-button class="btn" size="small" @click="filterResetFun(column)"
>重置</el-button
>
<el-button class="btn" type="primary" size="small" @click="filterFun(column)"
>确定</el-button
>
</div>
</div>
</template>
<template #reference>
<el-icon class="head-icon" :class="{active: filterData[column.field]}" :size="16">
<el-icon
class="head-icon"
:class="{ active: filterData[column.field] }"
:size="16"
>
<Finished v-if="filterData[column.field]" />
<Filter v-else/>
<Filter v-else />
</el-icon>
</template>
</el-popover>
@@ -119,12 +143,27 @@
</template>
<template #default="{ row, column, $rowIndex }">
<template v-if="$slots[`${item.key}-edit`] || $slots[item.key]">
<template v-if="$slots[item.key] && !(editData[$rowIndex] && editData[$rowIndex][`${item.key}-edit`])">
<span class="table-cell" :class="{edit: !!$slots[`${item.key}-edit`]}" @dblclick="dblclickFun($rowIndex, item, !!$slots[`${item.key}-edit`])">
<template
v-if="
$slots[item.key] &&
!(editData[$rowIndex] && editData[$rowIndex][`${item.key}-edit`])
"
>
<span
class="table-cell"
:class="{ edit: !!$slots[`${item.key}-edit`] }"
@dblclick="dblclickFun($rowIndex, item, !!$slots[`${item.key}-edit`])"
>
<slot :name="item.key" :row="row" :column="column" />
</span>
</template>
<template v-if="$slots[`${item.key}-edit`] && (editData[$rowIndex] && editData[$rowIndex][`${item.key}-edit`])">
<template
v-if="
$slots[`${item.key}-edit`] &&
editData[$rowIndex] &&
editData[$rowIndex][`${item.key}-edit`]
"
>
<span @click.stop>
<slot :name="`${item.key}-edit`" :row="row" :column="column" />
</span>
@@ -146,7 +185,12 @@
<template #default="{ row }">
<div v-if="!$slots.tableActions" class="actions">
<template v-for="(action, aIndex) in actionList" :key="aIndex">
<el-link v-if="!(action.hide && action.hide(row)) && (findVisibleIndex(row, action) <= 2)" class="action-item" :type="action.type" @click="actionClickFun(row, action)">
<el-link
v-if="!(action.hide && action.hide(row)) && findVisibleIndex(row, action) <= 2"
class="action-item"
:type="action.type"
@click="actionClickFun(row, action)"
>
{{ action.title }}
</el-link>
</template>
@@ -157,7 +201,12 @@
<template #dropdown>
<el-dropdown-menu>
<template v-for="(action, aIndex) in actionList" :key="aIndex">
<el-dropdown-item v-if="!(action.hide && action.hide(row)) && (findVisibleIndex(row, action) > 2)" @click="actionClickFun(row, action)">
<el-dropdown-item
v-if="
!(action.hide && action.hide(row)) && findVisibleIndex(row, action) > 2
"
@click="actionClickFun(row, action)"
>
<el-link :type="action.type">{{ action.title }}</el-link>
</el-dropdown-item>
</template>
@@ -172,7 +221,12 @@
</vxe-column>
</vxe-table>
</div>
<TableFormDia v-model="formDiaVisible" :head="tableHead" :name="tableName" @update="getHeadDataFun" />
<TableFormDia
v-model="formDiaVisible"
:head="tableHead"
:name="tableName"
@update="getHeadDataFun"
/>
</div>
</template>
@@ -188,7 +242,13 @@ import { formOptionsFormat } from './lib';
import { uniqBy, cloneDeep } from 'lodash-es';
import { exportFile } from '@/utils/file';
const emit = defineEmits(['searchChange', 'load', 'settingConfirm', 'filterReset', 'filterConfirm']);
const emit = defineEmits([
'searchChange',
'load',
'settingConfirm',
'filterReset',
'filterConfirm',
]);
interface Props {
tableName: string;
@@ -266,49 +326,66 @@ const findVisibleIndex = (row: any, action: any) => {
return index;
};
const visibleNum = (row: any) => { // 展示按钮数量
const visibleNum = (row: any) => {
// 展示按钮数量
return props.actionList.filter((d: any) => !(d.hide && d.hide(row))).length;
};
watch(() => props.actionList, (list: any) => {
let width = 20; // cell内边距
list.some((item: any, index: number) => {
if (index < 2) {
width += item.title.length * 14; // 一个汉字14
width += 8; // 内边距
} else {
return true;
}
});
if (list.length > 2) {
width += 30; // 更多宽度
}
actionAutoWidth.value = width;
}, { immediate: true });
watch(() => props.data, (data) => {
data.forEach((item: any) => {
for (const key in item) {
if (key === 'extras' && item.extras) {
item[key].forEach((val: any) => {
item[val.propertyName] = val.propertyValue;
});
watch(
() => props.actionList,
(list: any) => {
let width = 20; // cell内边距
list.some((item: any, index: number) => {
if (index < 2) {
width += item.title.length * 14; // 一个汉字14
width += 8; // 内边距
} else {
return true;
}
});
if (list.length > 2) {
width += 30; // 更多宽度
}
});
formatData.value = data;
originData = cloneDeep(props.data);
}, { immediate: true });
actionAutoWidth.value = width;
},
{ immediate: true }
);
watch(() => props.params, (val: any, oldVal: any) => {
if (JSON.stringify(val) !== JSON.stringify(oldVal)) {
resetFun(val);
}
}, { deep: true });
watch(
() => props.data,
(data) => {
data.forEach((item: any) => {
for (const key in item) {
if (key === 'extras' && item.extras) {
item[key].forEach((val: any) => {
item[val.propertyName] = val.propertyValue;
});
}
}
});
formatData.value = data;
originData = cloneDeep(props.data);
},
{ immediate: true }
);
watch(() => props.searchItems, (val) => {
searchList.value = val;
}, { deep: true, immediate: true });
watch(
() => props.params,
(val: any, oldVal: any) => {
if (JSON.stringify(val) !== JSON.stringify(oldVal)) {
resetFun(val);
}
},
{ deep: true }
);
watch(
() => props.searchItems,
(val) => {
searchList.value = val;
},
{ deep: true, immediate: true }
);
onMounted(() => {
initFun();
@@ -333,7 +410,8 @@ const getHeadDataFun = () => {
const formConfig = JSON.parse(res.data.formConfig);
tableHead.value = formConfig;
tableHeadVisible.value = formConfig.filter((item: any) => item.isShow);
if (props.searchItems.length === 0) { // 没有传入搜索配置,则默认搜索配置
if (props.searchItems.length === 0) {
// 没有传入搜索配置,则默认搜索配置
const searchBuild: any[] = [];
formConfig.forEach((item: any) => {
if (item.tableSearch) {
@@ -365,13 +443,17 @@ const resetFun = (data: object) => {
searchData.value = data;
getTableDataFun();
};
watch(() => props.head, (val) => {
if (val) {
tableHead.value = val;
tableHeadVisible.value = val.filter((item: any) => item.isShow);
resetFun({});
}
}, { deep: true, immediate: true });
watch(
() => props.head,
(val) => {
if (val) {
tableHead.value = val;
tableHeadVisible.value = val.filter((item: any) => item.isShow);
resetFun({});
}
},
{ deep: true, immediate: true }
);
// 获取搜索参数
const getSearchParamsFun = () => {
if (tableSearchRef.value) {
@@ -406,7 +488,7 @@ const filterResetFun = (data: any) => {
filterFun(data, true);
};
// 筛选
const filterFun = (data: any, isReset:boolean = false) => {
const filterFun = (data: any, isReset: boolean = false) => {
const idMap: any = {};
const matchedIds = new Set<any>();
originData.forEach((item: any) => {
@@ -501,9 +583,11 @@ const actionClickFun = (row: any, action: any) => {
if (needConfirm) {
ElMessageBox.confirm(confirmTip || '确定操作吗?', '提示', {
type: 'warning',
}).then(() => {
click(row);
}).catch(() => {});
})
.then(() => {
click(row);
})
.catch(() => {});
} else {
click(row);
}
@@ -511,12 +595,21 @@ const actionClickFun = (row: any, action: any) => {
};
const exportFun = () => {
exportFile(props.exportApi, props.tableName, props.exportFileName, props.exportParams, props.exportDict);
exportFile(
props.exportApi,
props.tableName,
props.exportFileName,
props.exportParams,
props.exportDict
);
};
watch(() => props.tableName, () => {
initFun();
});
watch(
() => props.tableName,
() => {
initFun();
}
);
defineExpose({
tableData,
@@ -531,6 +624,7 @@ defineExpose({
getCheckboxRecordsFun,
removeFun,
getRecordSetFun,
cancelEditFun,
});
</script>

View File

@@ -1,12 +1,15 @@
<template>
<div class="comp-content comp-tree-case-table">
<TreeTable ref="TreeTableRef" :tableName="tableName" :data="treeData" :editMode="editMode" v-bind="$attrs">
<TreeTable
ref="TreeTableRef"
:tableName="tableName"
:data="treeData"
:editMode="editMode"
v-bind="$attrs"
>
<!-- 名称 -->
<template #nodeName="{ row ,column}">
<TreeEditItem
:data="row[column.field]"
:editMode="editMode"
>
<template #nodeName="{ row }">
<TreeEditItem :data="row.nodeName" :editMode="editMode">
<div class="node-name">
<el-icon v-if="row.nodeType === NODE_TYPE.TASK" :size="16" class="blue">
<Document />
@@ -21,40 +24,60 @@
</div>
</TreeEditItem>
</template>
<template #nodeName-edit="{ row, column }">
<el-input v-model="row[column.field]" size="small" placeholder="请输入" />
<template #nodeName-edit="{ row }">
<el-input
v-model="row.nodeName"
size="small"
placeholder="请输入"
@input="(val: any) => inputFun(val, row, 'nodeName')"
@keyup.enter="enterFun"
/>
</template>
<!-- 英文名 -->
<template #englishName="{ row, column }">
<TreeEditItem
:data="row[column.field]"
:editMode="editMode"
/>
<template #englishName="{ row }">
<TreeEditItem :data="row.englishName" :editMode="editMode" />
</template>
<template #englishName-edit="{ row }">
<el-input v-model="row.englishName" size="small" placeholder="请输入" />
</template>
<!-- 编码 -->
<template #nodeCode="{ row, column }">
<TreeEditItem
:data="row[column.field]"
:editMode="editMode"
<el-input
v-model="row.englishName"
size="small"
placeholder="请输入"
@input="(val: any) => inputFun(val, row, 'englishName')"
@keyup.enter="enterFun"
/>
</template>
<!-- 编码 -->
<template #nodeCode="{ row }">
<TreeEditItem :data="row.nodeCode" :editMode="editMode" />
</template>
<template #nodeCode-edit="{ row }">
<el-input v-model="row.nodeCode" size="small" placeholder="请输入" />
<el-input
v-model="row.nodeCode"
size="small"
placeholder="请输入"
@input="(val: any) => inputFun(val, row, 'nodeCode')"
@keyup.enter="enterFun"
/>
</template>
<template #pMemberIds="{ row }">
{{ disposeMemberList(row,'pMemberList') }}
{{ disposeMemberList(row, 'pMemberList') }}
</template>
<template #pMemberIds-edit="{ row,column }">
<userSelect @change="(data) => changeUserFun(row,data,'pMemberList','pMemberIds')" :multiple="true" v-model="row[column.field]"></userSelect>
<template #pMemberIds-edit="{ row }">
<userSelect
@change="(data) => changeUserFun(row, data, 'pMemberList', 'pMemberIds')"
:multiple="true"
v-model="row.pMemberIds"
></userSelect>
</template>
<template #eMemberIds="{ row }">
{{ disposeMemberList(row,'eMemberList') }}
{{ disposeMemberList(row, 'eMemberList') }}
</template>
<template #eMemberIds-edit="{ row,column }">
<userSelect @change="(data) => changeUserFun(row,data,'eMemberList','eMemberIds')" :multiple="true" v-model="row[column.field]"></userSelect>
<template #eMemberIds-edit="{ row }">
<userSelect
@change="(data) => changeUserFun(row, data, 'eMemberList', 'eMemberIds')"
:multiple="true"
v-model="row.eMemberIds"
></userSelect>
</template>
<!-- 计划开始时间 -->
<template #beginTime="{ row }">
@@ -93,186 +116,259 @@
/>
</template>
<!-- 达标方式 -->
<template #method="{ row,column }">
<TreeEditItem v-if="[NODE_TYPE.PERFORMANCE].includes(row.nodeType) || isMixedNodeType(row.nodeType)" :data="row[column.field]" :editMode="editMode">
<dictLabel v-model="row[column.field]" dictName="COMPLIANCE_METHOD" />
<template #method="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.PERFORMANCE].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row.method"
:editMode="editMode"
>
<dictLabel v-model="row.method" dictName="COMPLIANCE_METHOD" />
</TreeEditItem>
</template>
<template #method-edit="{ row,column }">
<dictLabel v-model="row[column.field]" dictName="COMPLIANCE_METHOD" :editable="true" />
<template #method-edit="{ row }">
<dictLabel v-model="row.method" dictName="COMPLIANCE_METHOD" :editable="true" />
</template>
<!-- 目标值 -->
<template #highValue="{ row,column }">
<TreeEditItem v-if="[NODE_TYPE.PERFORMANCE].includes(row.nodeType) || isMixedNodeType(row.nodeType)" :data="row[column.field]" :editMode="editMode">
<template #highValue="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.PERFORMANCE].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row.highValue"
:editMode="editMode"
>
</TreeEditItem>
</template>
<template #highValue-edit="{ row,column }">
<el-input-number v-if="row.performanceType==='1'" v-model="row[column.field]" size="small" placeholder="请输入" />
<el-input v-else v-model="row[column.field]" size="small" placeholder="请输入" />
<template #highValue-edit="{ row }">
<el-input-number
v-if="row.performanceType === '1'"
v-model="row.highValue"
size="small"
placeholder="请输入"
/>
<el-input
v-else
v-model="row.highValue"
size="small"
placeholder="请输入"
@input="(val: any) => inputFun(val, row, 'highValue')"
@keyup.enter="enterFun"
/>
</template>
<!-- 类型 -->
<template #nodeType="{ row, column }">
<dictLabel v-model="row[column.field]" :options="allNodeTypeOptions" />
<template #nodeType="{ row }">
<dictLabel v-model="row.nodeType" :options="allNodeTypeOptions" />
</template>
<!-- 任务模板 -->
<template #flowTemplate="{ row, column }">
<template #flowTemplate="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row[column.field]"
:data="row.flowTemplate"
:editMode="editMode"
>
<flowTemplateSelect v-model="row[column.field]" :editable="false" size="small"/>
<flowTemplateSelect v-model="row.flowTemplate" :editable="false" size="small" />
</TreeEditItem>
</template>
<template #flowTemplate-edit="{ row, column }">
<flowTemplateSelect v-model="row[column.field]" size="small" />
<template #flowTemplate-edit="{ row }">
<flowTemplateSelect v-model="row.flowTemplate" size="small" />
</template>
<!-- 标准规范 -->
<template #standard="{ row, column }">
<template #standard="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row[column.field]"
:data="row.standard"
:editMode="editMode"
>
<knowledgeSelect v-model="row[column.field]" v-model:model-name="row.standard" :editable="false" size="small"/>
<knowledgeSelect
v-model="row.standard"
v-model:model-name="row.standard"
:editable="false"
size="small"
/>
</TreeEditItem>
</template>
<template #standard-edit="{ row, column }">
<knowledgeSelect v-model="row[column.field]" size="small"/>
<template #standard-edit="{ row }">
<knowledgeSelect v-model="row.standard" size="small" />
</template>
<!-- 分析目标 -->
<template #analyseTarget="{ row, column }">
<template #analyseTarget="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row[column.field]"
:data="row.analyseTarget"
:editMode="editMode"
/>
</template>
<template #analyseTarget-edit="{ row , column}">
<el-input v-model="row[column.field]" size="small" placeholder="请输入" />
<template #analyseTarget-edit="{ row }">
<el-input
v-model="row.analyseTarget"
size="small"
placeholder="请输入"
@input="(val: any) => inputFun(val, row, 'analyseTarget')"
@keyup.enter="enterFun"
/>
</template>
<!-- 置信度 -->
<template #confidence="{ row, column }">
<template #confidence="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row[column.field]"
:data="row.confidence"
:editMode="editMode"
/>
</template>
<template #confidence-edit="{ row , column}">
<el-input-number v-model="row[column.field]" size="small" placeholder="请输入" />
<template #confidence-edit="{ row }">
<el-input-number v-model="row.confidence" size="small" placeholder="请输入" />
</template>
<!-- 难度系数 -->
<template #difficult="{ row, column }">
<template #difficult="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row[column.field]"
:data="row.difficult"
:editMode="editMode"
/>
</template>
<template #difficult-edit="{ row , column}">
<el-input-number v-model="row[column.field]" size="small" placeholder="请输入" />
<template #difficult-edit="{ row }">
<el-input-number v-model="row.difficult" size="small" placeholder="请输入" />
</template>
<!-- 标准工时 -->
<template #days="{ row, column }">
<template #days="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row[column.field]"
:data="row.days"
:editMode="editMode"
/>
</template>
<template #days-edit="{ row , column}">
<el-input-number v-model="row[column.field]" size="small" placeholder="请输入" />
<template #days-edit="{ row }">
<el-input-number v-model="row.days" size="small" placeholder="请输入" />
</template>
<!-- 指标类型 -->
<template #performanceType="{ row, column }">
<template #performanceType="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.PERFORMANCE].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row.performanceType"
:editMode="editMode"
>
<dictLabel v-model="row[column.field]" dictName="PERFORMANCE_TYPE" />
<dictLabel v-model="row.performanceType" dictName="PERFORMANCE_TYPE" />
</TreeEditItem>
</template>
<template #performanceType-edit="{ row, column }">
<dictLabel v-model="row[column.field]" dictName="PERFORMANCE_TYPE" :editable="true" />
<template #performanceType-edit="{ row }">
<dictLabel v-model="row.performanceType" dictName="PERFORMANCE_TYPE" :editable="true" />
</template>
<!-- 指标单位 -->
<template #unit="{ row, column }">
<TreeEditItem v-if="[NODE_TYPE.PERFORMANCE].includes(row.nodeType) || isMixedNodeType(row.nodeType)" :data="row.unit" :editMode="editMode">
<dictLabel v-model="row[column.field]" dictName="PERFORMANCE_UNIT" />
<template #unit="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.PERFORMANCE].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row.unit"
:editMode="editMode"
>
<dictLabel v-model="row.unit" dictName="PERFORMANCE_UNIT" />
</TreeEditItem>
</template>
<template #unit-edit="{ row, column }">
<dictLabel v-model="row[column.field]" dictName="PERFORMANCE_UNIT" :editable="true" />
<template #unit-edit="{ row }">
<dictLabel v-model="row.unit" dictName="PERFORMANCE_UNIT" :editable="true" />
</template>
<!-- 分析软件 -->
<template #analyseSoftware="{ row, column }">
<TreeEditItem v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)" :data="row.analyseSoftware" :editMode="editMode">
<dictLabel v-model="row[column.field]" dictName="ANALYSIS_SOFTWARE" />
<template #analyseSoftware="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row.analyseSoftware"
:editMode="editMode"
>
<dictLabel v-model="row.analyseSoftware" dictName="ANALYSIS_SOFTWARE" />
</TreeEditItem>
</template>
<template #analyseSoftware-edit="{ row, column }">
<dictLabel v-model="row[column.field]" dictName="ANALYSIS_SOFTWARE" :editable="true" :multiple="true" />
<template #analyseSoftware-edit="{ row }">
<dictLabel
v-model="row.analyseSoftware"
dictName="ANALYSIS_SOFTWARE"
:editable="true"
:multiple="true"
/>
</template>
<!-- 3d图示 -->
<template #imageFileId="{ row, column }">
<TreeEditItem v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)" :data="row[column.field]" :editMode="editMode">
<uploadImg v-model="row[column.field]" />
<template #imageFileId="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row.imageFileId"
:editMode="editMode"
>
<uploadImg v-model="row.imageFileId" />
</TreeEditItem>
</template>
<template #imageFileId-edit="{ row, column }">
<uploadImg v-model="row[column.field]" />
<template #imageFileId-edit="{ row }">
<uploadImg v-model="row.imageFileId" />
</template>
<!-- 仿真能力 -->
<template #bCapacity="{ row, column }">
<TreeEditItem v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)" :data="row[column.field]" :editMode="editMode">
<dictLabel v-model="row[column.field]" dictName="SIMULATION_CAPACITY" />
<template #bCapacity="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row.bCapacity"
:editMode="editMode"
>
<dictLabel v-model="row.bCapacity" dictName="SIMULATION_CAPACITY" />
</TreeEditItem>
</template>
<template #bCapacity-edit="{ row, column }">
<dictLabel v-model="row[column.field]" dictName="SIMULATION_CAPACITY" :editable="true" />
<template #bCapacity-edit="{ row }">
<dictLabel v-model="row.bCapacity" dictName="SIMULATION_CAPACITY" :editable="true" />
</template>
<!-- -->
<template #department="{ row, column }">
<TreeEditItem v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)" :data="row.department" :editMode="editMode">
<dictLabel v-model="row[column.field]" dictName="DEPARTMENT_LIST" />
<template #department="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row.department"
:editMode="editMode"
>
<dictLabel v-model="row.department" dictName="DEPARTMENT_LIST" />
</TreeEditItem>
</template>
<template #department-edit="{ row, column }">
<dictLabel v-model="row[column.field]" dictName="DEPARTMENT_LIST" :editable="true" />
<template #department-edit="{ row }">
<dictLabel v-model="row.department" dictName="DEPARTMENT_LIST" :editable="true" />
</template>
<!-- -->
<template #section="{ row, column }">
<TreeEditItem v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)" :data="row.section" :editMode="editMode">
<dictLabel v-model="row[column.field]" dictName="SECTION_LIST" />
<template #section="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row.section"
:editMode="editMode"
>
<dictLabel v-model="row.section" dictName="SECTION_LIST" />
</TreeEditItem>
</template>
<template #section-edit="{ row, column }">
<dictLabel v-model="row[column.field]" dictName="SECTION_LIST" :editable="true" />
<template #section-edit="{ row }">
<dictLabel v-model="row.section" dictName="SECTION_LIST" :editable="true" />
</template>
<!-- -->
<template #group="{ row, column }">
<TreeEditItem v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)" :data="row[column.field]" :editMode="editMode">
<dictLabel v-model="row[column.field]" dictName="GROUP_LIST" />
<template #group="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.TASK].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
:data="row.group"
:editMode="editMode"
>
<dictLabel v-model="row.group" dictName="GROUP_LIST" />
</TreeEditItem>
</template>
<template #group-edit="{ row, column }">
<dictLabel v-model="row[column.field]" dictName="GROUP_LIST" :editable="true" />
<template #group-edit="{ row }">
<dictLabel v-model="row.group" dictName="GROUP_LIST" :editable="true" />
</template>
<!-- 描述 -->
<template #description="{ row }">
<TreeEditItem
v-if="[NODE_TYPE.TASK, NODE_TYPE.PERFORMANCE].includes(row.nodeType) || isMixedNodeType(row.nodeType)"
v-if="
[NODE_TYPE.TASK, NODE_TYPE.PERFORMANCE].includes(row.nodeType) ||
isMixedNodeType(row.nodeType)
"
:data="row.description"
:editMode="editMode"
/>
</template>
<template #description-edit="{ row }">
<el-input v-model="row.description" size="small" placeholder="请输入" />
<el-input
v-model="row.description"
size="small"
placeholder="请输入"
@input="(val: any) => inputFun(val, row, 'description')"
@keyup.enter="enterFun"
/>
</template>
<!-- 插槽 -->
<template v-for="(name) in Object.keys($slots)" :key="name" #[name]="scope">
<template v-for="name in Object.keys($slots)" :key="name" #[name]="scope">
<slot :name="name" v-bind="scope" />
</template>
</TreeTable>
@@ -297,6 +393,7 @@ import userSelect from '../userSelect/index.vue';
import { disposeMemberList } from '@/views/task/projectDetail/components/project';
import { getMemberListIds } from '@/utils/task';
const ALLOWED_PATTERN = /[^a-zA-Z0-9\u4e00-\u9fa5\s]/g;
const TreeTableRef = ref<any>();
interface Props {
@@ -327,36 +424,46 @@ const treeDataFormatFun = (data: any, build: any, pId: any) => {
return build;
};
const changeUserFun = (row:any, data:any, listKey:string, idKey:string) => {
const changeUserFun = (row: any, data: any, listKey: string, idKey: string) => {
console.log('changeUserFun', row, data);
row[listKey] = data;
row[idKey] = getMemberListIds(data);
};
watch(() => props.data, (val: any) => {
treeData.value = treeDataFormatFun(val, [], '0');
}, { immediate: true });
watch(
() => props.data,
(val: any) => {
treeData.value = treeDataFormatFun(val, [], '0');
},
{ immediate: true }
);
const getCheckboxRecordsFun = (isFull: boolean) => {
if (TreeTableRef.value) {
return TreeTableRef.value.getCheckboxRecordsFun(isFull);
}
return TreeTableRef.value?.getCheckboxRecordsFun(isFull);
};
const removeFun = (data: any) => {
if (TreeTableRef.value) {
return TreeTableRef.value.removeFun(data);
}
return TreeTableRef.value?.removeFun(data);
};
const allNodeTypeOptions = computed(() => {
const options: any = poolCategoryTypeOptions.value;
return nodeTypeList.concat(options);
});
const inputFun = (val: any, data: any, key: any) => {
// 过滤特殊字符
data[key] = val.replace(ALLOWED_PATTERN, '');
};
const enterFun = () => {
TreeTableRef.value?.cancelEditFun();
};
onMounted(() => {
taskStore.fetchTemplates();
});
defineExpose({
getCheckboxRecordsFun,
removeFun,