|
@@ -382,6 +382,91 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
</a-tab-pane>
|
|
|
+ <a-tab-pane key="4" :tab="t('导入配置')">
|
|
|
+ <div class="right-contarin">
|
|
|
+ <div class="right-bottom">
|
|
|
+ <CollapseContainer :title="t('列表配置')">
|
|
|
+ <div class="right-top">
|
|
|
+ <div class="right-top-list">
|
|
|
+ <span>{{ t('模板名称:') }}</span>
|
|
|
+ <a-input
|
|
|
+ v-model:value="generatorConfig.listConfig.importTemplateName"
|
|
|
+ :placeholder="t('可填写列表标题,非必填')"
|
|
|
+ style="width: 250px"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <a-table
|
|
|
+ size="middle"
|
|
|
+ :columns="importListColumns"
|
|
|
+ :pagination="false"
|
|
|
+ :data-source="generatorConfig.listConfig.importConfigs"
|
|
|
+ :key="importColumnTableKey"
|
|
|
+ class="list-config"
|
|
|
+ >
|
|
|
+ <template #headerCell="{ column }">
|
|
|
+ <template v-if="column.key === 'sort'">
|
|
|
+ <svg class="icon" aria-hidden="true">
|
|
|
+ <use xlink:href="#icon-fangxiang1" />
|
|
|
+ </svg>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ <template #bodyCell="{ column, record, index }">
|
|
|
+ <template v-if="column.key !== 'action'">
|
|
|
+ <template v-if="column.key === 'sort'">
|
|
|
+ <svg
|
|
|
+ class="icon importDraggable-icon"
|
|
|
+ aria-hidden="true"
|
|
|
+ style="cursor: move"
|
|
|
+ >
|
|
|
+ <use xlink:href="#icon-paixu" />
|
|
|
+ </svg>
|
|
|
+ </template>
|
|
|
+ <!---如果是checked一类的组件-->
|
|
|
+ <template v-if="column.key === 'columnName'">
|
|
|
+ <a-select
|
|
|
+ v-model:value="record[column.dataIndex]"
|
|
|
+ style="width: 100%"
|
|
|
+ :options="selectOption"
|
|
|
+ @change="(_, option) => handleColumnNameChange(option, index)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template v-if="column.key === 'alignType'">
|
|
|
+ <a-select v-model:value="record[column.dataIndex]" style="width: 100%">
|
|
|
+ <a-select-option value="left"> {{ t('左对齐') }} </a-select-option>
|
|
|
+ <a-select-option value="center"> {{ t('居中') }} </a-select-option>
|
|
|
+ <a-select-option value="right"> {{ t('右对齐') }} </a-select-option>
|
|
|
+ </a-select>
|
|
|
+ </template>
|
|
|
+ <template v-if="column.key === 'width'">
|
|
|
+ <a-input type="number" v-model:value="record[column.dataIndex]" />
|
|
|
+ </template>
|
|
|
+ <template v-if="column.key === 'required'">
|
|
|
+ <Switch
|
|
|
+ v-model:checked="record[column.dataIndex]"
|
|
|
+ :disabled="record.componentProps?.required"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template v-if="column.key === 'isFilter'">
|
|
|
+ <Switch v-model:checked="record[column.dataIndex]" />
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ <template v-if="column.key === 'action' && !record.required">
|
|
|
+ <DeleteTwoTone two-tone-color="#ff8080" @click="ImportColumnRemove(index)" />
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </a-table>
|
|
|
+ <a-button type="dashed" block @click="importColumnAdd">
|
|
|
+ <PlusOutlined />
|
|
|
+ {{ t('新增') }}
|
|
|
+ </a-button>
|
|
|
+ </div>
|
|
|
+ </CollapseContainer>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </a-tab-pane>
|
|
|
+
|
|
|
<a-tab-pane class="tab-list3" key="3" :tab="t('按钮设置')">
|
|
|
<div style="padding-top: 10px">
|
|
|
<p class="tab-title">{{ t('按钮列表') }}</p>
|
|
@@ -418,8 +503,8 @@
|
|
|
<a-input v-model:value="record[column.dataIndex]" disabled />
|
|
|
</template>
|
|
|
</template>
|
|
|
- <template v-if="column.key === 'action' && !record.isDefault">
|
|
|
- <DeleteTwoTone two-tone-color="#ff8080" @click="buttonRemove(index)" />
|
|
|
+ <template v-if="column.key === 'redirectUrl' && record.isUse">
|
|
|
+ <a-input placeholder="重定向地址" v-model:value="record[column.dataIndex]" />
|
|
|
</template>
|
|
|
</template>
|
|
|
</a-table>
|
|
@@ -498,7 +583,6 @@
|
|
|
});
|
|
|
const { notification } = useMessage();
|
|
|
const generatorConfig = inject<GeneratorConfig>('generatorConfig') as GeneratorConfig;
|
|
|
- console.log('generatorConfig', generatorConfig);
|
|
|
// generatorConfig!.formJson!.list.push()
|
|
|
const current = inject<Ref<number>>('current') as Ref<number>;
|
|
|
const designType = inject<string>('designType', '');
|
|
@@ -584,6 +668,40 @@
|
|
|
width: '80px',
|
|
|
},
|
|
|
]);
|
|
|
+ const importListColumns = ref([
|
|
|
+ {
|
|
|
+ dataIndex: 'sort',
|
|
|
+ key: 'sort',
|
|
|
+ width: '50px',
|
|
|
+ align: 'center',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: t('列表字段'),
|
|
|
+ dataIndex: 'columnName',
|
|
|
+ key: 'columnName',
|
|
|
+ width: '35%',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: t('宽度'),
|
|
|
+ dataIndex: 'width',
|
|
|
+ key: 'width',
|
|
|
+ width: '15%',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: t('是否必填'),
|
|
|
+ dataIndex: 'required',
|
|
|
+ width: '15%',
|
|
|
+ key: 'required',
|
|
|
+ align: 'center',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: t('操作'),
|
|
|
+ key: 'action',
|
|
|
+ fixed: 'right',
|
|
|
+ align: 'center',
|
|
|
+ width: '80px',
|
|
|
+ },
|
|
|
+ ]);
|
|
|
|
|
|
const buttonColumns = ref([
|
|
|
{
|
|
@@ -612,8 +730,9 @@
|
|
|
width: '20%',
|
|
|
},
|
|
|
{
|
|
|
- title: t('操作'),
|
|
|
- key: 'action',
|
|
|
+ title: t('配置'),
|
|
|
+ dataIndex: 'redirectUrl',
|
|
|
+ key: 'redirectUrl',
|
|
|
fixed: 'right',
|
|
|
align: 'center',
|
|
|
},
|
|
@@ -622,6 +741,7 @@
|
|
|
const activeKey = ref<string>('1');
|
|
|
const queryTableKey = ref<number>(0);
|
|
|
const columnTableKey = ref<number>(0);
|
|
|
+ const importColumnTableKey = ref<number>(0);
|
|
|
|
|
|
const apiConfigDialog = ref<boolean>(false);
|
|
|
|
|
@@ -651,6 +771,7 @@
|
|
|
code: 'refresh',
|
|
|
icon: 'ant-design:reload-outlined',
|
|
|
isDefault: true,
|
|
|
+ redirectUrl: '',
|
|
|
},
|
|
|
{
|
|
|
isUse: true,
|
|
@@ -658,6 +779,7 @@
|
|
|
code: 'view',
|
|
|
icon: 'ant-design:eye-outlined',
|
|
|
isDefault: true,
|
|
|
+ redirectUrl: '',
|
|
|
},
|
|
|
{
|
|
|
isUse: true,
|
|
@@ -665,6 +787,7 @@
|
|
|
code: 'add',
|
|
|
icon: 'ant-design:plus-outlined',
|
|
|
isDefault: true,
|
|
|
+ redirectUrl: '',
|
|
|
},
|
|
|
{
|
|
|
isUse: true,
|
|
@@ -672,6 +795,7 @@
|
|
|
code: 'edit',
|
|
|
icon: 'ant-design:form-outlined',
|
|
|
isDefault: true,
|
|
|
+ redirectUrl: '',
|
|
|
},
|
|
|
{
|
|
|
isUse: true,
|
|
@@ -679,6 +803,7 @@
|
|
|
code: 'delete',
|
|
|
icon: 'ant-design:delete-outlined',
|
|
|
isDefault: true,
|
|
|
+ redirectUrl: '',
|
|
|
},
|
|
|
{
|
|
|
isUse: false,
|
|
@@ -686,6 +811,7 @@
|
|
|
code: 'batchdelete',
|
|
|
icon: 'ant-design:delete-outlined',
|
|
|
isDefault: true,
|
|
|
+ redirectUrl: '',
|
|
|
},
|
|
|
{
|
|
|
isUse: false,
|
|
@@ -693,6 +819,7 @@
|
|
|
code: 'copyData',
|
|
|
icon: 'ant-design:copy-outlined',
|
|
|
isDefault: true,
|
|
|
+ redirectUrl: '',
|
|
|
},
|
|
|
{
|
|
|
isUse: false,
|
|
@@ -700,6 +827,7 @@
|
|
|
code: 'batchSetUserId',
|
|
|
icon: 'ant-design:setting-outlined',
|
|
|
isDefault: true,
|
|
|
+ redirectUrl: '',
|
|
|
},
|
|
|
{
|
|
|
isUse: false,
|
|
@@ -707,6 +835,7 @@
|
|
|
code: 'import',
|
|
|
icon: 'ant-design:import-outlined',
|
|
|
isDefault: true,
|
|
|
+ redirectUrl: '',
|
|
|
},
|
|
|
{
|
|
|
isUse: false,
|
|
@@ -721,6 +850,7 @@
|
|
|
code: 'startwork',
|
|
|
icon: 'ant-design:form-outlined',
|
|
|
isDefault: true,
|
|
|
+ redirectUrl: '',
|
|
|
},
|
|
|
{
|
|
|
isUse: false,
|
|
@@ -728,6 +858,7 @@
|
|
|
code: 'print',
|
|
|
icon: 'ant-design:printer-outlined',
|
|
|
isDefault: true,
|
|
|
+ redirectUrl: '',
|
|
|
},
|
|
|
{
|
|
|
isUse: false,
|
|
@@ -735,6 +866,7 @@
|
|
|
code: PrintButton.CODE,
|
|
|
icon: 'ant-design:printer-outlined',
|
|
|
isDefault: true,
|
|
|
+ redirectUrl: '',
|
|
|
},
|
|
|
];
|
|
|
}
|
|
@@ -853,8 +985,130 @@
|
|
|
|
|
|
return mainComponents;
|
|
|
};
|
|
|
+
|
|
|
+ //过滤出 所有主表数据字段 子表的不需要 不在列表页展示的不需要 (只给导入配置使用)
|
|
|
+ const filterImportMainComponent = (
|
|
|
+ list: ComponentOptionModel[] | null,
|
|
|
+ isSearch = false,
|
|
|
+ ): Recordable[] => {
|
|
|
+ if (!list) return [];
|
|
|
+ let mainComponents = [] as Recordable[];
|
|
|
+ let mainTableFieldConfigs = [] as TableFieldConfig[];
|
|
|
+
|
|
|
+ const remoteComponents = [
|
|
|
+ 'select',
|
|
|
+ 'associate-select',
|
|
|
+ 'associate-popup',
|
|
|
+ 'multiple-popup',
|
|
|
+ 'checkbox',
|
|
|
+ 'radio',
|
|
|
+ ];
|
|
|
+ generatorConfig.tableStructureConfigs?.forEach((x) => {
|
|
|
+ if (x.isMain) mainTableFieldConfigs = x.tableFieldConfigs;
|
|
|
+ });
|
|
|
+ for (const item of list) {
|
|
|
+ //去除子表单组件 和 不在列表页展示的组件
|
|
|
+ if (noShowList.includes(item.type)) {
|
|
|
+ if (['tab', 'grid', 'card'].includes(item.type)) {
|
|
|
+ for (const child of item.layout!) {
|
|
|
+ mainComponents = unionWith(mainComponents, filterMainComponent(child.list, isSearch));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (item.type.indexOf('range') !== -1) {
|
|
|
+ //查询配置不要时间范围和日期范围
|
|
|
+ if (!isSearch) {
|
|
|
+ mainComponents.push({
|
|
|
+ key: item.key,
|
|
|
+ value: item.bindStartTime,
|
|
|
+ label: t(`{name}开始时间`, { name: item.label }),
|
|
|
+ type: item.type,
|
|
|
+ componentProps: item.options,
|
|
|
+
|
|
|
+ format: item.options?.format,
|
|
|
+ });
|
|
|
+ mainComponents.push({
|
|
|
+ key: item.key,
|
|
|
+ value: item.bindEndTime,
|
|
|
+ label: t(`{name}结束时间`, { name: item.label }),
|
|
|
+ type: item.type,
|
|
|
+ componentProps: item.options,
|
|
|
+
|
|
|
+ format: item.options?.format,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ let notInQuery = false;
|
|
|
+ //组件的数据是使用api并且引用组件值作为参数的组件 不进入查询列表
|
|
|
+ if (
|
|
|
+ ((remoteComponents.includes(item.type) && item.options?.datasourceType === 'api') ||
|
|
|
+ item.type === 'cascader') &&
|
|
|
+ isSearch
|
|
|
+ ) {
|
|
|
+ notInQuery = item.options?.apiConfig?.apiParams?.some((para) => {
|
|
|
+ const hasFormData = para.tableInfo?.some((info) => {
|
|
|
+ if (!info.value) return false;
|
|
|
+ return info.bindType === 'data' && info.value?.slice(0, 2) !== '3-';
|
|
|
+ });
|
|
|
+ return hasFormData;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!notInQuery) {
|
|
|
+ if (item.type === 'time' || item.type === 'date') {
|
|
|
+ //查询时 时间选择和日期选择需要保存format
|
|
|
+ mainComponents.push({
|
|
|
+ value: item.bindField,
|
|
|
+ label: item.label,
|
|
|
+ type: item.type,
|
|
|
+ format: item.options?.format,
|
|
|
+ });
|
|
|
+ } else if (isSearch && item.type === 'info' && item.options?.infoType === 2) {
|
|
|
+ //查询时 信息体为当前时间 则查询为时间范围
|
|
|
+ mainComponents.push({
|
|
|
+ value: item.bindField,
|
|
|
+ label: item.label,
|
|
|
+ type: item.type,
|
|
|
+ componentProps: item.options,
|
|
|
+
|
|
|
+ // format: 'YYYY-MM-DD HH:mm:ss',
|
|
|
+ isDate: true,
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ let isNumber;
|
|
|
+ if (unref(designType) !== 'data') {
|
|
|
+ let fieldType;
|
|
|
+ mainTableFieldConfigs?.map((x) => {
|
|
|
+ if (x.fieldName === item.bindField) {
|
|
|
+ fieldType = x.fieldType;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ isNumber = [2, 3, 7].includes(fieldType);
|
|
|
+ } else {
|
|
|
+ const table = tableInfo?.value.find((x) => x.isMain); //找到主表信息
|
|
|
+ const field = table?.fields.find((x) => x.name === item.bindField); //找到当前字段信息
|
|
|
+ isNumber = field?.type === ColumnType.NUMBER;
|
|
|
+ }
|
|
|
+ if ((item.type == 'input' && !item.options?.isSave) || item.type !== 'input') {
|
|
|
+ mainComponents.push({
|
|
|
+ key: item.key,
|
|
|
+ value: item.bindField,
|
|
|
+ label: item.label,
|
|
|
+ type: item.type,
|
|
|
+ isNumber,
|
|
|
+ componentProps: item.options,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return mainComponents;
|
|
|
+ };
|
|
|
+
|
|
|
const getConfigInfo = () => {
|
|
|
let listComponent = filterMainComponent(generatorConfig!.formJson!.list);
|
|
|
+ let importComponent = filterImportMainComponent(generatorConfig!.formJson!.list);
|
|
|
let queryComponent = filterMainComponent(generatorConfig!.formJson!.list, true);
|
|
|
let columnConfigs: ColumnConfig[] = [];
|
|
|
let queryConfigs: QueryConfig[] = [];
|
|
@@ -894,7 +1148,23 @@
|
|
|
//除去查询配置新增时已经设置好的组件
|
|
|
queryComponent = queryComponent.filter((x) => !addQueryNames.includes(x.value));
|
|
|
}
|
|
|
-
|
|
|
+ generatorConfig.listConfig.importConfigs = importComponent.map((component) => {
|
|
|
+ const columnConfig: ColumnConfig = {
|
|
|
+ key: component.key, //数据优先存在编辑时 绑定字段相同的情况 所以需要唯一标识
|
|
|
+ columnName: component.value,
|
|
|
+ label: component.label,
|
|
|
+ width: 100,
|
|
|
+ alignType: '',
|
|
|
+ autoWidth: true,
|
|
|
+ isNumber: component.isNumber,
|
|
|
+ componentType: component.type,
|
|
|
+ componentProps: component.componentProps,
|
|
|
+ required: component.componentProps?.required || false,
|
|
|
+ };
|
|
|
+ return columnConfig;
|
|
|
+ });
|
|
|
+ generatorConfig.listConfig.importTemplateName =
|
|
|
+ generatorConfig.listConfig.importTemplateName || generatorConfig.menuConfig.name + '导出模板';
|
|
|
generatorConfig.listConfig.columnConfigs = listComponent.map((component) => {
|
|
|
const columnConfig: ColumnConfig = {
|
|
|
key: component.key, //数据优先存在编辑时 绑定字段相同的情况 所以需要唯一标识
|
|
@@ -1009,7 +1279,6 @@
|
|
|
columns.splice(oldIndex, 1);
|
|
|
}
|
|
|
generatorConfig!.listConfig!.columnConfigs = cloneDeep(columns);
|
|
|
- console.log(generatorConfig!.listConfig!.columnConfigs);
|
|
|
columnTableKey.value++;
|
|
|
},
|
|
|
});
|
|
@@ -1021,6 +1290,39 @@
|
|
|
immediate: true,
|
|
|
},
|
|
|
);
|
|
|
+ // 监听导入模板事件
|
|
|
+ watch(
|
|
|
+ () => [generatorConfig?.listConfig?.importConfigs, activeKey.value],
|
|
|
+ (val) => {
|
|
|
+ if (val[0] && val[0].length && val[1] === '4') {
|
|
|
+ nextTick(() => {
|
|
|
+ const tbody: any = document.querySelector('.list-config .ant-table-tbody');
|
|
|
+ Sortable.create(tbody, {
|
|
|
+ handle: '.importDraggable-icon',
|
|
|
+ onEnd: ({ oldIndex, newIndex }) => {
|
|
|
+ if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || newIndex === oldIndex) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const columns = cloneDeep(generatorConfig?.listConfig?.importConfigs);
|
|
|
+ if (oldIndex > newIndex) {
|
|
|
+ columns.splice(newIndex, 0, columns[oldIndex]);
|
|
|
+ columns.splice(oldIndex + 1, 1);
|
|
|
+ } else {
|
|
|
+ columns.splice(newIndex + 1, 0, columns[oldIndex]);
|
|
|
+ columns.splice(oldIndex, 1);
|
|
|
+ }
|
|
|
+ generatorConfig!.listConfig!.importConfigs = cloneDeep(columns);
|
|
|
+ importColumnTableKey.value++;
|
|
|
+ },
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ deep: true,
|
|
|
+ immediate: true,
|
|
|
+ },
|
|
|
+ );
|
|
|
|
|
|
watch(
|
|
|
apiConfig,
|
|
@@ -1075,10 +1377,27 @@
|
|
|
generatorConfig?.listConfig?.columnConfigs.push(pushObj);
|
|
|
// queryOptionData.value.push(pushObj);
|
|
|
};
|
|
|
+ const importColumnAdd = () => {
|
|
|
+ const pushObj: ColumnConfig = {
|
|
|
+ key: '',
|
|
|
+ label: '',
|
|
|
+ columnName: '',
|
|
|
+ width: 100,
|
|
|
+ alignType: '',
|
|
|
+ autoWidth: true,
|
|
|
+ isTotal: false,
|
|
|
+ isFilter: false,
|
|
|
+ componentType: '',
|
|
|
+ };
|
|
|
+ generatorConfig.listConfig.importConfigs.push(pushObj);
|
|
|
+ };
|
|
|
|
|
|
const columnRemove = (index) => {
|
|
|
generatorConfig?.listConfig?.columnConfigs.splice(index, 1);
|
|
|
};
|
|
|
+ const ImportColumnRemove = (index) => {
|
|
|
+ generatorConfig.listConfig.importConfigs.splice(index, 1);
|
|
|
+ };
|
|
|
|
|
|
const buttonAdd = () => {
|
|
|
//给各个组件赋默认值
|
|
@@ -1092,10 +1411,6 @@
|
|
|
generatorConfig?.listConfig?.buttonConfigs.push(pushObj);
|
|
|
};
|
|
|
|
|
|
- const buttonRemove = (index) => {
|
|
|
- generatorConfig?.listConfig?.buttonConfigs.splice(index, 1);
|
|
|
- };
|
|
|
-
|
|
|
const closeModal = () => {
|
|
|
formRef.value.resetFields();
|
|
|
};
|