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..2f1e5d409 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 @@ -3,6 +3,7 @@ package org.dromara.generator.util; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; import org.dromara.generator.constant.GenConstants; import org.dromara.common.core.utils.DateUtils; import org.dromara.common.core.utils.StringUtils; @@ -74,6 +75,29 @@ public class VelocityUtils { if (GenConstants.TPL_TREE.equals(tplCategory)) { setTreeVelocityContext(velocityContext, genTable); } + // 判断是modal还是drawer + Dict paramsObj = JsonUtils.parseMap(genTable.getOptions()); + if (ObjectUtil.isNotNull(paramsObj)) { + String popupComponent = Optional + .ofNullable(paramsObj.getStr("popupComponent")) + .orElse("modal"); + velocityContext.put("popupComponent", popupComponent); + velocityContext.put("PopupComponent", StringUtils.capitalize(popupComponent)); + } else { + velocityContext.put("popupComponent", "modal"); + velocityContext.put("PopupComponent", "Modal"); + } + // 判断是原生antd表单还是useForm表单 + // native 原生antd表单 + // useForm useVbenForm + if (ObjectUtil.isNotNull(paramsObj)) { + String formComponent = Optional + .ofNullable(paramsObj.getStr("formComponent")) + .orElse("useForm"); + velocityContext.put("formComponent", formComponent); + } else { + velocityContext.put("formComponent", "useForm"); + } return velocityContext; } @@ -134,6 +158,21 @@ public class VelocityUtils { } else if (GenConstants.TPL_TREE.equals(tplCategory)) { templates.add("vm/vue/index-tree.vue.vm"); } + + /** + * 添加vben5 + */ + templates.add("vm/vben5/api/index.ts.vm"); + templates.add("vm/vben5/api/model.d.ts.vm"); + templates.add("vm/vben5/views/data.ts.vm"); + if (GenConstants.TPL_CRUD.equals(tplCategory)) { + templates.add("vm/vben5/views/index_vben.vue.vm"); + templates.add("vm/vben5/views/popup.vue.vm"); + } else if (GenConstants.TPL_TREE.equals(tplCategory)) { + templates.add("vm/vben5/views/index_vben_tree.vue.vm"); + templates.add("vm/vben5/views/popup_tree.vue.vm"); + } + return templates; } @@ -186,6 +225,38 @@ public class VelocityUtils { } else if (template.contains("index-tree.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); } + + // 判断是modal还是drawer + Dict paramsObj = JsonUtils.parseMap(genTable.getOptions()); + String popupComponent = "modal"; + if (ObjectUtil.isNotNull(paramsObj)) { + popupComponent = Optional + .ofNullable(paramsObj.getStr("popupComponent")) + .orElse("modal"); + } + String vben5Path = "vben5"; + if (template.contains("vm/vben5/api/index.ts.vm")) { + fileName = StringUtils.format("{}/api/{}/{}/index.ts", vben5Path, moduleName, businessName); + } + if (template.contains("vm/vben5/api/model.d.ts.vm")) { + fileName = StringUtils.format("{}/api/{}/{}/model.d.ts", vben5Path, moduleName, businessName); + } + if (template.contains("vm/vben5/views/index_vben.vue.vm")) { + fileName = StringUtils.format("{}/views/{}/{}/index.vue", vben5Path, moduleName, businessName); + } + if (template.contains("vm/vben5/views/index_vben_tree.vue.vm")) { + fileName = StringUtils.format("{}/views/{}/{}/index.vue", vben5Path, moduleName, businessName); + } + if (template.contains("vm/vben5/views/data.ts.vm")) { + fileName = StringUtils.format("{}/views/{}/{}/data.ts", vben5Path, moduleName, businessName); + } + if (template.contains("vm/vben5/views/popup.vue.vm")) { + fileName = StringUtils.format("{}/views/{}/{}/{}-{}.vue", vben5Path, moduleName, businessName, businessName, popupComponent); + } + if (template.contains("vm/vben5/views/popup_tree.vue.vm")) { + fileName = StringUtils.format("{}/views/{}/{}/{}-{}.vue", vben5Path, moduleName, businessName, businessName, popupComponent); + } + return fileName; } diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/api/index.ts.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/api/index.ts.vm new file mode 100644 index 000000000..018c139a5 --- /dev/null +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/api/index.ts.vm @@ -0,0 +1,69 @@ +import type { ${BusinessName}VO, ${BusinessName}Form, ${BusinessName}Query } from './model'; + +import type { ID, IDS } from '#/api/common'; +#if($tplCategory != 'tree') +import type { PageResult } from '#/api/common'; +#end + +import { commonExport } from '#/api/helper'; +import { requestClient } from '#/api/request'; + +/** +* 查询${functionName}列表 +* @param params +* @returns ${functionName}列表 +*/ +export function ${businessName}List(params?: ${BusinessName}Query) { + #if($tplCategory != 'tree') + return requestClient.get>('/${moduleName}/${businessName}/list', { params }); + #else + return requestClient.get<${BusinessName}VO[]>(`/${moduleName}/${businessName}/list`, { params }); + #end +} + +#if($tplCategory != 'tree') +/** + * 导出${functionName}列表 + * @param params + * @returns ${functionName}列表 + */ +export function ${businessName}Export(params?: ${BusinessName}Query) { + return commonExport('/${moduleName}/${businessName}/export', params ?? {}); +} +#end + +/** + * 查询${functionName}详情 + * @param ${pkColumn.javaField} id + * @returns ${functionName}详情 + */ +export function ${businessName}Info(${pkColumn.javaField}: ID) { + return requestClient.get<${BusinessName}VO>(`/${moduleName}/${businessName}/${${pkColumn.javaField}}`); +} + +/** + * 新增${functionName} + * @param data + * @returns void + */ +export function ${businessName}Add(data: ${BusinessName}Form) { + return requestClient.postWithMsg('/${moduleName}/${businessName}', data); +} + +/** + * 更新${functionName} + * @param data + * @returns void + */ +export function ${businessName}Update(data: ${BusinessName}Form) { + return requestClient.putWithMsg('/${moduleName}/${businessName}', data); +} + +/** + * 删除${functionName} + * @param ${pkColumn.javaField} id + * @returns void + */ +export function ${businessName}Remove(${pkColumn.javaField}: ID | IDS) { + return requestClient.deleteWithMsg(`/${moduleName}/${businessName}/${${pkColumn.javaField}}`); +} diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/api/model.d.ts.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/api/model.d.ts.vm new file mode 100644 index 000000000..862c26488 --- /dev/null +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/api/model.d.ts.vm @@ -0,0 +1,56 @@ +import type { PageQuery, BaseEntity } from '#/api/common'; + +export interface ${BusinessName}VO { +#foreach ($column in $columns) +#if($column.list) + /** + * $column.columnComment + */ + $column.javaField:#if($column.javaField.indexOf("id") != -1 || $column.javaField.indexOf("Id") != -1) string | number; + #elseif($column.javaType == 'Long' || $column.javaType == 'Integer' || $column.javaType == 'Double' || $column.javaType == 'Float' || $column.javaType == 'BigDecimal') number; + #elseif($column.javaType == 'Boolean') boolean; + #else string; + #end +#end +#end +#if ($table.tree) + /** + * 子对象 + */ + children: ${BusinessName}VO[]; +#end +} + +export interface ${BusinessName}Form extends BaseEntity { +#foreach ($column in $columns) +#if($column.insert || $column.edit) + /** + * $column.columnComment + */ + $column.javaField?:#if($column.javaField.indexOf("id") != -1 || $column.javaField.indexOf("Id") != -1) string | number; + #elseif($column.javaType == 'Long' || $column.javaType == 'Integer' || $column.javaType == 'Double' || $column.javaType == 'Float' || $column.javaType == 'BigDecimal') number; + #elseif($column.javaType == 'Boolean') boolean; + #else string; + #end +#end +#end +} + +export interface ${BusinessName}Query #if(!${treeCode})extends PageQuery #end{ +#foreach ($column in $columns) +#if($column.query) + /** + * $column.columnComment + */ + $column.javaField?:#if($column.javaField.indexOf("id") != -1 || $column.javaField.indexOf("Id") != -1) string | number; + #elseif($column.javaType == 'Long' || $column.javaType == 'Integer' || $column.javaType == 'Double' || $column.javaType == 'Float' || $column.javaType == 'BigDecimal') number; + #elseif($column.javaType == 'Boolean') boolean; + #else string; + #end +#end +#end + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/views/data.ts.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/views/data.ts.vm new file mode 100644 index 000000000..81a69ace9 --- /dev/null +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/views/data.ts.vm @@ -0,0 +1,215 @@ +import type { FormSchemaGetter } from '#/adapter/form'; +import type { VxeGridProps } from '#/adapter/vxe-table'; + +#if(${dicts} != '') +import { getDictOptions } from '#/utils/dict'; +import { renderDict } from '#/utils/render'; +#end + +export const querySchema: FormSchemaGetter = () => [ + #foreach($column in $columns) + #if($column.query) + #if($column.dictType) + #set($dictType=$column.dictType) + #else + #set($dictType="") + #end + #set($parentheseIndex=$column.columnComment.indexOf("(")) + #if($parentheseIndex != -1) + #set($comment=$column.columnComment.substring(0, $parentheseIndex)) + #else + #set($comment=$column.columnComment) + #end + #if($column.htmlType == "input") + #set($component="Input") + #elseif($column.htmlType == "textarea") + #set($component="Textarea") + #elseif($column.htmlType == "select") + #set($component="Select") + #elseif($column.htmlType == "radio") + #set($component="RadioGroup") + #elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN") + #set($component="DatePicker") + #elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") + #set($component="RangePicker") + #else + #set($component="Input") + #end + { + component: '${component}', + #if($component == "Select" || $component == "RadioGroup") + componentProps: { + #if($dictType != "") + // 可选从DictEnum中获取 DictEnum.${dictType.toUpperCase()} 便于维护 + options: getDictOptions('$dictType'), + #end + #if($component == "RadioGroup") + buttonStyle: 'solid', + optionType: 'button', + #end + }, + #elseif($component == "DatePicker" || $component == "RangePicker") + componentProps: { + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'YYYY-MM-DD HH:mm:ss', + }, + #end + fieldName: '${column.javaField}', + label: '${comment}', + }, + #end + #end +]; + +// 需要使用i18n注意这里要改成getter形式 否则切换语言不会刷新 +// export const columns: () => VxeGridProps['columns'] = () => [ +export const columns: VxeGridProps['columns'] = [ + #if($tplCategory != 'tree') + { type: 'checkbox', width: 60 }, + #end + #foreach($column in $columns) + #if($column.list) + #if($column.dictType) + #set($dictType=$column.dictType) + #else + #set($dictType="") + #end + #set($parentheseIndex=$column.columnComment.indexOf("(")) + #if($parentheseIndex != -1) + #set($comment=$column.columnComment.substring(0, $parentheseIndex)) + #else + #set($comment=$column.columnComment) + #end + { + title: '${comment}', + field: '${column.javaField}', + #if( $foreach.count == 1 && $tplCategory == 'tree') + treeNode: true, + #end + #if($dictType != "") + slots: { + default: ({ row }) => { + // 可选从DictEnum中获取 DictEnum.${dictType.toUpperCase()} 便于维护 + return renderDict(row.${column.javaField}, '$dictType'); + }, + }, + #end + }, + #end + #end + { + field: 'action', + fixed: 'right', + slots: { default: 'action' }, + title: '操作', + width: 180, + }, +]; + +#if($formComponent == "useForm") +export const ${popupComponent}Schema: FormSchemaGetter = () => [ + #foreach($column in $columns) + #if($column.edit) + #if($column.dictType) + #set($dictType=$column.dictType) + #else + #set($dictType="") + #end + #set($parentheseIndex=$column.columnComment.indexOf("(")) + #if($parentheseIndex != -1) + #set($comment=$column.columnComment.substring(0, $parentheseIndex)) + #else + #set($comment=$column.columnComment) + #end + #if($column.htmlType == "input") + #set($component="Input") + #elseif($column.htmlType == "textarea") + #set($component="Textarea") + #elseif($column.htmlType == "select") + #set($component="Select") + #elseif($column.htmlType == "radio") + #set($component="RadioGroup") + #elseif($column.htmlType == "checkbox") + #set($component="Checkbox") + #elseif($column.htmlType == "imageUpload") + #set($component="ImageUpload") + #elseif($column.htmlType == "fileUpload") + #set($component="FileUpload") + #elseif($column.htmlType == "editor") + #set($component="RichTextarea") + #elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN") + #set($component="DatePicker") + #elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") + #set($component="RangePicker") + #else + #set($component="Input") + #end + #if($column.required && $column.pk == false) + #set($required='true') + #else + #set($required='false') + #end + { + label: '${comment}', + fieldName: '${column.javaField}', + #if("" != $treeParentCode && $column.javaField == $treeParentCode) + component: 'TreeSelect', + #else + component: '${component}', + #end + #if($component == "DatePicker" || $component == "RangePicker") + componentProps: { + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'YYYY-MM-DD HH:mm:ss', + }, + #elseif($component == "ImageUpload") + componentProps: { + // accept: 'image/*', // 可选拓展名或者mime类型 ,拼接 + // maxCount: 1, // 最大上传文件数 默认为1 为1会绑定为string而非string[]类型 + }, + #elseif($component == "FileUpload") + /** + * 注意这里获取为数组 需要自行定义回显/提交 + * 文件上传还在demo阶段 可能有重大改动! + */ + componentProps: { + // accept: 'application/pdf', // 可选拓展名或者mime类型 ,拼接 + // maxCount: 1, // 最大上传文件数 默认为1 为1会绑定为string而非string[]类型 + }, + #elseif($component == "RichTextarea") + componentProps: { + // disabled: false, // 是否只读 + // height: 400 // 高度 默认400 + }, + #elseif($component == "Select" || $component == "RadioGroup" || $component == "Checkbox") + componentProps: { + #if($dictType != "") + // 可选从DictEnum中获取 DictEnum.${dictType.toUpperCase()} 便于维护 + options: getDictOptions('$dictType'), + #end + #if($component == "RadioGroup") + buttonStyle: 'solid', + optionType: 'button', + #end + }, + #end + #if(${column.pk}) + dependencies: { + show: () => false, + triggerFields: [''], + }, + #end + #if($required == 'true' && $column.pk == false) + #if($component == "Select" || $component == "RadioGroup" || $component == "Checkbox") + rules: 'selectRequired', + #else + rules: 'required', + #end + #end + }, + #end + #end +]; +#end diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/views/index_vben.vue.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/views/index_vben.vue.vm new file mode 100644 index 000000000..790d19697 --- /dev/null +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/views/index_vben.vue.vm @@ -0,0 +1,182 @@ + + + diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/views/index_vben_tree.vue.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/views/index_vben_tree.vue.vm new file mode 100644 index 000000000..cf7ad564f --- /dev/null +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/views/index_vben_tree.vue.vm @@ -0,0 +1,152 @@ + + + diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/views/popup.vue.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/views/popup.vue.vm new file mode 100644 index 000000000..ecd0a32b2 --- /dev/null +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vben5/views/popup.vue.vm @@ -0,0 +1,373 @@ +#if($formComponent == "useForm") + + + +#else + + + +