diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTableColumn.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTableColumn.java index e1560b421..5647836de 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTableColumn.java +++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTableColumn.java @@ -49,6 +49,11 @@ public class GenTableColumn extends BaseEntity { */ private String columnType; + /** + * 字符最大长度 + */ + private Integer columnMaxLength; + /** * JAVA类型 */ diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java index bb8b444fc..1fc6fff17 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java +++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java @@ -312,6 +312,18 @@ public class GenTableServiceImpl implements IGenTableService { tableColumn.setColumnName(column.getName()); tableColumn.setColumnComment(column.getComment()); tableColumn.setColumnType(column.getTypeName().toLowerCase()); + // 字段长度判断 + if (column.getTypeName().equalsIgnoreCase("varchar") || + column.getTypeName().equalsIgnoreCase("text") || + column.getTypeName().equalsIgnoreCase("char") || + column.getTypeName().equalsIgnoreCase("tinytext") || + column.getTypeName().equalsIgnoreCase("mediumtext") + ) { + tableColumn.setColumnMaxLength(column.getLength() == null ? 0 : column.getLength()); + } + if (column.getTypeName().equalsIgnoreCase("longtext")) { + tableColumn.setColumnMaxLength(column.getLength() == null ? 0 : -1); + } tableColumn.setSort(column.getPosition()); tableColumn.setIsRequired(column.isNullable() == 0 ? "1" : "0"); tableColumn.setIsIncrement(column.isAutoIncrement() == -1 ? "0" : "1"); diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityUtils.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityUtils.java index 6e111e3a8..53f7c459f 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityUtils.java +++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityUtils.java @@ -131,6 +131,11 @@ public class VelocityUtils { templates.add("vm/ts/types.ts.vm"); if (GenConstants.TPL_CRUD.equals(tplCategory)) { templates.add("vm/vue/index.vue.vm"); + // 新增模板 + templates.add("vm/vue/useTable.ts.vm"); + templates.add("vm/vue/form.vue.vm"); + templates.add("vm/vue/useDialog.ts.vm"); + templates.add("vm/vue/useForm.ts.vm"); } else if (GenConstants.TPL_TREE.equals(tplCategory)) { templates.add("vm/vue/index-tree.vue.vm"); } @@ -183,6 +188,16 @@ public class VelocityUtils { fileName = StringUtils.format("{}/api/{}/{}/types.ts", vuePath, moduleName, businessName); } else if (template.contains("index.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); + } + // 新增的模板 + else if (template.contains("useTable.ts.vm")) { + fileName = StringUtils.format("{}/views/{}/{}/hooks/use" + className + "Table.ts", vuePath, moduleName, businessName); + } else if (template.contains("form.vue.vm")) { + fileName = StringUtils.format("{}/views/{}/{}/modules/form.vue", vuePath, moduleName, businessName); + } else if (template.contains("useDialog.ts.vm")) { + fileName = StringUtils.format("{}/views/{}/{}/hooks/useDialog.ts", vuePath, moduleName, businessName); + } else if (template.contains("useForm.ts.vm")) { + fileName = StringUtils.format("{}/views/{}/{}/hooks/use" + className + "Form.ts", vuePath, moduleName, businessName); } else if (template.contains("index-tree.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); } diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/bo.java.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/bo.java.vm index 511d37c04..65cbe1d06 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/bo.java.vm +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/bo.java.vm @@ -41,6 +41,12 @@ public class ${ClassName}Bo extends BaseEntity { #else @NotNull(message = "$column.columnComment不能为空", groups = { $Group }) #end +#end +## 字符长度判断 +#if($column.columnMaxLength && $column.columnMaxLength != -1) +@Size(max = $column.columnMaxLength, message = "字符长度不能超过$column.columnMaxLength个字符") +#elseif($column.columnMaxLength == -1) +@Size(max = 4294967295, message = "字符长度不能超过4294967295个字符") #end private $column.javaType $column.javaField; diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/form.vue.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/form.vue.vm new file mode 100644 index 000000000..77d3f87b4 --- /dev/null +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/form.vue.vm @@ -0,0 +1,97 @@ + + + diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm index a92d19adc..2ac645e19 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm @@ -1,459 +1,215 @@ diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/useDialog.ts.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/useDialog.ts.vm new file mode 100644 index 000000000..b348d6d48 --- /dev/null +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/useDialog.ts.vm @@ -0,0 +1,17 @@ +export function useDialog() { + const dialog = ref({ + visible: false, + title: '', + isEdit: false + }) + + const openDialog = (title: string, isEdit: boolean) => { + dialog.value = { visible: true, title, isEdit } + } + + const closeDialog = () => { + dialog.value.visible = false + } + + return { dialog, openDialog, closeDialog } +} diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/useForm.ts.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/useForm.ts.vm new file mode 100644 index 000000000..caac1adde --- /dev/null +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/useForm.ts.vm @@ -0,0 +1,107 @@ +import { ${BusinessName}Form } from '@/api/${moduleName}/${businessName}/types' +import { update${BusinessName}, add${BusinessName}, get${BusinessName} } from '@/api/${moduleName}/${businessName}'; + +interface UseFormOptions { + props: any + emit: any + proxy: any + onSuccess?: () => void + onClose?: () => void +} + +export function use${BusinessName}Form({ emit, proxy, onSuccess, onClose }: UseFormOptions) { + const loading = ref(false) + const form = reactive<${BusinessName}Form>({ + #foreach ($column in $columns) + #if($column.insert || $column.edit) + #if($column.htmlType == "checkbox") + $column.javaField: []#if($foreach.count != $columns.size()),#end + #else + $column.javaField: undefined#if($foreach.count != $columns.size()),#end + #end + #end + #end + }); + + const rules = { + #foreach ($column in $columns) + #if($column.insert || $column.edit) + #if($column.required) + #set($parentheseIndex=$column.columnComment.indexOf("(")) + #if($parentheseIndex != -1) + #set($comment=$column.columnComment.substring(0, $parentheseIndex)) + #else + #set($comment=$column.columnComment) + #end + $column.javaField: [ + { required: true, message: "$comment不能为空", trigger: ['change', 'blur']}, + #if($column.columnMaxLength) + { max: $column.columnMaxLength, message: "字符长度不能超过$column.columnMaxLength个字符", trigger: ['change', 'blur']} + #end + ] + #if($foreach.count != $columns.size()),#end + #else + #if($column.columnMaxLength) + $column.javaField: [ + { max: $column.columnMaxLength, message: "字符长度不能超过$column.columnMaxLength个字符", trigger: ['change', 'blur']} + ], + #end + #end + #end + #end + } + + const ${businessName}FormRef = ref() + + const close = () => { + reset() + form.id = undefined + emit('update:modelValue', false) + onClose?.() + } + + const reset = () => { + ${businessName}FormRef.value?.resetFields() + } + + const submitForm = async () => { + try { + await ${businessName}FormRef.value?.validate() + loading.value = true + if (form.id) { + await update${BusinessName}(form) + } else { + await add${BusinessName}(form) + } + proxy?.$modal.msgSuccess('操作成功') + close() + onSuccess?.() + } catch (error) { + console.error('Form submission error:', error) + } finally { + loading.value = false + } + } + + const loadData = async (id: string | number) => { + loading.value = true + try { + const res = await get${BusinessName}(id) + Object.assign(form, res.data) + } catch (error) { + console.error('Error fetching project data:', error) + } finally { + loading.value = false + } + } + + return { + form, + rules, + loading, + ${businessName}FormRef, + submitForm, + close, + loadData + } +} diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/useTable.ts.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/useTable.ts.vm new file mode 100644 index 000000000..a15468615 --- /dev/null +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/useTable.ts.vm @@ -0,0 +1,79 @@ +import { list${BusinessName}, del${BusinessName} } from '@/api/${moduleName}/${businessName}'; +import { ${BusinessName}VO, ${BusinessName}Query } from '@/api/${moduleName}/${businessName}/types'; + +export function use${BusinessName}Table(proxy) { + const projectsList = ref<${BusinessName}VO[]>([]); + const loading = ref(true); + const total = ref(0); + const ids = ref>([]); + const single = ref(true); + const multiple = ref(true); + const clearSelection = ref(false) + + const queryParams = reactive<${BusinessName}Query>({ + pageNum: 1, + pageSize: 10, + #foreach ($column in $columns) + #if($column.query) + #if($column.htmlType != "datetime" || $column.queryType != "BETWEEN") + $column.javaField: undefined, + #end + #end + #end + params: { + #foreach ($column in $columns) + #if($column.query) + #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") + $column.javaField: undefined#if($foreach.count != $columns.size()),#end + #end + #end + #end + } + }); + + const getList = async () => { + loading.value = true; + try { + const res = await list${BusinessName}(queryParams); + projectsList.value = res.rows; + total.value = res.total; + } finally { + loading.value = false; + } + }; + + const handleSelectionChange = (selection: ${BusinessName}VO[]) => { + ids.value = selection.map((item) => item.id); + single.value = selection.length !== 1; + multiple.value = !selection.length; + }; + + const handleDelete = async (row?: ${BusinessName}VO) => { + const _ids = row?.id || ids.value; + + try { + await proxy.$modal.confirm('是否确认删除项目编号为"' + _ids + '"的数据项?'); + await del${BusinessName}(_ids); + proxy.$modal.msgSuccess('删除成功'); + getList(); + } catch (error) { + console.log('删除操作已取消') + } finally { + clearSelection.value = true + } + }; + + return { + ${businessName}List, + loading, + total, + ids, + single, + multiple, + queryParams, + getList, + handleSelectionChange, + handleDelete, + clearSelection + }; +} diff --git a/script/sql/update/update_gen_table_column.sql b/script/sql/update/update_gen_table_column.sql new file mode 100644 index 000000000..ea155d810 --- /dev/null +++ b/script/sql/update/update_gen_table_column.sql @@ -0,0 +1,4 @@ +-- 给gen_table_column表新增column_max_length字段 +ALTER TABLE `gen_table_column` +ADD COLUMN `column_max_length` int DEFAULT NULL COMMENT '字符最大长度' +AFTER `column_type`;