Compare commits

...

10 Commits

Author SHA1 Message Date
2814a4e655 refactor(clinic): 移除诊所模块的控制器和实体类
- 移除 ClinicAppointmentController 挂号控制器
- 移除 ClinicDoctorApplyController 医生入驻申请控制器
- 移除 ClinicDoctorUserController 分销商用户记录表控制器
- 移除 ClinicPatientUserController 患者控制器
- 移除 ClinicPrescriptionController 处方主表控制器
- 移除 ClinicPrescriptionItemController 处方明细表控制器
- 移除 ClinicAppointment 挂号实体类
- 移除 ClinicDoctorApply 医生入驻申请实体类
- 移除 ClinicDoctorUser 分销商用户记录表实体类
- 移除 ClinicPatientUser 患者实体类
2026-01-08 13:56:23 +08:00
8aa814a2a4 feat(clinic): 添加处方主表和明细表功能模块- 新增处方主表和明细表的实体类定义
- 实现处方主表和明细表的CRUD控制器- 创建处方主表和明细表的Mapper接口及XML映射文件
- 添加处方主表和明细表的Service接口及实现类
- 完成处方主表和明细表的查询参数封装
-修正前端页面中row-key及删除方法的字段引用问题- 更新代码生成器模板以适配新的主键字段命名规则
2025-10-22 02:03:35 +08:00
7bf80cb179 feat(admin): 移除管理员界面的旧版 SVG 图标- 删除了位于 /dict/admin/public/assets/ 目录下的 logo.svg 文件- 清理了项目中不再使用的图标资源
- 减少了前端静态资源体积
-为后续引入新版图标系统做准备
- 更新了相关引用路径(如有)- 确保移除后功能正常运行且无报错
2025-10-19 09:31:25 +08:00
ba6896855a feat(admin): 添加管理后台logo文件- 新增128x128尺寸的SVG格式logo文件
- 使用Method Draw工具创建矢量图形
- 包含背景层和图层1的基础结构
- 支持透明背景显示
- 为管理后台界面提供品牌标识- 便于后续UI组件中引用和展示
2025-10-18 09:16:51 +08:00
4c7a7e2452 refactor(entity):优化实体类模板注解生成逻辑
- 移除了时间类型字段的冗余声明注解
- 合并了条件判断逻辑,减少嵌套层级- 调整了注释与注解的排列顺序
- 统一处理字段注解生成流程
- 简化了主键和填充字段的注解条件判断
-优化了代码格式,提高可读性
2025-10-16 20:42:29 +08:00
c61fe0c3bf feat(generator):为不同时间类型字段添加特定日期格式化注解
- 为 LocalDateTime 类型字段添加 "yyyy-MM-dd HH:mm:ss" 格式
-为 LocalDate 类型字段添加 "yyyy-MM-dd" 格式- 为 LocalTime 类型字段添加 "HH:mm:ss" 格式
- 为 Date 类型字段保留原有 "yyyy-MM-dd HH:mm:ss" 格式- 优化时间字段格式化逻辑,提高代码可读性
2025-10-16 20:39:08 +08:00
c2df93faeb feat(generator):为不同时间类型字段添加特定日期格式化注解
- 为 LocalDateTime 类型字段添加 "yyyy-MM-dd HH:mm:ss" 格式
-为 LocalDate 类型字段添加 "yyyy-MM-dd" 格式- 为 LocalTime 类型字段添加 "HH:mm:ss" 格式
- 为 Date 类型字段保留原有 "yyyy-MM-dd HH:mm:ss" 格式- 优化时间字段格式化逻辑,提高代码可读性
2025-10-16 20:34:41 +08:00
e65003ddb3 feat(generator):为时间类型字段添加日期格式化注解
- 在实体类模板中为LocalDateTime、LocalDate、LocalTime和Date类型字段添加@JsonFormat注解
- 设置默认日期格式为"yyyy-MM-dd HH:mm:ss"- 确保生成的实体类能正确序列化和反序列化时间字段
2025-10-16 20:34:06 +08:00
d92b81ab55 feat(web): 新增 BaseController 基类并优化代码生成模板
- 添加 BaseController 基类,包含常用方法如获取登录用户、租户ID等
- 实现统一的 ApiResult 返回结果处理方法
- 添加请求参数空字符串转 null 的处理逻辑- 新增方法参数类型转换异常的统一处理机制
- 更新代码生成器模板,将 ID 类型从 Integer 改为 Long
- 修改代码生成器配置,使用新的 BaseController 替代 SimpleBaseController
- 优化 HTTP 请求头获取逻辑,支持大小写兼容的 AppId 获取方式
2025-10-16 20:29:43 +08:00
ed6bb2772f feat(web): 新增 BaseController 基类并优化代码生成模板
- 添加 BaseController 基类,包含常用方法如获取登录用户、租户ID等
- 实现统一的 ApiResult 返回结果处理方法
- 添加请求参数空字符串转 null 的处理逻辑- 新增方法参数类型转换异常的统一处理机制
- 更新代码生成器模板,将 ID 类型从 Integer 改为 Long
- 修改代码生成器配置,使用新的 BaseController 替代 SimpleBaseController
- 优化 HTTP 请求头获取逻辑,支持大小写兼容的 AppId 获取方式
2025-10-16 20:29:33 +08:00
7 changed files with 662 additions and 133 deletions

