Commit ab8e9d2dc41eb0fe2efad4d3f9c0f58220a99349
1 parent
7b4fbe38
refactor: remove dead code (unused accessors/methods, exception dtos, ErrorCode trim)
Showing
13 changed files
with
13 additions
and
230 deletions
src/main/java/com/xly/agent/AgentIdentity.java
| ... | ... | @@ -17,20 +17,13 @@ public final class AgentIdentity { |
| 17 | 17 | |
| 18 | 18 | private final String token; |
| 19 | 19 | private final String userId; |
| 20 | - private final String userNo; | |
| 21 | 20 | private final String brandsId; |
| 22 | - private final String subsidiaryId; | |
| 23 | - private final String userType; | |
| 24 | 21 | private final Set<String> grantedModuleIds; // null = 全部(管理员) |
| 25 | 22 | |
| 26 | - public AgentIdentity(String token, String userId, String userNo, String brandsId, | |
| 27 | - String subsidiaryId, String userType, Set<String> grantedModuleIds) { | |
| 23 | + public AgentIdentity(String token, String userId, String brandsId, Set<String> grantedModuleIds) { | |
| 28 | 24 | this.token = token; |
| 29 | 25 | this.userId = userId; |
| 30 | - this.userNo = userNo; | |
| 31 | 26 | this.brandsId = brandsId; |
| 32 | - this.subsidiaryId = subsidiaryId; | |
| 33 | - this.userType = userType; | |
| 34 | 27 | this.grantedModuleIds = grantedModuleIds; |
| 35 | 28 | } |
| 36 | 29 | |
| ... | ... | @@ -39,39 +32,14 @@ public final class AgentIdentity { |
| 39 | 32 | return token; |
| 40 | 33 | } |
| 41 | 34 | |
| 42 | - public boolean hasUserToken() { | |
| 43 | - return token != null && !token.isBlank(); | |
| 44 | - } | |
| 45 | - | |
| 46 | 35 | public String userId() { |
| 47 | 36 | return userId; |
| 48 | 37 | } |
| 49 | 38 | |
| 50 | - public String userNo() { | |
| 51 | - return userNo; | |
| 52 | - } | |
| 53 | - | |
| 54 | 39 | public String brandsId() { |
| 55 | 40 | return brandsId; |
| 56 | 41 | } |
| 57 | 42 | |
| 58 | - public String subsidiaryId() { | |
| 59 | - return subsidiaryId; | |
| 60 | - } | |
| 61 | - | |
| 62 | - public String userType() { | |
| 63 | - return userType; | |
| 64 | - } | |
| 65 | - | |
| 66 | - /** null = 全部权限(管理员)。 */ | |
| 67 | - public Set<String> grantedModuleIds() { | |
| 68 | - return grantedModuleIds; | |
| 69 | - } | |
| 70 | - | |
| 71 | - public boolean isAdminAll() { | |
| 72 | - return grantedModuleIds == null; | |
| 73 | - } | |
| 74 | - | |
| 75 | 43 | public boolean canAccessModule(String moduleId) { |
| 76 | 44 | return grantedModuleIds == null || (moduleId != null && grantedModuleIds.contains(moduleId)); |
| 77 | 45 | } | ... | ... |
src/main/java/com/xly/agent/Intent.java
| ... | ... | @@ -41,11 +41,6 @@ public class Intent { |
| 41 | 41 | public List<Entity> entities = new ArrayList<>(); |
| 42 | 42 | public List<String> missing = new ArrayList<>(); // 完成该意图还缺的关键信息 |
| 43 | 43 | |
| 44 | - public boolean isWrite() { | |
| 45 | - return CREATE.equals(intent) || UPDATE.equals(intent) | |
| 46 | - || DELETE.equals(intent) || EXAMINE.equals(intent); | |
| 47 | - } | |
| 48 | - | |
| 49 | 44 | /** 取某业务角色的第一个实体值(如「客户」「产品」),没有则返回 null。 */ |
| 50 | 45 | public String firstValueByRole(String role) { |
| 51 | 46 | for (Entity e : entities) { | ... | ... |
src/main/java/com/xly/config/AgentFactory.java
| ... | ... | @@ -102,13 +102,13 @@ public class AgentFactory { |
| 102 | 102 | case WRITE: |
| 103 | 103 | tools = new Object[]{skillTool, interactionTool, readTool, |
| 104 | 104 | new ProposeWriteTool(erp, jdbc, ops, mapper, identity, resolver), |
| 105 | - new FormCollectTool(erp, jdbc, resolver, identity, mapper)}; | |
| 105 | + new FormCollectTool(jdbc, resolver, identity, mapper)}; | |
| 106 | 106 | break; |
| 107 | 107 | default: // FULL |
| 108 | 108 | tools = new Object[]{kgQueryTool, skillTool, interactionTool, readTool, |
| 109 | 109 | new ProposeWriteTool(erp, jdbc, ops, mapper, identity, resolver), |
| 110 | 110 | new QueryTool(sqlModel, jdbc, audit, identity, resolver), |
| 111 | - new FormCollectTool(erp, jdbc, resolver, identity, mapper)}; | |
| 111 | + new FormCollectTool(jdbc, resolver, identity, mapper)}; | |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | 114 | return AiServices.builder(ReActAgent.class) |
| ... | ... | @@ -126,7 +126,7 @@ public class AgentFactory { |
| 126 | 126 | |
| 127 | 127 | /** 供确定性「新增」路径直接构建 collectForm 表单(不经 LLM 工具选择)。 */ |
| 128 | 128 | public FormCollectTool formCollectTool(AgentIdentity identity) { |
| 129 | - return new FormCollectTool(erp, jdbc, resolver, identity, mapper); | |
| 129 | + return new FormCollectTool(jdbc, resolver, identity, mapper); | |
| 130 | 130 | } |
| 131 | 131 | |
| 132 | 132 | /** 供确定性「修改/作废/审核…」路径直接调 proposeWrite(不经 LLM 工具选择)。 */ | ... | ... |
src/main/java/com/xly/constant/ErrorCode.java
| ... | ... | @@ -2,66 +2,17 @@ package com.xly.constant; |
| 2 | 2 | |
| 3 | 3 | import lombok.Getter; |
| 4 | 4 | |
| 5 | -/*** | |
| 6 | - * @Author 钱豹 | |
| 7 | - * @Date 23:04 2026/1/30 | |
| 8 | - * @Param | |
| 9 | - * @return | |
| 10 | - * @Description 异常码枚举 | |
| 11 | - **/ | |
| 5 | +/** 异常码枚举(供 {@code GlobalExceptionHandler} 统一错误响应用)。 */ | |
| 12 | 6 | @Getter |
| 13 | 7 | public enum ErrorCode { |
| 14 | 8 | |
| 15 | - // 成功 | |
| 16 | - SUCCESS(200, "操作成功"), | |
| 17 | - SUCCESSMSG(201, "成功"), | |
| 18 | - ERRORMSG(202, "失败"), | |
| 19 | - WFHYY(203, "未返回原因"), | |
| 20 | - | |
| 21 | - // 客户端错误 | |
| 22 | 9 | BAD_REQUEST(400, "请求参数错误"), |
| 23 | - UNAUTHORIZED(401, "未授权"), | |
| 24 | - FORBIDDEN(403, "禁止访问"), | |
| 25 | 10 | NOT_FOUND(404, "资源不存在"), |
| 26 | - | |
| 27 | - // 参数错误 | |
| 28 | 11 | PARAM_ERROR(40001, "参数错误"), |
| 29 | - PARAM_REQUIRED(40002, "参数缺失"), | |
| 30 | - PARAM_TYPE_ERROR(40003, "参数类型错误"), | |
| 31 | - PARAM_FORMAT_ERROR(40004, "参数格式错误"), | |
| 32 | - | |
| 33 | - // 业务错误 | |
| 34 | - BUSINESS_ERROR(50001, "业务异常"), | |
| 35 | 12 | DATA_ERROR(50002, "数据异常"), |
| 36 | - DATA_NOT_FOUND(50003, "数据不存在"), | |
| 37 | 13 | DATA_EXISTS(50004, "数据已存在"), |
| 38 | - DATA_STATE_ERROR(50005, "数据状态异常"), | |
| 39 | - | |
| 40 | - // 用户相关 | |
| 41 | - USER_NOT_FOUND(60001, "用户不存在"), | |
| 42 | - USER_DISABLED(60002, "用户已禁用"), | |
| 43 | - USER_PASSWORD_ERROR(60003, "密码错误"), | |
| 44 | - USER_NOT_LOGIN(60004, "用户未登录"), | |
| 45 | - | |
| 46 | - // 权限相关 | |
| 47 | - PERMISSION_DENIED(70001, "权限不足"), | |
| 48 | - ROLE_NOT_FOUND(70002, "角色不存在"), | |
| 49 | - | |
| 50 | - // 系统错误 | |
| 51 | 14 | SYSTEM_ERROR(10000, "系统异常"), |
| 52 | - SERVICE_UNAVAILABLE(10001, "服务不可用"), | |
| 53 | - DB_ERROR(10002, "数据库异常"), | |
| 54 | - NETWORK_ERROR(10003, "网络异常"), | |
| 55 | - THIRD_PARTY_ERROR(10004, "第三方服务异常"), | |
| 56 | - CONFIG_ERROR(10005, "配置错误"), | |
| 57 | - | |
| 58 | - // 文件相关 | |
| 59 | - FILE_UPLOAD_ERROR(80001, "文件上传失败"), | |
| 60 | - FILE_NOT_FOUND(80002, "文件不存在"), | |
| 61 | - FILE_TYPE_ERROR(80003, "文件类型错误"), | |
| 62 | - FILE_SIZE_ERROR(80004, "文件大小超限"), | |
| 63 | - | |
| 64 | - PYTHON_ERROR(9001, "Python脚本执行失败"); | |
| 15 | + DB_ERROR(10002, "数据库异常"); | |
| 65 | 16 | |
| 66 | 17 | private final Integer code; |
| 67 | 18 | private final String message; |
| ... | ... | @@ -70,16 +21,4 @@ public enum ErrorCode { |
| 70 | 21 | this.code = code; |
| 71 | 22 | this.message = message; |
| 72 | 23 | } |
| 73 | - | |
| 74 | - /** | |
| 75 | - * 根据code获取ErrorCode | |
| 76 | - */ | |
| 77 | - public static ErrorCode getByCode(Integer code) { | |
| 78 | - for (ErrorCode errorCode : values()) { | |
| 79 | - if (errorCode.getCode().equals(code)) { | |
| 80 | - return errorCode; | |
| 81 | - } | |
| 82 | - } | |
| 83 | - return SYSTEM_ERROR; | |
| 84 | - } | |
| 85 | -} | |
| 86 | 24 | \ No newline at end of file |
| 25 | +} | ... | ... |
src/main/java/com/xly/exception/GlobalExceptionHandler.java
| 1 | 1 | package com.xly.exception; |
| 2 | 2 | |
| 3 | 3 | import com.xly.constant.ErrorCode; |
| 4 | -import com.xly.exception.dto.BusinessException; | |
| 5 | 4 | import jakarta.servlet.http.HttpServletRequest; |
| 6 | 5 | import jakarta.validation.ConstraintViolationException; |
| 7 | 6 | import lombok.extern.slf4j.Slf4j; |
| ... | ... | @@ -40,12 +39,6 @@ public class GlobalExceptionHandler { |
| 40 | 39 | return error(ErrorCode.SYSTEM_ERROR.getCode(), "系统异常: " + e.getMessage()); |
| 41 | 40 | } |
| 42 | 41 | |
| 43 | - @ExceptionHandler(BusinessException.class) | |
| 44 | - public Map<String, Object> handleBusinessException(BusinessException e) { | |
| 45 | - log.warn("业务异常: {}", e.getMessage()); | |
| 46 | - return error(e.getCode(), e.getMessage()); | |
| 47 | - } | |
| 48 | - | |
| 49 | 42 | @ExceptionHandler(MethodArgumentNotValidException.class) |
| 50 | 43 | public Map<String, Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { |
| 51 | 44 | List<String> errors = e.getBindingResult().getFieldErrors() | ... | ... |
src/main/java/com/xly/exception/dto/BaseException.java deleted
| 1 | -package com.xly.exception.dto; | |
| 2 | - | |
| 3 | -import com.xly.constant.ErrorCode; | |
| 4 | -import lombok.Data; | |
| 5 | -import lombok.EqualsAndHashCode; | |
| 6 | - | |
| 7 | -/*** | |
| 8 | - * @Author 钱豹 | |
| 9 | - * @Date 23:13 2026/1/30 | |
| 10 | - * @Param | |
| 11 | - * @return | |
| 12 | - * @Description 基础异常定义 | |
| 13 | - **/ | |
| 14 | -@Data | |
| 15 | -@EqualsAndHashCode(callSuper = true) | |
| 16 | -public class BaseException extends RuntimeException { | |
| 17 | - private final Integer code; | |
| 18 | - private final String message; | |
| 19 | - | |
| 20 | - public BaseException(ErrorCode errorCode) { | |
| 21 | - super(errorCode.getMessage()); | |
| 22 | - this.code = errorCode.getCode(); | |
| 23 | - this.message = errorCode.getMessage(); | |
| 24 | - } | |
| 25 | - | |
| 26 | - public BaseException(ErrorCode errorCode, String message) { | |
| 27 | - super(message); | |
| 28 | - this.code = errorCode.getCode(); | |
| 29 | - this.message = message; | |
| 30 | - } | |
| 31 | - | |
| 32 | - public BaseException(Integer code, String message) { | |
| 33 | - super(message); | |
| 34 | - this.code = code; | |
| 35 | - this.message = message; | |
| 36 | - } | |
| 37 | -} | |
| 38 | 0 | \ No newline at end of file |
src/main/java/com/xly/exception/dto/BusinessException.java deleted
| 1 | -package com.xly.exception.dto; | |
| 2 | - | |
| 3 | -import com.xly.constant.ErrorCode; | |
| 4 | - | |
| 5 | -/*** | |
| 6 | - * @Author 钱豹 | |
| 7 | - * @Date 23:13 2026/1/30 | |
| 8 | - * @Param | |
| 9 | - * @return | |
| 10 | - * @Description 业务异常 | |
| 11 | - **/ | |
| 12 | -public class BusinessException extends BaseException { | |
| 13 | - public BusinessException(ErrorCode errorCode) { | |
| 14 | - super(errorCode); | |
| 15 | - } | |
| 16 | - public BusinessException(ErrorCode errorCode, String message) { | |
| 17 | - super(errorCode, message); | |
| 18 | - } | |
| 19 | - | |
| 20 | - public BusinessException(Integer code, String message) { | |
| 21 | - super(code, message); | |
| 22 | - } | |
| 23 | -} | |
| 24 | - | |
| 25 | - | |
| 26 | - |
src/main/java/com/xly/service/AuthzService.java
| ... | ... | @@ -43,12 +43,6 @@ public class AuthzService { |
| 43 | 43 | this.jdbc = jdbc; |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | - /** 当前有效用户(本地=dev-login)能否访问该菜单/表单 id。 */ | |
| 47 | - public boolean canAccessModule(String moduleId) { | |
| 48 | - Set<String> granted = grantedIds(resolveDevUserId(), devUserType, devBrand, devSub); | |
| 49 | - return isAllowed(granted, moduleId); | |
| 50 | - } | |
| 51 | - | |
| 52 | 46 | /** |
| 53 | 47 | * 构造 dev-login(本地开发)身份:token 为空 → ErpClient 回退 dev-login;权限集按 dev 账号解析 |
| 54 | 48 | * (admin → null = 全部)。 |
| ... | ... | @@ -56,21 +50,21 @@ public class AuthzService { |
| 56 | 50 | public com.xly.agent.AgentIdentity devIdentity() { |
| 57 | 51 | String uid = devUserIdOverride != null && !devUserIdOverride.isBlank() ? devUserIdOverride : resolveDevUserId(); |
| 58 | 52 | Set<String> granted = grantedIds(uid, devUserType, devBrand, devSub); |
| 59 | - return new com.xly.agent.AgentIdentity(null, uid, devUserNo, devBrand, devSub, devUserType, granted); | |
| 53 | + return new com.xly.agent.AgentIdentity(null, uid, devBrand, granted); | |
| 60 | 54 | } |
| 61 | 55 | |
| 62 | 56 | /** |
| 63 | 57 | * 构造透传的真实用户身份:token = 用户浏览器里的 ERP 登录 token(转发给 ERP),权限集按该用户 |
| 64 | 58 | * 真实授权({@code sAuthsId})解析。用于生产环境按各用户真实权限收紧。 |
| 65 | 59 | */ |
| 66 | - public com.xly.agent.AgentIdentity userIdentity(String token, String userId, String userNo, | |
| 60 | + public com.xly.agent.AgentIdentity userIdentity(String token, String userId, | |
| 67 | 61 | String brandsId, String subsidiaryId, String userType) { |
| 68 | 62 | Set<String> granted = grantedIds(userId, userType, brandsId, subsidiaryId); |
| 69 | - return new com.xly.agent.AgentIdentity(token, userId, userNo, brandsId, subsidiaryId, userType, granted); | |
| 63 | + return new com.xly.agent.AgentIdentity(token, userId, brandsId, granted); | |
| 70 | 64 | } |
| 71 | 65 | |
| 72 | 66 | /** null = 全部(管理员);否则 = 有权的 id 集合。 */ |
| 73 | - public Set<String> grantedIds(String userId, String userType, String brandsId, String subsidiaryId) { | |
| 67 | + private Set<String> grantedIds(String userId, String userType, String brandsId, String subsidiaryId) { | |
| 74 | 68 | if (isAdmin(userType)) { |
| 75 | 69 | return null; // 超管全部权限 |
| 76 | 70 | } |
| ... | ... | @@ -118,18 +112,6 @@ public class AuthzService { |
| 118 | 112 | return ids; |
| 119 | 113 | } |
| 120 | 114 | |
| 121 | - public boolean isAllowed(Set<String> granted, String... ids) { | |
| 122 | - if (granted == null) { | |
| 123 | - return true; // 管理员 | |
| 124 | - } | |
| 125 | - for (String id : ids) { | |
| 126 | - if (id != null && granted.contains(id)) { | |
| 127 | - return true; | |
| 128 | - } | |
| 129 | - } | |
| 130 | - return false; | |
| 131 | - } | |
| 132 | - | |
| 133 | 115 | private String resolveDevUserId() { |
| 134 | 116 | return queryStr("SELECT sId FROM gdslogininfo WHERE sUserNo=? AND sBrandsId=? LIMIT 1", devUserNo, devBrand); |
| 135 | 117 | } | ... | ... |
src/main/java/com/xly/service/FormResolverService.java
| ... | ... | @@ -83,19 +83,6 @@ public class FormResolverService { |
| 83 | 83 | "ORDER BY iFormUses DESC LIMIT 1", table); |
| 84 | 84 | } |
| 85 | 85 | |
| 86 | - /** 字段中文名 -> 技术列名(先精确、再模糊)。 */ | |
| 87 | - public String resolveField(String table, String fieldChinese) { | |
| 88 | - String f = queryOne( | |
| 89 | - "SELECT sField FROM viw_kg_field_dict WHERE sTable=? AND sChinese=? ORDER BY iFormUses DESC LIMIT 1", | |
| 90 | - table, fieldChinese.trim()); | |
| 91 | - if (f == null) { | |
| 92 | - f = queryOne( | |
| 93 | - "SELECT sField FROM viw_kg_field_dict WHERE sTable=? AND sChinese LIKE ? ORDER BY iFormUses DESC LIMIT 1", | |
| 94 | - table, "%" + fieldChinese.trim() + "%"); | |
| 95 | - } | |
| 96 | - return f; | |
| 97 | - } | |
| 98 | - | |
| 99 | 86 | // ERP 会自动注入 / 系统管理、不该让用户填的列(新增时排除)。 |
| 100 | 87 | private static final Set<String> SYS_EXACT = Set.of( |
| 101 | 88 | "sId", "sBrandsId", "sSubsidiaryId", "sMakePerson", "sFormId", "sBillNo", "iIncrement", "iOrder", | ... | ... |
src/main/java/com/xly/service/SystemPromptService.java
| ... | ... | @@ -34,11 +34,6 @@ public class SystemPromptService { |
| 34 | 34 | + "不要复述你在调用哪个工具、不要输出思考过程或过程性旁白。\n\n" |
| 35 | 35 | + "你是「小羚羊」,小羚羊印刷 ERP 的智能助手,服务印刷/包装行业的企业用户,帮他们查询和操作 ERP 业务单据。\n"; |
| 36 | 36 | |
| 37 | - /** 兼容旧入口:默认给 FULL 版。 */ | |
| 38 | - public String buildSystemPrompt() { | |
| 39 | - return buildPrompt(ToolScope.FULL); | |
| 40 | - } | |
| 41 | - | |
| 42 | 37 | public String buildPrompt(ToolScope scope) { |
| 43 | 38 | switch (scope) { |
| 44 | 39 | case READ: | ... | ... |
src/main/java/com/xly/tool/FormCollectTool.java
| ... | ... | @@ -2,7 +2,6 @@ package com.xly.tool; |
| 2 | 2 | |
| 3 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; |
| 4 | 4 | import com.xly.agent.AgentIdentity; |
| 5 | -import com.xly.service.ErpClient; | |
| 6 | 5 | import com.xly.service.FormResolverService; |
| 7 | 6 | import dev.langchain4j.agent.tool.P; |
| 8 | 7 | import dev.langchain4j.agent.tool.Tool; |
| ... | ... | @@ -39,8 +38,7 @@ public class FormCollectTool { |
| 39 | 38 | private final AgentIdentity identity; |
| 40 | 39 | private final ObjectMapper mapper; |
| 41 | 40 | |
| 42 | - /** {@code erp} 参数保留只为与其它按请求新建的工具签名一致;本工具只读元数据,不打 ERP API。 */ | |
| 43 | - public FormCollectTool(ErpClient erp, JdbcTemplate jdbc, FormResolverService resolver, | |
| 41 | + public FormCollectTool(JdbcTemplate jdbc, FormResolverService resolver, | |
| 44 | 42 | AgentIdentity identity, ObjectMapper mapper) { |
| 45 | 43 | this.jdbc = jdbc; |
| 46 | 44 | this.resolver = resolver; | ... | ... |
src/main/java/com/xly/tool/ProposeWriteTool.java
| ... | ... | @@ -625,16 +625,6 @@ public class ProposeWriteTool { |
| 625 | 625 | return out; |
| 626 | 626 | } |
| 627 | 627 | |
| 628 | - /** 外键兜底:该列现有的最常见非空值。列名来自 KG/info_schema(可信)。 */ | |
| 629 | - private String commonValue(String table, String col) { | |
| 630 | - try { | |
| 631 | - return queryOne("SELECT `" + col + "` FROM `" + table + "` WHERE `" + col + "` IS NOT NULL AND `" + col + | |
| 632 | - "`<>'' GROUP BY `" + col + "` ORDER BY COUNT(*) DESC LIMIT 1"); | |
| 633 | - } catch (Exception e) { | |
| 634 | - return null; | |
| 635 | - } | |
| 636 | - } | |
| 637 | - | |
| 638 | 628 | /** 定位实体的可写主表——统一走 FormResolverService(与 collectForm 同源,含从属/参数表排除)。 */ |
| 639 | 629 | private Map<String, Object> resolveForm(String entityKeyword) { |
| 640 | 630 | return resolver.resolveMasterForm(entityKeyword); | ... | ... |
src/main/java/com/xly/web/AgentChatController.java
| ... | ... | @@ -89,7 +89,6 @@ public class AgentChatController { |
| 89 | 89 | public String conversationId; |
| 90 | 90 | // 透传的 ERP 会话 token + 稳定身份(前端逐请求带上;token 绝不进 prompt) |
| 91 | 91 | public String authorization; |
| 92 | - public String username; | |
| 93 | 92 | public String brandsid; |
| 94 | 93 | public String subsidiaryid; |
| 95 | 94 | public String usertype; |
| ... | ... | @@ -353,7 +352,7 @@ public class AgentChatController { |
| 353 | 352 | private AgentIdentity resolveIdentity(ChatReq req) { |
| 354 | 353 | try { |
| 355 | 354 | if (req.authorization != null && !req.authorization.isBlank()) { |
| 356 | - return authz.userIdentity(req.authorization.trim(), req.userid, req.username, | |
| 355 | + return authz.userIdentity(req.authorization.trim(), req.userid, | |
| 357 | 356 | req.brandsid, req.subsidiaryid, req.usertype); |
| 358 | 357 | } |
| 359 | 358 | } catch (Exception e) { | ... | ... |