ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/controller/GenController.java
@@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.web.controller.BaseController; @@ -104,12 +105,12 @@ @RequiresPermissions("tool:gen:import") @Log(title = "代码生成", businessType = BusinessType.IMPORT) @PostMapping("/importTable") public AjaxResult importTableSave(String tables) public AjaxResult importTableSave(@RequestParam("tables") String tables, @RequestParam("tplWebType") String tplWebType) { String[] tableNames = Convert.toStrArray(tables); // 查询表信息 List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames); genTableService.importGenTable(tableList); genTableService.importGenTable(tableList, tplWebType); return success(); } ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/domain/GenTable.java
@@ -41,7 +41,7 @@ /** 使用的模板(crud单表操作 tree树表操作 sub主子表操作) */ private String tplCategory; /** 前端类型(element-ui模版 element-plus模版) */ /** 前端类型(element-ui模版 element-plus模版 element-plus-typescript模版) */ private String tplWebType; /** 生成包路径 */ @@ -267,6 +267,7 @@ { this.subTable = subTable; } public List<GenTableColumn> getColumns() { return columns; @@ -346,6 +347,7 @@ { return tplCategory != null && StringUtils.equals(GenConstants.TPL_SUB, tplCategory); } public boolean isTree() { return isTree(this.tplCategory); ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/GenTableServiceImpl.java
@@ -157,7 +157,7 @@ */ @Override @Transactional(rollbackFor = Exception.class) public void importGenTable(List<GenTable> tableList) public void importGenTable(List<GenTable> tableList, String tplWebType) { String operName = SecurityUtils.getUsername(); try @@ -165,6 +165,7 @@ for (GenTable table : tableList) { String tableName = table.getTableName(); table.setTplWebType(tplWebType); GenUtils.initTable(table, operName); int row = genTableMapper.insertGenTable(table); if (row > 0) ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/IGenTableService.java
@@ -70,8 +70,9 @@ * 导入表结构 * * @param tableList 导入表列表 * @param tplWebType 前端类型 */ public void importGenTable(List<GenTable> tableList); public void importGenTable(List<GenTable> tableList, String tplWebType); /** * 预览代码 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/VelocityUtils.java
@@ -29,6 +29,12 @@ /** 默认上级菜单,系统工具 */ private static final String DEFAULT_PARENT_MENU_ID = "3"; /** Vue3 Element Plus 模版 */ private static final String ELEMENT_PLUS = "element-plus"; /** Vue3 Element Plus TypeScript 模版 */ private static final String ELEMENT_PLUS_TYPESSRIPT = "element-plus-typescript"; /** * 设置模板变量信息 * @@ -130,9 +136,15 @@ public static List<String> getTemplateList(String tplCategory, String tplWebType) { String useWebType = "vm/vue"; if ("element-plus".equals(tplWebType)) String apiTemplate = "vm/js/api.js.vm"; if (StringUtils.equals(ELEMENT_PLUS, tplWebType)) { useWebType = "vm/vue/v3"; } else if (StringUtils.equals(ELEMENT_PLUS_TYPESSRIPT, tplWebType)) { useWebType = "vm/vue/v3ts"; apiTemplate = "vm/ts/api.ts.vm"; } List<String> templates = new ArrayList<String>(); templates.add("vm/java/domain.java.vm"); @@ -142,7 +154,12 @@ templates.add("vm/java/controller.java.vm"); templates.add("vm/xml/mapper.xml.vm"); templates.add("vm/sql/sql.vm"); templates.add("vm/js/api.js.vm"); templates.add(apiTemplate); if (StringUtils.equals(ELEMENT_PLUS_TYPESSRIPT, tplWebType)) { templates.add("vm/ts/type.ts.vm"); templates.add("vm/ts/index.ts.vm"); } if (GenConstants.TPL_CRUD.equals(tplCategory)) { templates.add(useWebType + "/index.vue.vm"); @@ -215,6 +232,18 @@ { fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName); } else if (template.contains("api.ts.vm")) { fileName = StringUtils.format("{}/api/{}/{}.ts", vuePath, moduleName, businessName); } else if (template.contains("type.ts.vm")) { fileName = StringUtils.format("{}/types/api/{}/{}.ts", vuePath, moduleName, businessName); } else if (template.contains("index.ts.vm")) { fileName = StringUtils.format("{}/types/api/index-bak.ts", vuePath); } else if (template.contains("index.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/controller.java.vm
@@ -1,7 +1,6 @@ package ${packageName}.controller; import java.util.List; import java.io.IOException; import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; ruoyi-modules/ruoyi-gen/src/main/resources/vm/ts/api.ts.vm
New file @@ -0,0 +1,51 @@ import request from '@/utils/request' import type { AjaxResult, TableDataInfo, ${BusinessName}QueryParams, ${ClassName} } from '@/types' // 查询${functionName}列表 #if($table.tree) export function list${BusinessName}(query?: ${BusinessName}QueryParams): Promise<AjaxResult<${ClassName}[]>> { #else export function list${BusinessName}(query: ${BusinessName}QueryParams): Promise<TableDataInfo<${ClassName}[]>> { #end return request({ url: '/${moduleName}/${businessName}/list', method: 'get', params: query }) } // 查询${functionName}详细 export function get${BusinessName}(${pkColumn.javaField}: number): Promise<AjaxResult<${ClassName}>> { return request({ url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, method: 'get' }) } // 新增${functionName} export function add${BusinessName}(data: ${ClassName}): Promise<AjaxResult> { return request({ url: '/${moduleName}/${businessName}', method: 'post', data: data }) } // 修改${functionName} export function update${BusinessName}(data: ${ClassName}): Promise<AjaxResult> { return request({ url: '/${moduleName}/${businessName}', method: 'put', data: data }) } // 删除${functionName} export function del${BusinessName}(${pkColumn.javaField}: number | number[]): Promise<AjaxResult> { return request({ url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, method: 'delete' }) } ruoyi-modules/ruoyi-gen/src/main/resources/vm/ts/index.ts.vm
New file @@ -0,0 +1,9 @@ /** * API 类型统一导出 */ .... // 防止覆盖,需手动追加下面代码到index.ts文件中,追加好后此文件可删除 // ${moduleName} 模块 export * from "./${moduleName}/${businessName}"; ruoyi-modules/ruoyi-gen/src/main/resources/vm/ts/type.ts.vm
New file @@ -0,0 +1,51 @@ import type { PageDomain, BaseEntity } from "../common"; /** ${functionName}配置分页查询参数 */ export interface ${BusinessName}QueryParams extends PageDomain { #foreach($column in $columns) #if($column.query) #set($type = "string") #if($column.javaType == "Long" || $column.javaType == "Integer") #set($type = "number") #elseif($column.javaType == "Boolean") #set($type = "boolean") #end /** ${column.columnComment} */ ${column.javaField}?: ${type}; #end #end } /** ${functionName}配置信息 */ export interface ${ClassName} extends BaseEntity { #foreach($column in $columns) #set($type = "string") #if($column.javaType == "Long" || $column.javaType == "Integer") #set($type = "number") #elseif($column.javaType == "Boolean") #set($type = "boolean") #end /** ${column.columnComment} */ ${column.javaField}?: ${type}; #end #if($table.sub) /** $table.subTable.functionName信息 */ ${subclassName}List?: ${subClassName}[]; #end } #if($table.sub) /** ${subTable.functionName}配置信息 */ export interface ${subClassName} extends BaseEntity { #foreach ($column in $subTable.columns) #set($type = "string") #if($column.javaType == "Long" || $column.javaType == "Integer") #set($type = "number") #elseif($column.javaType == "Boolean") #set($type = "boolean") #end /** ${column.columnComment} */ ${column.javaField}?: ${type}; #end } #end ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/v3ts/index-tree.vue.vm
New file @@ -0,0 +1,476 @@ <template> <div class="app-container"> <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"> #foreach($column in $columns) #if($column.query) #set($dictType=$column.dictType) #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) #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") <el-form-item label="${comment}" prop="${column.javaField}"> <el-input v-model="queryParams.${column.javaField}" placeholder="请输入${comment}" clearable @keyup.enter="handleQuery" /> </el-form-item> #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType) <el-form-item label="${comment}" prop="${column.javaField}"> <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable> <el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" :value="dict.value" /> </el-select> </el-form-item> #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType) <el-form-item label="${comment}" prop="${column.javaField}"> <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable> <el-option label="请选择字典生成" value="" /> </el-select> </el-form-item> #elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN") <el-form-item label="${comment}" prop="${column.javaField}"> <el-date-picker clearable v-model="queryParams.${column.javaField}" type="date" value-format="YYYY-MM-DD" placeholder="选择${comment}"> </el-date-picker> </el-form-item> #elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") <el-form-item label="${comment}" style="width: 308px"> <el-date-picker v-model="daterange${AttrName}" value-format="YYYY-MM-DD" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" ></el-date-picker> </el-form-item> #end #end #end <el-form-item> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button> </el-form-item> </el-form> <el-row :gutter="10" class="mb8"> <el-col :span="1.5"> <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['${permissionPrefix}:add']" >新增</el-button> </el-col> <el-col :span="1.5"> <el-button type="info" plain icon="Sort" @click="toggleExpandAll" >展开/折叠</el-button> </el-col> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> </el-row> <el-table v-if="refreshTable" v-loading="loading" :data="${businessName}List" row-key="${treeCode}" :default-expand-all="isExpandAll" :tree-props="{children: 'children', hasChildren: 'hasChildren'}" > #foreach($column in $columns) #set($javaField=$column.javaField) #set($parentheseIndex=$column.columnComment.indexOf("(")) #if($parentheseIndex != -1) #set($comment=$column.columnComment.substring(0, $parentheseIndex)) #else #set($comment=$column.columnComment) #end #if($column.pk) #elseif($column.list && $column.htmlType == "datetime") <el-table-column label="${comment}" align="center" prop="${javaField}" width="180"> <template #default="scope"> <span>{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}</span> </template> </el-table-column> #elseif($column.list && $column.htmlType == "imageUpload") <el-table-column label="${comment}" align="center" prop="${javaField}" width="100"> <template #default="scope"> <image-preview :src="scope.row.${javaField}" :width="50" :height="50"/> </template> </el-table-column> #elseif($column.list && "" != $column.dictType) <el-table-column label="${comment}" align="center" prop="${javaField}"> <template #default="scope"> #if($column.htmlType == "checkbox") <dict-tag :options="${column.dictType}" :value="scope.row.${javaField} ? scope.row.${javaField}.split(',') : []"/> #else <dict-tag :options="${column.dictType}" :value="scope.row.${javaField}"/> #end </template> </el-table-column> #elseif($column.list && "" != $javaField) #if(${foreach.index} == 1) <el-table-column label="${comment}" prop="${javaField}" /> #else <el-table-column label="${comment}" align="center" prop="${javaField}" /> #end #end #end <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <template #default="scope"> <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${permissionPrefix}:edit']">修改</el-button> <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['${permissionPrefix}:add']">新增</el-button> <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${permissionPrefix}:remove']">删除</el-button> </template> </el-table-column> </el-table> <!-- 添加或修改${functionName}对话框 --> <el-dialog :title="title" v-model="open" width="500px" append-to-body> <el-form ref="${businessName}Ref" :model="form" :rules="rules" label-width="80px"> #foreach($column in $columns) #set($field=$column.javaField) #if($column.insert && !$column.pk) #if(($column.usableColumn) || (!$column.superColumn)) #set($parentheseIndex=$column.columnComment.indexOf("(")) #if($parentheseIndex != -1) #set($comment=$column.columnComment.substring(0, $parentheseIndex)) #else #set($comment=$column.columnComment) #end #set($dictType=$column.dictType) #if("" != $treeParentCode && $column.javaField == $treeParentCode) <el-form-item label="${comment}" prop="${treeParentCode}"> <el-tree-select v-model="form.${treeParentCode}" :data="${businessName}Options" :props="{ value: '${treeCode}', label: '${treeName}', children: 'children' }" value-key="${treeCode}" placeholder="请选择${comment}" check-strictly /> </el-form-item> #elseif($column.htmlType == "input") <el-form-item label="${comment}" prop="${field}"> <el-input v-model="form.${field}" placeholder="请输入${comment}" /> </el-form-item> #elseif($column.htmlType == "imageUpload") <el-form-item label="${comment}" prop="${field}"> <image-upload v-model="form.${field}"/> </el-form-item> #elseif($column.htmlType == "fileUpload") <el-form-item label="${comment}" prop="${field}"> <file-upload v-model="form.${field}"/> </el-form-item> #elseif($column.htmlType == "editor") <el-form-item label="${comment}"> <editor v-model="form.${field}" :min-height="192"/> </el-form-item> #elseif($column.htmlType == "select" && "" != $dictType) <el-form-item label="${comment}" prop="${field}"> <el-select v-model="form.${field}" placeholder="请选择${comment}"> <el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" #if($column.javaType == "Integer" || $column.javaType == "Long") :value="parseInt(dict.value)" #else :value="dict.value" #end ></el-option> </el-select> </el-form-item> #elseif($column.htmlType == "select" && $dictType) <el-form-item label="${comment}" prop="${field}"> <el-select v-model="form.${field}" placeholder="请选择${comment}"> <el-option label="请选择字典生成" value="" /> </el-select> </el-form-item> #elseif($column.htmlType == "checkbox" && "" != $dictType) <el-form-item label="${comment}" prop="${field}"> <el-checkbox-group v-model="form.${field}"> <el-checkbox v-for="dict in ${dictType}" :key="dict.value" :label="dict.value"> {{dict.label}} </el-checkbox> </el-checkbox-group> </el-form-item> #elseif($column.htmlType == "checkbox" && $dictType) <el-form-item label="${comment}" prop="${field}"> <el-checkbox-group v-model="form.${field}"> <el-checkbox>请选择字典生成</el-checkbox> </el-checkbox-group> </el-form-item> #elseif($column.htmlType == "radio" && "" != $dictType) <el-form-item label="${comment}" prop="${field}"> <el-radio-group v-model="form.${field}"> <el-radio v-for="dict in ${dictType}" :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long") :label="parseInt(dict.value)" #else :label="dict.value" #end >{{dict.label}}</el-radio> </el-radio-group> </el-form-item> #elseif($column.htmlType == "radio" && $dictType) <el-form-item label="${comment}" prop="${field}"> <el-radio-group v-model="form.${field}"> <el-radio label="1">请选择字典生成</el-radio> </el-radio-group> </el-form-item> #elseif($column.htmlType == "datetime") <el-form-item label="${comment}" prop="${field}"> <el-date-picker clearable v-model="form.${field}" type="date" value-format="YYYY-MM-DD" placeholder="选择${comment}"> </el-date-picker> </el-form-item> #elseif($column.htmlType == "textarea") <el-form-item label="${comment}" prop="${field}"> <el-input v-model="form.${field}" type="textarea" placeholder="请输入内容" /> </el-form-item> #end #end #end #end </el-form> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="submitForm">确 定</el-button> <el-button @click="cancel">取 消</el-button> </div> </template> </el-dialog> </div> </template> <script setup lang="ts" name="${BusinessName}"> import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}" import type { ${ClassName}, ${BusinessName}QueryParams } from "@/types/api/${moduleName}/${businessName}" import type { TreeSelect } from '@/types/api/common' const { proxy } = getCurrentInstance() #if(${dicts} != '') #set($dictsNoSymbol=$dicts.replace("'", "")) const { ${dictsNoSymbol} } = proxy.useDict(${dicts}) #end const ${businessName}List = ref<any[]>([]) const ${businessName}Options = ref<TreeSelect[]>([]) const open = ref<boolean>(false) const loading = ref<boolean>(true) const showSearch = ref<boolean>(true) const title = ref<string>("") const isExpandAll = ref<boolean>(true) const refreshTable = ref<boolean>(true) #foreach ($column in $columns) #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) const daterange${AttrName} = ref([]) #end #end const data = reactive({ form: {} as ${ClassName}, queryParams: { #foreach ($column in $columns) #if($column.query) $column.javaField: undefined#if($foreach.count != $columns.size()),#end #end #end } as ${BusinessName}QueryParams, rules: { #foreach ($column in $columns) #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: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end } ]#if($foreach.count != $columns.size()),#end #end #end } }) const { queryParams, form, rules } = toRefs(data) /** 查询${functionName}列表 */ function getList() { loading.value = true #foreach ($column in $columns) #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") queryParams.value.params = {} #break #end #end #foreach ($column in $columns) #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) if (null != daterange${AttrName}.value && '' != daterange${AttrName}.value) { queryParams.value.params["begin${AttrName}"] = daterange${AttrName}.value[0] queryParams.value.params["end${AttrName}"] = daterange${AttrName}.value[1] } #end #end list${BusinessName}(queryParams.value).then(response => { ${businessName}List.value = proxy.handleTree(response.data, "${treeCode}", "${treeParentCode}") loading.value = false }) } /** 查询${functionName}下拉树结构 */ function getTreeselect() { list${BusinessName}().then(response => { ${businessName}Options.value = [] const data = { ${treeCode}: 0, ${treeName}: '顶级节点', children: [] } data.children = proxy.handleTree(response.data, "${treeCode}", "${treeParentCode}") ${businessName}Options.value.push(data) }) } // 取消按钮 function cancel() { open.value = false reset() } // 表单重置 function reset() { form.value = { #foreach ($column in $columns) #if($column.htmlType == "checkbox") $column.javaField: []#if($foreach.count != $columns.size()),#end #else $column.javaField: null#if($foreach.count != $columns.size()),#end #end #end } proxy.resetForm("${businessName}Ref") } /** 搜索按钮操作 */ function handleQuery() { getList() } /** 重置按钮操作 */ function resetQuery() { #foreach ($column in $columns) #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) daterange${AttrName}.value = [] #end #end proxy.resetForm("queryRef") handleQuery() } /** 新增按钮操作 */ function handleAdd(row: ${ClassName}) { reset() getTreeselect() if (row != null && row.${treeCode}) { form.value.${treeParentCode} = row.${treeCode} } else { form.value.${treeParentCode} = 0 } open.value = true title.value = "添加${functionName}" } /** 展开/折叠操作 */ function toggleExpandAll() { refreshTable.value = false isExpandAll.value = !isExpandAll.value nextTick(() => { refreshTable.value = true }) } /** 修改按钮操作 */ async function handleUpdate(row: ${ClassName}) { reset() await getTreeselect() if (row != null) { form.value.${treeParentCode} = row.${treeParentCode} } get${BusinessName}(row.${pkColumn.javaField}!).then(response => { form.value = response.data #foreach ($column in $columns) #if($column.htmlType == "checkbox") form.value.$column.javaField = form.value.${column.javaField}.split(",") #end #end open.value = true title.value = "修改${functionName}" }) } /** 提交按钮 */ function submitForm() { proxy.#[[$]]#refs["${businessName}Ref"].validate((valid: boolean) => { if (valid) { #foreach ($column in $columns) #if($column.htmlType == "checkbox") form.value.$column.javaField = form.value.${column.javaField}.join(",") #end #end if (form.value.${pkColumn.javaField} != null) { update${BusinessName}(form.value).then(() => { proxy.#[[$modal]]#.msgSuccess("修改成功") open.value = false getList() }) } else { add${BusinessName}(form.value).then(() => { proxy.#[[$modal]]#.msgSuccess("新增成功") open.value = false getList() }) } } }) } /** 删除按钮操作 */ function handleDelete(row: ${ClassName}) { proxy.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + row.${pkColumn.javaField} + '"的数据项?').then(function() { return del${BusinessName}(row.${pkColumn.javaField}!) }).then(() => { getList() proxy.#[[$modal]]#.msgSuccess("删除成功") }).catch(() => {}) } getList() </script> ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/v3ts/index.vue.vm
New file @@ -0,0 +1,594 @@ <template> <div class="app-container"> <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"> #foreach($column in $columns) #if($column.query) #set($dictType=$column.dictType) #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) #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") <el-form-item label="${comment}" prop="${column.javaField}"> <el-input v-model="queryParams.${column.javaField}" placeholder="请输入${comment}" clearable @keyup.enter="handleQuery" /> </el-form-item> #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType) <el-form-item label="${comment}" prop="${column.javaField}"> <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable> <el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" :value="dict.value" /> </el-select> </el-form-item> #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType) <el-form-item label="${comment}" prop="${column.javaField}"> <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable> <el-option label="请选择字典生成" value="" /> </el-select> </el-form-item> #elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN") <el-form-item label="${comment}" prop="${column.javaField}"> <el-date-picker clearable v-model="queryParams.${column.javaField}" type="date" value-format="YYYY-MM-DD" placeholder="请选择${comment}"> </el-date-picker> </el-form-item> #elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") <el-form-item label="${comment}" style="width: 308px"> <el-date-picker v-model="daterange${AttrName}" value-format="YYYY-MM-DD" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" ></el-date-picker> </el-form-item> #end #end #end <el-form-item> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button> </el-form-item> </el-form> <el-row :gutter="10" class="mb8"> <el-col :span="1.5"> <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['${permissionPrefix}:add']" >新增</el-button> </el-col> <el-col :span="1.5"> <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['${permissionPrefix}:edit']" >修改</el-button> </el-col> <el-col :span="1.5"> <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['${permissionPrefix}:remove']" >删除</el-button> </el-col> <el-col :span="1.5"> <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['${permissionPrefix}:export']" >导出</el-button> </el-col> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> </el-row> <el-table v-loading="loading" :data="${businessName}List" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55" align="center" /> #foreach($column in $columns) #set($javaField=$column.javaField) #set($parentheseIndex=$column.columnComment.indexOf("(")) #if($parentheseIndex != -1) #set($comment=$column.columnComment.substring(0, $parentheseIndex)) #else #set($comment=$column.columnComment) #end #if($column.pk) <el-table-column label="${comment}" align="center" prop="${javaField}" /> #elseif($column.list && $column.htmlType == "datetime") <el-table-column label="${comment}" align="center" prop="${javaField}" width="180"> <template #default="scope"> <span>{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}</span> </template> </el-table-column> #elseif($column.list && $column.htmlType == "imageUpload") <el-table-column label="${comment}" align="center" prop="${javaField}" width="100"> <template #default="scope"> <image-preview :src="scope.row.${javaField}" :width="50" :height="50"/> </template> </el-table-column> #elseif($column.list && "" != $column.dictType) <el-table-column label="${comment}" align="center" prop="${javaField}"> <template #default="scope"> #if($column.htmlType == "checkbox") <dict-tag :options="${column.dictType}" :value="scope.row.${javaField} ? scope.row.${javaField}.split(',') : []"/> #else <dict-tag :options="${column.dictType}" :value="scope.row.${javaField}"/> #end </template> </el-table-column> #elseif($column.list && "" != $javaField) <el-table-column label="${comment}" align="center" prop="${javaField}" /> #end #end <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <template #default="scope"> <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${permissionPrefix}:edit']">修改</el-button> <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${permissionPrefix}:remove']">删除</el-button> </template> </el-table-column> </el-table> <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> <!-- 添加或修改${functionName}对话框 --> <el-dialog :title="title" v-model="open" width="500px" append-to-body> <el-form ref="${businessName}Ref" :model="form" :rules="rules" label-width="80px"> #foreach($column in $columns) #set($field=$column.javaField) #if($column.insert && !$column.pk) #if(($column.usableColumn) || (!$column.superColumn)) #set($parentheseIndex=$column.columnComment.indexOf("(")) #if($parentheseIndex != -1) #set($comment=$column.columnComment.substring(0, $parentheseIndex)) #else #set($comment=$column.columnComment) #end #set($dictType=$column.dictType) #if($column.htmlType == "input") <el-form-item label="${comment}" prop="${field}"> <el-input v-model="form.${field}" placeholder="请输入${comment}" /> </el-form-item> #elseif($column.htmlType == "imageUpload") <el-form-item label="${comment}" prop="${field}"> <image-upload v-model="form.${field}"/> </el-form-item> #elseif($column.htmlType == "fileUpload") <el-form-item label="${comment}" prop="${field}"> <file-upload v-model="form.${field}"/> </el-form-item> #elseif($column.htmlType == "editor") <el-form-item label="${comment}"> <editor v-model="form.${field}" :min-height="192"/> </el-form-item> #elseif($column.htmlType == "select" && "" != $dictType) <el-form-item label="${comment}" prop="${field}"> <el-select v-model="form.${field}" placeholder="请选择${comment}"> <el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" #if($column.javaType == "Integer" || $column.javaType == "Long") :value="parseInt(dict.value)" #else :value="dict.value" #end ></el-option> </el-select> </el-form-item> #elseif($column.htmlType == "select" && $dictType) <el-form-item label="${comment}" prop="${field}"> <el-select v-model="form.${field}" placeholder="请选择${comment}"> <el-option label="请选择字典生成" value="" /> </el-select> </el-form-item> #elseif($column.htmlType == "checkbox" && "" != $dictType) <el-form-item label="${comment}" prop="${field}"> <el-checkbox-group v-model="form.${field}"> <el-checkbox v-for="dict in ${dictType}" :key="dict.value" :label="dict.value"> {{dict.label}} </el-checkbox> </el-checkbox-group> </el-form-item> #elseif($column.htmlType == "checkbox" && $dictType) <el-form-item label="${comment}" prop="${field}"> <el-checkbox-group v-model="form.${field}"> <el-checkbox>请选择字典生成</el-checkbox> </el-checkbox-group> </el-form-item> #elseif($column.htmlType == "radio" && "" != $dictType) <el-form-item label="${comment}" prop="${field}"> <el-radio-group v-model="form.${field}"> <el-radio v-for="dict in ${dictType}" :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long") :label="parseInt(dict.value)" #else :label="dict.value" #end >{{dict.label}}</el-radio> </el-radio-group> </el-form-item> #elseif($column.htmlType == "radio" && $dictType) <el-form-item label="${comment}" prop="${field}"> <el-radio-group v-model="form.${field}"> <el-radio label="1">请选择字典生成</el-radio> </el-radio-group> </el-form-item> #elseif($column.htmlType == "datetime") <el-form-item label="${comment}" prop="${field}"> <el-date-picker clearable v-model="form.${field}" type="date" value-format="YYYY-MM-DD" placeholder="请选择${comment}"> </el-date-picker> </el-form-item> #elseif($column.htmlType == "textarea") <el-form-item label="${comment}" prop="${field}"> <el-input v-model="form.${field}" type="textarea" placeholder="请输入内容" /> </el-form-item> #end #end #end #end #if($table.sub) <el-divider content-position="center">${subTable.functionName}信息</el-divider> <el-row :gutter="10" class="mb8"> <el-col :span="1.5"> <el-button type="primary" icon="Plus" @click="handleAdd${subClassName}">添加</el-button> </el-col> <el-col :span="1.5"> <el-button type="danger" icon="Delete" @click="handleDelete${subClassName}">删除</el-button> </el-col> </el-row> <el-table :data="${subclassName}List" @selection-change="handle${subClassName}SelectionChange" ref="${subclassName}"> <el-table-column type="selection" width="50" align="center" /> <el-table-column label="序号" width="60"> <template #default="{ $index }"> {{ $index + 1 }} </template> </el-table-column> #foreach($column in $subTable.columns) #set($javaField=$column.javaField) #set($parentheseIndex=$column.columnComment.indexOf("(")) #if($parentheseIndex != -1) #set($comment=$column.columnComment.substring(0, $parentheseIndex)) #else #set($comment=$column.columnComment) #end #if($column.pk || $javaField == ${subTableFkclassName}) #elseif($column.list && $column.htmlType == "input") <el-table-column label="$comment" prop="${javaField}" width="150"> <template #default="scope"> <el-input v-model="scope.row.$javaField" placeholder="请输入$comment" /> </template> </el-table-column> #elseif($column.list && $column.htmlType == "datetime") <el-table-column label="$comment" prop="${javaField}" width="240"> <template #default="scope"> <el-date-picker clearable v-model="scope.row.$javaField" type="date" value-format="YYYY-MM-DD" placeholder="请选择$comment"> </el-date-picker> </template> </el-table-column> #elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" != $column.dictType) <el-table-column label="$comment" prop="${javaField}" width="150"> <template #default="scope"> <el-select v-model="scope.row.$javaField" placeholder="请选择$comment"> <el-option v-for="dict in $column.dictType" :key="dict.value" :label="dict.label" :value="dict.value" ></el-option> </el-select> </template> </el-table-column> #elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" == $column.dictType) <el-table-column label="$comment" prop="${javaField}" width="150"> <template #default="scope"> <el-select v-model="scope.row.$javaField" placeholder="请选择$comment"> <el-option label="请选择字典生成" value="" /> </el-select> </template> </el-table-column> #end #end </el-table> #end </el-form> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="submitForm">确 定</el-button> <el-button @click="cancel">取 消</el-button> </div> </template> </el-dialog> </div> </template> <script setup lang="ts" name="Config"> #if($table.sub) import type { ${ClassName}, ${subClassName}, ${BusinessName}QueryParams } from "@/types/api/${moduleName}/${businessName}" #else import type { ${ClassName}, ${BusinessName}QueryParams } from "@/types/api/${moduleName}/${businessName}" #end import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}" const { proxy } = getCurrentInstance() #if(${dicts} != '') #set($dictsNoSymbol=$dicts.replace("'", "")) const { ${dictsNoSymbol} } = proxy.useDict(${dicts}) #end const ${businessName}List = ref<${ClassName}[]>([]) #if($table.sub) const ${subclassName}List = ref([]) #end const open = ref<boolean>(false) const loading = ref<boolean>(true) const showSearch = ref<boolean>(true) const ids = ref<number[]>([]) #if($table.sub) const checked${subClassName} = ref([]) #end const single = ref<boolean>(true) const multiple = ref<boolean>(true) const total = ref<number>(0) const title = ref<string>("") #foreach ($column in $columns) #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) const daterange${AttrName} = ref<string[]>([]) #end #end const data = reactive({ form: {} as ${ClassName}, queryParams: { pageNum: 1, pageSize: 10, #foreach ($column in $columns) #if($column.query) $column.javaField: undefined#if($foreach.count != $columns.size()),#end #end #end } as ${BusinessName}QueryParams, rules: { #foreach ($column in $columns) #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: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end } ]#if($foreach.count != $columns.size()),#end #end #end } }) const { queryParams, form, rules } = toRefs(data) /** 查询${functionName}列表 */ function getList() { loading.value = true #foreach ($column in $columns) #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") queryParams.value.params = {} #break #end #end #foreach ($column in $columns) #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) if (null != daterange${AttrName}.value && '' != daterange${AttrName}.value) { queryParams.value.params["begin${AttrName}"] = daterange${AttrName}.value[0] queryParams.value.params["end${AttrName}"] = daterange${AttrName}.value[1] } #end #end list${BusinessName}(queryParams.value).then(response => { ${businessName}List.value = response.rows total.value = response.total loading.value = false }) } // 取消按钮 function cancel() { open.value = false reset() } // 表单重置 function reset() { form.value = { #foreach ($column in $columns) #if($column.htmlType == "checkbox") $column.javaField: []#if($foreach.count != $columns.size()),#end #else $column.javaField: null#if($foreach.count != $columns.size()),#end #end #end } #if($table.sub) ${subclassName}List.value = [] #end proxy.resetForm("${businessName}Ref") } /** 搜索按钮操作 */ function handleQuery() { queryParams.value.pageNum = 1 getList() } /** 重置按钮操作 */ function resetQuery() { #foreach ($column in $columns) #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) daterange${AttrName}.value = [] #end #end proxy.resetForm("queryRef") handleQuery() } // 多选框选中数据 function handleSelectionChange(selection: ${ClassName}[]) { ids.value = selection.map(item => item.${pkColumn.javaField}) single.value = selection.length != 1 multiple.value = !selection.length } /** 新增按钮操作 */ function handleAdd() { reset() open.value = true title.value = "添加${functionName}" } /** 修改按钮操作 */ function handleUpdate(row: ${ClassName}) { reset() const _${pkColumn.javaField} = row.${pkColumn.javaField} || ids.value[0] get${BusinessName}(_${pkColumn.javaField}).then(response => { form.value = response.data #foreach ($column in $columns) #if($column.htmlType == "checkbox") form.value.$column.javaField = form.value.${column.javaField}.split(",") #end #end #if($table.sub) ${subclassName}List.value = response.data?.${subclassName}List ?? [] #end open.value = true title.value = "修改${functionName}" }) } /** 提交按钮 */ function submitForm() { proxy.#[[$]]#refs["${businessName}Ref"].validate((valid: boolean) => { if (valid) { #foreach ($column in $columns) #if($column.htmlType == "checkbox") form.value.$column.javaField = form.value.${column.javaField}.join(",") #end #end #if($table.sub) form.value.${subclassName}List = ${subclassName}List.value #end if (form.value.${pkColumn.javaField} != null) { update${BusinessName}(form.value).then(() => { proxy.#[[$modal]]#.msgSuccess("修改成功") open.value = false getList() }) } else { add${BusinessName}(form.value).then(() => { proxy.#[[$modal]]#.msgSuccess("新增成功") open.value = false getList() }) } } }) } /** 删除按钮操作 */ function handleDelete(row: ${ClassName}) { const _${pkColumn.javaField}s = row.${pkColumn.javaField} || ids.value proxy.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + _${pkColumn.javaField}s + '"的数据项?').then(function() { return del${BusinessName}(_${pkColumn.javaField}s) }).then(() => { getList() proxy.#[[$modal]]#.msgSuccess("删除成功") }).catch(() => {}) } #if($table.sub) /** ${subTable.functionName}添加按钮操作 */ function handleAdd${subClassName}() { let obj: ${subClassName} = {} #foreach($column in $subTable.columns) #if($column.pk || $column.javaField == ${subTableFkclassName}) #elseif($column.list && "" != $javaField) obj.$column.javaField = undefined #end #end ${subclassName}List.value.push(obj) } /** ${subTable.functionName}删除按钮操作 */ function handleDelete${subClassName}() { if (checked${subClassName}.value.length == 0) { proxy.#[[$modal]]#.msgError("请先选择要删除的${subTable.functionName}数据") } else { const ${subclassName}s = ${subclassName}List.value const checked${subClassName}s = checked${subClassName}.value ${subclassName}List.value = ${subclassName}s.filter(function(item: any) { return checked${subClassName}s.indexOf(item.index) == -1 }) } } /** 复选框选中数据 */ function handle${subClassName}SelectionChange(selection: any[]) { checked${subClassName}.value = selection.map(item => item.index) } #end /** 导出按钮操作 */ function handleExport() { proxy.download('${moduleName}/${businessName}/export', { ...queryParams.value }, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`) } getList() </script> ruoyi-ui/src/views/tool/gen/genInfoForm.vue
@@ -17,6 +17,7 @@ <el-select v-model="info.tplWebType"> <el-option label="Vue2 Element UI 模版" value="element-ui" /> <el-option label="Vue3 Element Plus 模版" value="element-plus" /> <el-option label="Vue3 Element Plus TypeScript 模版" value="element-plus-typescript" /> </el-select> </el-form-item> </el-col> ruoyi-ui/src/views/tool/gen/importTable.vue
@@ -107,7 +107,7 @@ this.$modal.msgError("请选择要导入的表") return } importTable({ tables: tableNames }).then(res => { importTable({ tables: tableNames, tplWebType: 'element-ui' }).then(res => { this.$modal.msgSuccess(res.msg) if (res.code === 200) { this.visible = false ruoyi-ui/src/views/tool/gen/index.vue
@@ -167,6 +167,7 @@ hljs.registerLanguage("html", require("highlight.js/lib/languages/xml")) hljs.registerLanguage("vue", require("highlight.js/lib/languages/xml")) hljs.registerLanguage("javascript", require("highlight.js/lib/languages/javascript")) hljs.registerLanguage("typescript", require("highlight.js/lib/languages/typescript")) hljs.registerLanguage("sql", require("highlight.js/lib/languages/sql")) export default {