View File

@@ -0,0 +1,221 @@
package com.gxwebsoft.common.core.web;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.common.core.Constants;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* Controller基类
*
* @author WebSoft
* @since 2017-06-10 10:10:19
*/
public class BaseController {
@Resource
private HttpServletRequest request;
@Resource
// private RedisUtil redisUtil;
/**
* 获取当前登录的user
*
* @return User
*/
// public User getLoginUser() {
// try {
// Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
// if (authentication != null) {
// Object object = authentication.getPrincipal();
// if (object instanceof User) {
// return (User) object;
// }
// }
// } catch (Exception e) {
// System.out.println(e.getMessage());
// }
// return null;
// }
/**
* 获取当前登录的userId
*
* @return userId
*/
public Integer getLoginUserId() {
return null;
}
/**
* 获取当前登录的tenantId
*
* @return tenantId
*/
public Integer getTenantId() {
String tenantId;
// 2 从请求头拿ID
tenantId = request.getHeader("tenantId");
if(StrUtil.isNotBlank(tenantId)){
return Integer.valueOf(tenantId);
}
return null;
}
/**
* 返回成功
*
* @return ApiResult
*/
public ApiResult<?> success() {
return new ApiResult<>(Constants.RESULT_OK_CODE, Constants.RESULT_OK_MSG);
}
/**
* 返回成功
*
* @param message 状态信息
* @return ApiResult
*/
public ApiResult<?> success(String message) {
return success().setMessage(message);
}
/**
* 返回成功
*
* @param data 返回数据
* @return ApiResult
*/
public <T> ApiResult<T> success(T data) {
return new ApiResult<>(Constants.RESULT_OK_CODE, Constants.RESULT_OK_MSG, data);
}
/**
* 返回成功
*
* @param message 状态信息
* @return ApiResult
*/
public <T> ApiResult<T> success(String message, T data) {
return success(data).setMessage(message);
}
/**
* 返回分页查询数据
*
* @param list 当前页数据
* @param count 总数量
* @return ApiResult
*/
public <T> ApiResult<PageResult<T>> success(List<T> list, Long count) {
return success(new PageResult<>(list, count));
}
/**
* 返回分页查询数据
*
* @param iPage IPage
* @return ApiResult
*/
public <T> ApiResult<PageResult<T>> success(IPage<T> iPage) {
return success(iPage.getRecords(), iPage.getTotal());
}
/**
* 返回失败
*
* @return ApiResult
*/
public ApiResult<?> fail() {
return new ApiResult<>(Constants.RESULT_ERROR_CODE, Constants.RESULT_ERROR_MSG);
}
/**
* 返回失败
*
* @param message 状态信息
* @return ApiResult
*/
public ApiResult<?> fail(String message) {
return fail().setMessage(message);
}
/**
* 返回失败
*
* @param data 返回数据
* @return ApiResult
*/
public <T> ApiResult<T> fail(T data) {
return fail(Constants.RESULT_ERROR_MSG, data);
}
/**
* 返回失败
*
* @param message 状态信息
* @param data 返回数据
* @return ApiResult
*/
public <T> ApiResult<T> fail(String message, T data) {
return new ApiResult<>(Constants.RESULT_ERROR_CODE, message, data);
}
/**
* 请求参数的空字符串转为null
*/
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
}
// 自定义函数
public String getAuthorization(){
return request.getHeader("Authorization");
}
public String getAppId() {
// 兼容小写
if(request.getHeader("appid") != null){
return request.getHeader("appid");
}
return request.getHeader("AppId");
}
/**
* 处理方法参数类型转换异常
* 主要处理URL路径参数中传入"NaN"等无法转换为Integer的情况
*
* @param ex 方法参数类型不匹配异常
* @return ApiResult
*/
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ApiResult<?> handleMethodArgumentTypeMismatch(MethodArgumentTypeMismatchException ex) {
String parameterName = ex.getName();
Object value = ex.getValue();
Class<?> requiredType = ex.getRequiredType();
// 记录错误日志
System.err.println("参数类型转换异常: 参数名=" + parameterName +
", 传入值=" + value +
", 期望类型=" + (requiredType != null ? requiredType.getSimpleName() : "unknown"));
// 如果是ID参数且传入的是"NaN",返回友好的错误信息
if ("id".equals(parameterName) && "NaN".equals(String.valueOf(value))) {
return fail("无效的ID参数请检查传入的ID值");
}
// 其他类型转换错误的通用处理
return fail("参数格式错误: " + parameterName + " 的值 '" + value + "' 无法转换为 " +
(requiredType != null ? requiredType.getSimpleName() : "目标类型"));
}
}

