diff --git a/src/api/tool/gen/types.ts b/src/api/tool/gen/types.ts
index 39c6c33..bc1d0e3 100644
--- a/src/api/tool/gen/types.ts
+++ b/src/api/tool/gen/types.ts
@@ -4,8 +4,6 @@ export interface TableVO extends BaseEntity {
dataName: string;
tableName: string;
tableComment: string;
- subTableName?: any;
- subTableFkName?: any;
className: string;
tplCategory: string;
packageName: string;
@@ -25,6 +23,16 @@ export interface TableVO extends BaseEntity {
menuIds?: any;
parentMenuId?: any;
parentMenuName?: any;
+ enableExport?: boolean;
+ enableStatus?: boolean;
+ statusField?: string;
+ enableUnique?: boolean;
+ uniqueFields?: string[];
+ enableSort?: boolean;
+ sortField?: string;
+ treeRootValue?: string;
+ treeAncestorsField?: string;
+ treeOrderField?: string;
tree: boolean;
crud: boolean;
}
@@ -72,8 +80,6 @@ export interface DbTableVO {
tableId?: any;
tableName: string;
tableComment: string;
- subTableName?: any;
- subTableFkName?: any;
className?: any;
tplCategory?: any;
packageName?: any;
@@ -93,6 +99,16 @@ export interface DbTableVO {
menuIds?: any;
parentMenuId?: any;
parentMenuName?: any;
+ enableExport?: boolean;
+ enableStatus?: boolean;
+ statusField?: string;
+ enableUnique?: boolean;
+ uniqueFields?: string[];
+ enableSort?: boolean;
+ sortField?: string;
+ treeRootValue?: string;
+ treeAncestorsField?: string;
+ treeOrderField?: string;
tree: boolean;
crud: boolean;
}
@@ -104,15 +120,13 @@ export interface DbTableQuery extends PageQuery {
}
/**
- * 代码生成表详情接口 data 结构(与后端 Map 三键一致)
+ * 代码生成表详情接口 data 结构
* - info:当前表 GenTable
* - rows:字段列表 GenTableColumn[]
- * - tables:全部表 GenTable[](主子表等选项)
*/
export interface GenTableDetailPayload {
info: DbTableVO;
rows: DbColumnVO[];
- tables: DbTableVO[];
}
export interface DbColumnForm extends BaseEntity {
@@ -152,6 +166,16 @@ export interface DbParamForm {
treeName?: any;
treeParentCode?: any;
parentMenuId: string;
+ enableExport?: boolean;
+ enableStatus?: boolean;
+ statusField?: string;
+ enableUnique?: boolean;
+ uniqueFields?: string[];
+ enableSort?: boolean;
+ sortField?: string;
+ treeRootValue?: string;
+ treeAncestorsField?: string;
+ treeOrderField?: string;
}
export interface DbTableForm extends BaseEntity {
@@ -159,8 +183,6 @@ export interface DbTableForm extends BaseEntity {
tableId: string | string;
tableName: string;
tableComment: string;
- subTableName?: any;
- subTableFkName?: any;
className: string;
tplCategory: string;
packageName: string;
@@ -180,6 +202,16 @@ export interface DbTableForm extends BaseEntity {
menuIds?: any;
parentMenuId: string;
parentMenuName?: any;
+ enableExport?: boolean;
+ enableStatus?: boolean;
+ statusField?: string;
+ enableUnique?: boolean;
+ uniqueFields?: string[];
+ enableSort?: boolean;
+ sortField?: string;
+ treeRootValue?: string;
+ treeAncestorsField?: string;
+ treeOrderField?: string;
tree: boolean;
crud: boolean;
params: DbParamForm;
diff --git a/src/views/tool/gen/editTable.vue b/src/views/tool/gen/editTable.vue
index 3dfca9b..7d645bf 100644
--- a/src/views/tool/gen/editTable.vue
+++ b/src/views/tool/gen/editTable.vue
@@ -22,7 +22,7 @@
-
+
@@ -74,12 +74,14 @@
-
+
+
+
@@ -89,7 +91,14 @@
-
+
-
+
@@ -131,14 +140,26 @@ import GenInfoForm from './genInfoForm.vue';
const route = useRoute();
const activeName = ref('columnInfo');
const tableHeight = ref(document.documentElement.scrollHeight - 245 + 'px');
-const tables = ref([]);
const columns = ref([]);
const dictOptions = ref([]);
const info = ref>({});
+const DICT_HTML_TYPES = ['select', 'radio', 'checkbox', 'switch'];
const basicInfo = ref>();
const genInfo = ref>();
+const supportsDictHtmlType = (htmlType?: string) => DICT_HTML_TYPES.includes(htmlType ?? '');
+
+const normalizeColumnDictType = (column: Partial) => {
+ if (!supportsDictHtmlType(String(column.htmlType ?? ''))) {
+ column.dictType = '';
+ }
+};
+
+const handleHtmlTypeChange = (column: DbColumnVO) => {
+ normalizeColumnDictType(column);
+};
+
/** 提交按钮 */
const submitForm = async () => {
const basicOk = (await basicInfo.value?.validate()) ?? false;
@@ -147,13 +168,24 @@ const submitForm = async () => {
modal.msgError('表单校验未通过,请重新检查提交内容');
return;
}
+ columns.value.forEach(normalizeColumnDictType);
const genTable: Record = { ...info.value };
genTable.columns = columns.value;
genTable.params = {
treeCode: info.value?.treeCode,
treeName: info.value.treeName,
treeParentCode: info.value.treeParentCode,
- parentMenuId: info.value.parentMenuId
+ parentMenuId: info.value.parentMenuId,
+ enableExport: info.value.enableExport,
+ enableStatus: info.value.enableStatus,
+ statusField: info.value.statusField,
+ enableUnique: info.value.enableUnique,
+ uniqueFields: info.value.uniqueFields,
+ enableSort: info.value.enableSort,
+ sortField: info.value.sortField,
+ treeRootValue: info.value.treeRootValue,
+ treeAncestors: info.value.treeAncestorsField,
+ treeOrderField: info.value.treeOrderField
};
const response = await updateGenTable(genTable as any);
modal.msgSuccess(response.msg ?? '');
@@ -175,9 +207,24 @@ onMounted(async () => {
const res = await getGenTable(tableId);
const detail = res.data;
if (!detail) return;
- columns.value = detail.rows;
- info.value = detail.info;
- tables.value = detail.tables;
+ columns.value = (detail.rows ?? []).map(column => {
+ const item = { ...column };
+ normalizeColumnDictType(item);
+ return item;
+ });
+ info.value = {
+ enableExport: detail.info.enableExport ?? true,
+ enableStatus: detail.info.enableStatus ?? false,
+ statusField: detail.info.statusField ?? '',
+ enableUnique: detail.info.enableUnique ?? false,
+ uniqueFields: detail.info.uniqueFields ?? [],
+ enableSort: detail.info.enableSort ?? false,
+ sortField: detail.info.sortField ?? '',
+ treeRootValue: detail.info.treeRootValue ?? '0',
+ treeAncestorsField: detail.info.treeAncestorsField ?? '',
+ treeOrderField: detail.info.treeOrderField ?? '',
+ ...detail.info
+ };
const response = await getDictOptionselect();
dictOptions.value = response.data;
});
diff --git a/src/views/tool/gen/genInfoForm.vue b/src/views/tool/gen/genInfoForm.vue
index 7fd9293..668f5dd 100644
--- a/src/views/tool/gen/genInfoForm.vue
+++ b/src/views/tool/gen/genInfoForm.vue
@@ -4,7 +4,7 @@
生成模板
-
+
@@ -122,6 +122,109 @@
+
+
+
+
+
+
+
+ 导出能力
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 状态切换
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 组合唯一校验
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 排序调整
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -135,7 +238,7 @@
+
+
+
+ 根节点值
+
+
+
+
+
+
+
+
+
+
+ 祖级字段
+
+
+
+
+
+
+
+
+
+
+
+
+ 树排序字段
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
- 关联子表的表名
-
-
-
-
-
-
-
-
-
-
-
-
- 子表关联的外键名
-
-
-
-
-
-
-
-
-
-
-
@@ -238,18 +347,21 @@ interface MenuOptionsType {
children?: MenuOptionsType[];
}
-const subColumns = ref([]);
const menuOptions = ref>([]);
const formRef = ref();
const props = defineProps({
info: propTypes.any.isRequired,
- tables: propTypes.any.isRequired
+ columns: propTypes.any.isRequired
});
const infoForm = computed(() => props.info);
-
-const table = computed(() => props.tables);
+const availableColumns = computed(() => props.columns ?? []);
+const sortableColumns = computed(() =>
+ availableColumns.value.filter((column: any) =>
+ ['Integer', 'Long', 'Double', 'BigDecimal', 'LocalDateTime'].includes(column.javaType)
+ )
+);
// 表单校验
const rules = ref({
@@ -257,27 +369,56 @@ const rules = ref({
packageName: [{ required: true, message: '请输入生成包路径', trigger: 'blur' }],
moduleName: [{ required: true, message: '请输入生成模块名', trigger: 'blur' }],
businessName: [{ required: true, message: '请输入生成业务名', trigger: 'blur' }],
- functionName: [{ required: true, message: '请输入生成功能名', trigger: 'blur' }]
-});
-const subSelectChange = () => {
- infoForm.value.subTableFkName = '';
-};
-const tplSelectChange = (value: string) => {
- if (value !== 'sub') {
- infoForm.value.subTableName = '';
- infoForm.value.subTableFkName = '';
- }
-};
-const setSubTableColumns = (value: string) => {
- table.value.forEach((item: any) => {
- const name = item.tableName;
- if (value === name) {
- subColumns.value = item.columns;
- return;
+ functionName: [{ required: true, message: '请输入生成功能名', trigger: 'blur' }],
+ statusField: [
+ {
+ validator: (_rule: any, value: string, callback: (error?: Error) => void) => {
+ if (infoForm.value.enableStatus && !value) {
+ callback(new Error('请选择状态字段'));
+ return;
+ }
+ callback();
+ },
+ trigger: 'change'
}
- });
-};
-
+ ],
+ uniqueFields: [
+ {
+ validator: (_rule: any, value: string[], callback: (error?: Error) => void) => {
+ if (infoForm.value.enableUnique && (!value || value.length === 0)) {
+ callback(new Error('请选择唯一字段'));
+ return;
+ }
+ callback();
+ },
+ trigger: 'change'
+ }
+ ],
+ sortField: [
+ {
+ validator: (_rule: any, value: string, callback: (error?: Error) => void) => {
+ if (infoForm.value.enableSort && !value) {
+ callback(new Error('请选择排序字段'));
+ return;
+ }
+ callback();
+ },
+ trigger: 'change'
+ }
+ ],
+ treeRootValue: [
+ {
+ validator: (_rule: any, value: string, callback: (error?: Error) => void) => {
+ if (infoForm.value.tplCategory === 'tree' && !value) {
+ callback(new Error('请输入根节点值'));
+ return;
+ }
+ callback();
+ },
+ trigger: 'blur'
+ }
+ ]
+});
/** 查询菜单下拉树结构 */
const getMenuTreeselect = async () => {
const res = await listMenu();
@@ -289,9 +430,29 @@ const getMenuTreeselect = async () => {
};
watch(
- () => props.info.subTableName,
+ () => infoForm.value.enableStatus,
val => {
- setSubTableColumns(val);
+ if (!val) {
+ infoForm.value.statusField = '';
+ }
+ }
+);
+
+watch(
+ () => infoForm.value.enableUnique,
+ val => {
+ if (!val) {
+ infoForm.value.uniqueFields = [];
+ }
+ }
+);
+
+watch(
+ () => infoForm.value.enableSort,
+ val => {
+ if (!val) {
+ infoForm.value.sortField = '';
+ }
}
);
@@ -311,3 +472,28 @@ onMounted(() => {
getMenuTreeselect();
});
+
+
diff --git a/src/views/tool/gen/index.vue b/src/views/tool/gen/index.vue
index e027fec..4044155 100644
--- a/src/views/tool/gen/index.vue
+++ b/src/views/tool/gen/index.vue
@@ -91,7 +91,7 @@
border
class="data-table"
:data="tableList"
- @selection-change="handleSelectionChange"
+ @selection-change="handleTableSelectionChange"
>
@@ -217,6 +217,7 @@ const dataNameList = ref>([]);
const queryFormRef = ref();
const importRef = ref>();
+const selectedRows = ref([]);
const queryParams = ref({
pageNum: 1,
@@ -233,9 +234,14 @@ const preview = ref<{
data: {},
activeName: 'domain.java'
});
-const { ids, single, multiple, handleSelectionChange } = useTableSelection(item => item.tableId);
+const { ids, single, multiple, handleSelectionChange: updateSelection } = useTableSelection(item => item.tableId);
const { dialog, openDialog: openPreviewDialog } = useDialogState('代码预览');
+const handleTableSelectionChange = (selection: TableVO[]) => {
+ selectedRows.value = selection;
+ updateSelection(selection);
+};
+
/** 查询多数据源名称 */
const getDataNameList = async () => {
const res = await getDataNames();
@@ -257,16 +263,30 @@ const handleQuery = () => {
};
/** 生成代码操作 */
const handleGenTable = async (row?: TableVO) => {
- const tbIds = row?.tableId || ids.value;
- if (tbIds == '') {
+ const currentRows = row ? [row] : selectedRows.value;
+ if (!currentRows.length) {
modal.msgError('请选择要生成的数据');
return;
}
- if (row?.genType === '1') {
- await genCode(row.tableId);
- modal.msgSuccess('成功生成到自定义路径:' + row.genPath);
- } else {
- download.zip('/tool/gen/batchGenCode?tableIdStr=' + tbIds, 'ruoyi.zip');
+
+ const customRows = currentRows.filter(item => item.genType === '1');
+ const zipRows = currentRows.filter(item => item.genType !== '1');
+
+ for (const item of customRows) {
+ await genCode(item.tableId);
+ }
+
+ if (customRows.length === 1 && zipRows.length === 0) {
+ modal.msgSuccess('成功生成到自定义路径:' + customRows[0].genPath);
+ return;
+ }
+ if (customRows.length > 1) {
+ modal.msgSuccess('已生成到自定义路径,共 ' + customRows.length + ' 张表');
+ }
+
+ if (zipRows.length > 0) {
+ const zipIds = zipRows.map(item => item.tableId).join(',');
+ download.zip('/tool/gen/batchGenCode?tableIdStr=' + zipIds, 'ruoyi.zip');
}
};
/** 同步数据库操作 */