View File

@@ -1,52 +0,0 @@
package com.gxwebsoft.common.core.web;
import org.springframework.web.bind.annotation.RestController;
/**
* 简化版控制器基类,用于代码生成
* Created by WebSoft on 2019-10-29 15:55
*/
@RestController
public class SimpleBaseController {
/**
* 响应成功结果
*
* @param data 数据内容
* @param <T> 数据类型
* @return 响应结果
*/
protected <T> ApiResult<T> success(T data) {
return new ApiResult<T>(0, "操作成功", data);
}
/**
* 响应成功结果
*
* @return 响应结果
*/
protected ApiResult<String> success(String message) {
return new ApiResult<String>(0, message, null);
}
/**
* 响应失败结果
*
* @param message 错误信息
* @return 响应结果
*/
protected ApiResult<String> fail(String message) {
return new ApiResult<String>(1, message, null);
}
/**
* 响应失败结果
*
* @param code 错误码
* @param message 错误信息
* @return 响应结果
*/
protected ApiResult<String> fail(int code, String message) {
return new ApiResult<String>(code, message, null);
}
}

View File

@@ -7,7 +7,7 @@ server:
# 数据源配置
spring:
datasource:
url: jdbc:mysql://8.134.169.209:13306/modules?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
url: jdbc:mysql://47.119.165.234:13308/modules?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
username: modules
password: P7KsAyDXG8YdLnkA
driver-class-name: com.mysql.cj.jdbc.Driver
@@ -16,7 +16,7 @@ spring:
# redis
redis:
database: 0
host: 8.134.169.209
host: 47.119.165.234
port: 16379
password: redis_WSDb88

View File

@@ -31,9 +31,9 @@ public class ClinicGenerator {
// JAVA输出目录
private static final String OUTPUT_DIR = "/src/main/java";
// Vue文件输出位置
private static final String OUTPUT_LOCATION_VUE = "/Users/gxwebsoft/VUE/generator-vue";
private static final String OUTPUT_LOCATION_VUE = "/Users/gxwebsoft/JAVA/generator/output/admin";
// UniApp文件输出目录
private static final String OUTPUT_LOCATION_UNIAPP = "/Users/gxwebsoft/APP/template-10001";
private static final String OUTPUT_LOCATION_UNIAPP = "/Users/gxwebsoft/JAVA/generator/output/taro";
// Vue文件输出目录
private static final String OUTPUT_DIR_VUE = "/src";
// 作者名称
@@ -51,7 +51,7 @@ public class ClinicGenerator {
private static final String MODULE_NAME = "clinic";
// 需要生成的表
private static final String[] TABLE_NAMES = new String[]{
"clinic_appointment",
// "clinic_appointment",
// "clinic_doctor_apply",
// "clinic_doctor_medical_record",
// "clinic_doctor_user",
@@ -65,6 +65,7 @@ public class ClinicGenerator {
// "clinic_prescription_item",
// "clinic_report",
// "clinic_visit_record",
"clinic_",
};
// 需要去除的表前缀
private static final String[] TABLE_PREFIX = new String[]{
@@ -135,7 +136,7 @@ public class ClinicGenerator {
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setInclude(TABLE_NAMES);
strategy.setTablePrefix(TABLE_PREFIX);
strategy.setSuperControllerClass(PACKAGE_NAME + ".common.core.web.SimpleBaseController");
strategy.setSuperControllerClass(PACKAGE_NAME + ".common.core.web.BaseController");
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);

View File

@@ -0,0 +1,407 @@
package com.gxwebsoft.generator;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.gxwebsoft.generator.engine.BeetlTemplateEnginePlus;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* CMS模块-代码生成工具
*
* @author WebSoft
* @since 2021-09-05 00:31:14
*/
public class CreditGenerator {
// 输出位置
private static final String OUTPUT_LOCATION = System.getProperty("user.dir");
//private static final String OUTPUT_LOCATION = "D:/codegen"; // 不想生成到项目中可以写磁盘路径
// JAVA输出目录
private static final String OUTPUT_DIR = "/src/main/java";
// Vue文件输出位置
private static final String OUTPUT_LOCATION_VUE = "/Users/gxwebsoft/JAVA/generator/output/admin";
// UniApp文件输出目录
private static final String OUTPUT_LOCATION_UNIAPP = "/Users/gxwebsoft/JAVA/generator/output/taro";
// Vue文件输出目录
private static final String OUTPUT_DIR_VUE = "/src";
// 作者名称
private static final String AUTHOR = "科技小王子";
// 是否在xml中添加二级缓存配置
private static final boolean ENABLE_CACHE = false;
// 数据库连接配置
private static final String DB_URL = "jdbc:mysql://47.119.165.234:13308/modules?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8";
private static final String DB_DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String DB_USERNAME = "modules";
private static final String DB_PASSWORD = "P7KsAyDXG8YdLnkA";
// 包名
private static final String PACKAGE_NAME = "com.gxwebsoft";
// 模块名
private static final String MODULE_NAME = "credit";
// 需要生成的表
private static final String[] TABLE_NAMES = new String[]{
// "credit_user",
// "credit_judiciary",
// "credit_company",
// "credit_breach_of_trust",
// "credit_case_filing",
// "credit_company",
// "credit_competitor",
// "credit_court_announcement",
// "credit_court_session",
// "credit_customer",
// "credit_delivery_notice",
// "credit_external",
// "credit_final_version",
// "credit_gqdj",
// "credit_judgment_debtor",
// "credit_judicial_document",
// "credit_mediation",
// "credit_risk_relation",
// "credit_supplier",
// "credit_xgxf",
"credit_administrative_license",
"credit_bankruptcy",
"credit_branch",
"credit_historical_legal_person",
"credit_nearby_company",
"credit_patent",
"credit_suspected_relationship"
};
// 需要去除的表前缀
private static final String[] TABLE_PREFIX = new String[]{
"tb_"
};
// 不需要作为查询参数的字段
private static final String[] PARAM_EXCLUDE_FIELDS = new String[]{
"tenant_id",
"create_time",
"update_time"
};
// 查询参数使用String的类型
private static final String[] PARAM_TO_STRING_TYPE = new String[]{
"Date",
"LocalDate",
"LocalTime",
"LocalDateTime"
};
// 查询参数使用EQ的类型
private static final String[] PARAM_EQ_TYPE = new String[]{
"Integer",
"Boolean",
"BigDecimal"
};
// 是否添加权限注解
private static final boolean AUTH_ANNOTATION = true;
// 是否添加日志注解
private static final boolean LOG_ANNOTATION = true;
// controller的mapping前缀
private static final String CONTROLLER_MAPPING_PREFIX = "/api";
// 模板所在位置
private static final String TEMPLATES_DIR = "/src/test/java/com/gxwebsoft/generator/templates";
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
gc.setOutputDir(OUTPUT_LOCATION + OUTPUT_DIR);
gc.setAuthor(AUTHOR);
gc.setOpen(false);
gc.setFileOverride(true);
gc.setEnableCache(ENABLE_CACHE);
gc.setSwagger2(true);
gc.setIdType(IdType.AUTO);
gc.setServiceName("%sService");
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl(DB_URL);
// dsc.setSchemaName("public");
dsc.setDriverName(DB_DRIVER);
dsc.setUsername(DB_USERNAME);
dsc.setPassword(DB_PASSWORD);
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName(MODULE_NAME);
pc.setParent(PACKAGE_NAME);
mpg.setPackageInfo(pc);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setInclude(TABLE_NAMES);
strategy.setTablePrefix(TABLE_PREFIX);
strategy.setSuperControllerClass(PACKAGE_NAME + ".common.core.web.BaseController");
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);
strategy.setLogicDeleteFieldName("deleted");
mpg.setStrategy(strategy);
// 模板配置
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setController(TEMPLATES_DIR + "/controller.java");
templateConfig.setEntity(TEMPLATES_DIR + "/entity.java");
templateConfig.setMapper(TEMPLATES_DIR + "/mapper.java");
templateConfig.setXml(TEMPLATES_DIR + "/mapper.xml");
templateConfig.setService(TEMPLATES_DIR + "/service.java");
templateConfig.setServiceImpl(TEMPLATES_DIR + "/serviceImpl.java");
mpg.setTemplate(templateConfig);
mpg.setTemplateEngine(new BeetlTemplateEnginePlus());
// 自定义模板配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
Map<String, Object> map = new HashMap<>();
map.put("packageName", PACKAGE_NAME);
map.put("paramExcludeFields", PARAM_EXCLUDE_FIELDS);
map.put("paramToStringType", PARAM_TO_STRING_TYPE);
map.put("paramEqType", PARAM_EQ_TYPE);
map.put("authAnnotation", AUTH_ANNOTATION);
map.put("logAnnotation", LOG_ANNOTATION);
map.put("controllerMappingPrefix", CONTROLLER_MAPPING_PREFIX);
// 添加项目类型标识,用于模板中的条件判断
map.put("isUniApp", false); // Vue 项目
map.put("isVueAdmin", true); // 后台管理项目
this.setMap(map);
}
};
String templatePath = TEMPLATES_DIR + "/param.java.btl";
List<FileOutConfig> focList = new ArrayList<>();
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION + OUTPUT_DIR + "/"
+ PACKAGE_NAME.replace(".", "/")
+ "/" + pc.getModuleName() + "/param/"
+ tableInfo.getEntityName() + "Param" + StringPool.DOT_JAVA;
}
});
/**
* 以下是生成VUE项目代码
* 生成文件的路径 /api/shop/goods/index.ts
*/
templatePath = TEMPLATES_DIR + "/index.ts.btl";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE
+ "/api/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/" + "index.ts";
}
});
// UniApp 使用专门的模板
String uniappTemplatePath = TEMPLATES_DIR + "/index.ts.uniapp.btl";
focList.add(new FileOutConfig(uniappTemplatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE
+ "/api/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/" + "index.ts";
}
});
// 生成TS文件 (/api/shop/goods/model/index.ts)
templatePath = TEMPLATES_DIR + "/model.ts.btl";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE
+ "/api/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/model/" + "index.ts";
}
});
// UniApp 使用专门的 model 模板
String uniappModelTemplatePath = TEMPLATES_DIR + "/model.ts.uniapp.btl";
focList.add(new FileOutConfig(uniappModelTemplatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE
+ "/api/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/model/" + "index.ts";
}
});
// 生成Vue文件(/views/shop/goods/index.vue)
templatePath = TEMPLATES_DIR + "/index.vue.btl";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE
+ "/views/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/" + "index.vue";
}
});
// 生成components文件(/views/shop/goods/components/edit.vue)
templatePath = TEMPLATES_DIR + "/components.edit.vue.btl";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE
+ "/views/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/components/" + tableInfo.getEntityPath() + "Edit.vue";
}
});
// 生成components文件(/views/shop/goods/components/search.vue)
templatePath = TEMPLATES_DIR + "/components.search.vue.btl";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE
+ "/views/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/components/" + "search.vue";
}
});
// ========== 移动端页面文件生成 ==========
// 生成移动端列表页面配置文件 (/src/shop/goods/index.config.ts)
templatePath = TEMPLATES_DIR + "/index.config.ts.btl";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE
+ "/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/" + "index.config.ts";
}
});
// 生成移动端列表页面组件文件 (/src/shop/goods/index.tsx)
templatePath = TEMPLATES_DIR + "/index.tsx.btl";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE
+ "/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/" + "index.tsx";
}
});
// 生成移动端新增/编辑页面配置文件 (/src/shop/goods/add.config.ts)
templatePath = TEMPLATES_DIR + "/add.config.ts.btl";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE
+ "/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/" + "add.config.ts";
}
});
// 生成移动端新增/编辑页面组件文件 (/src/shop/goods/add.tsx)
templatePath = TEMPLATES_DIR + "/add.tsx.btl";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE
+ "/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/" + "add.tsx";
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
mpg.execute();
// 自动更新 app.config.ts
updateAppConfig(TABLE_NAMES, MODULE_NAME);
}
/**
* 自动更新 app.config.ts 文件,添加新生成的页面路径
*/
private static void updateAppConfig(String[] tableNames, String moduleName) {
String appConfigPath = OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE + "/app.config.ts";
try {
// 读取原文件内容
String content = new String(Files.readAllBytes(Paths.get(appConfigPath)));
// 为每个表生成页面路径
StringBuilder newPages = new StringBuilder();
for (String tableName : tableNames) {
String entityPath = tableName.replaceAll("_", "");
// 转换为驼峰命名
String[] parts = tableName.split("_");
StringBuilder camelCase = new StringBuilder(parts[0]);
for (int i = 1; i < parts.length; i++) {
camelCase.append(parts[i].substring(0, 1).toUpperCase()).append(parts[i].substring(1));
}
entityPath = camelCase.toString();
newPages.append(" '").append(entityPath).append("/index',\n");
newPages.append(" '").append(entityPath).append("/add',\n");
}
// 查找对应模块的子包配置
String modulePattern = "\"root\":\\s*\"" + moduleName + "\",\\s*\"pages\":\\s*\\[([^\\]]*)]";
Pattern pattern = Pattern.compile(modulePattern, Pattern.DOTALL);
Matcher matcher = pattern.matcher(content);
if (matcher.find()) {
String existingPages = matcher.group(1);
// 检查页面是否已存在,避免重复添加
boolean needUpdate = false;
String[] newPageArray = newPages.toString().split("\n");
for (String newPage : newPageArray) {
if (!newPage.trim().isEmpty() && !existingPages.contains(newPage.trim().replace(" ", "").replace(",", ""))) {
needUpdate = true;
break;
}
}
if (needUpdate) {
// 备份原文件
String backupPath = appConfigPath + ".backup." + System.currentTimeMillis();
Files.copy(Paths.get(appConfigPath), Paths.get(backupPath));
System.out.println("已备份原文件到: " + backupPath);
// 在现有页面列表末尾添加新页面
String updatedPages = existingPages.trim();
if (!updatedPages.endsWith(",")) {
updatedPages += ",";
}
updatedPages += "\n" + newPages.toString().trim();
// 替换内容
String updatedContent = content.replace(matcher.group(1), updatedPages);
// 写入更新后的内容
Files.write(Paths.get(appConfigPath), updatedContent.getBytes());
System.out.println("✅ 已自动更新 app.config.ts添加了以下页面路径:");
System.out.println(newPages.toString());
} else {
System.out.println(" app.config.ts 中已包含所有页面路径,无需更新");
}
} else {
System.out.println("⚠️ 未找到 " + moduleName + " 模块的子包配置,请手动添加页面路径");
}
} catch (Exception e) {
System.err.println("❌ 更新 app.config.ts 失败: " + e.getMessage());
e.printStackTrace();
}
}
}

View File

@@ -13,6 +13,8 @@ import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
<% } %>
<% } %>
<% /* 为时间类型字段添加日期格式化注解的导入 */ %>
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* ${table.comment!}
@@ -48,64 +50,34 @@ public class ${entity} implements Serializable {
private static final long serialVersionUID = 1L;
<% } %>
<% /** -----------BEGIN 字段循环遍历----------- **/ %>
<% for(field in table.fields) { %>
<%
var keyPropertyName;
if(field.keyFlag) {
keyPropertyName = field.propertyName;
}
%>
<% for(field in table.fields) {
var keyPropertyName = field.keyFlag ? field.propertyName : null;
%>
<% if(isNotEmpty(field.comment)) { %>
<% if(swagger2) { %>
@Schema(description = "${field.comment}")
<% }else{ %>
/**
<% if(isNotEmpty(field.comment)) { %><% if(swagger2) { %> @Schema(description = "${field.comment}")
<% }else{ %> /**
* ${field.comment}
*/
<% } %>
<% } %>
<% /* 主键 */ %>
<% if(field.keyFlag) { %>
<% if(field.keyIdentityFlag) { %>
@TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
<% } else if(isNotEmpty(idType)) { %>
@TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
<% } else if(field.convert) { %>
@TableId("${field.annotationColumnName}")
<% } %>
<% /* 普通字段 */ %>
<% } else if(isNotEmpty(field.fill)) { %>
<% if(field.convert){ %>
@TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
<% }else{ %>
@TableField(fill = FieldFill.${field.fill})
<% } %>
<% } else if(field.convert) { %>
@TableField("${field.annotationColumnName}")
<% } %>
<% /* 乐观锁注解 */ %>
<% if(versionFieldName!'' == field.name) { %>
@Version
<% } %>
<% /* 逻辑删除注解 */ %>
<% if(logicDeleteFieldName!'' == field.name) { %>
@TableLogic
<% } %>
private ${field.propertyType} ${field.propertyName};
<% } %><% } %><% /* 为时间类型字段添加日期格式化注解 */ %><% if(field.propertyType == 'LocalDateTime' || field.propertyType == 'LocalDate' || field.propertyType == 'LocalTime' || field.propertyType == 'Date') { %><% if(field.propertyType == 'LocalDateTime') { %> @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
<% } else if(field.propertyType == 'LocalDate') { %> @JsonFormat(pattern = "yyyy-MM-dd")
<% } else if(field.propertyType == 'LocalTime') { %> @JsonFormat(pattern = "HH:mm:ss")
<% } else if(field.propertyType == 'Date') { %> @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
<% } %><% } %><% /* 添加其他注解(主键、字段填充等) */ %><% if(field.keyFlag) { %><% if(field.keyIdentityFlag) { %> @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
<% } else if(isNotEmpty(idType)) { %> @TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
<% } else if(field.convert) { %> @TableId("${field.annotationColumnName}")
<% } %><% } else if(isNotEmpty(field.fill)) { %><% if(field.convert){ %> @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
<% }else{ %> @TableField(fill = FieldFill.${field.fill})
<% } %><% } else if(field.convert) { %> @TableField("${field.annotationColumnName}")
<% } %><% if(versionFieldName!'' == field.name) { %> @Version
<% } %><% if(logicDeleteFieldName!'' == field.name) { %> @TableLogic
<% } %> private ${field.propertyType} ${field.propertyName};
<% } %>
<% /** -----------END 字段循环遍历----------- **/ %>
<% if(!entityLombokModel) { %>
<% for(field in table.fields) { %>
<%
var getprefix = '';
if(field.propertyType == 'boolean') {
getprefix = 'is';
} else {
getprefix = 'get';
}
%>
<% for(field in table.fields) {
var getprefix = field.propertyType == 'boolean' ? 'is' : 'get';
%>
public ${field.propertyType} ${getprefix}${field.capitalName}() {
return ${field.propertyName};
}

View File

@@ -3,7 +3,7 @@
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="${table.entityPath}Id"
row-key="id"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
@@ -98,7 +98,7 @@
};
// 完整的列配置(包含所有字段)
const allColumns = ref<ColumnItem[]>([
const columns = ref<ColumnItem[]>([
<% for(field in table.fields) { %>
<% if(field.propertyName != 'tenantId'){ %>
{
@@ -133,26 +133,6 @@
}
]);
// 默认显示的核心列最多5个主要字段
const defaultVisibleColumns = [
<% var count = 0; %>
<% for(field in table.fields) { %>
<% if(field.keyFlag || field.propertyName == 'name' || field.propertyName == 'title' || field.propertyName == 'status' || field.propertyName == 'createTime'){ %>
'${field.propertyName}',
<% count = count + 1; %>
<% if(count >= 5) break; %>
<% } %>
<% } %>
'action'
];
// 根据默认可见列过滤显示的列
const columns = computed(() => {
return allColumns.value.filter(col =>
defaultVisibleColumns.includes(col.dataIndex) || col.key === 'action'
);
});
/* 搜索 */
const reload = (where?: ${entity}Param) => {
selection.value = [];
@@ -173,7 +153,7 @@
/* 删除单个 */
const remove = (row: ${entity}) => {
const hide = message.loading('请求中..', 0);
remove${entity}(row.${table.entityPath}Id)
remove${entity}(row.id)
.then((msg) => {
hide();
message.success(msg);
@@ -198,7 +178,7 @@
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatch${entity}(selection.value.map((d) => d.${table.entityPath}Id))
removeBatch${entity}(selection.value.map((d) => d.id))
.then((msg) => {
hide();
message.success(msg);