From 088853b09815e132b4c966f6c76c736b559c0593 Mon Sep 17 00:00:00 2001 From: "zhiye.sun" Date: Thu, 21 May 2026 13:10:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E7=BB=9F=E4=B8=80=E5=85=AC=E5=85=B1?= =?UTF-8?q?=E5=AE=A1=E8=AE=A1=E5=A1=AB=E5=85=85=E5=B9=B6=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E6=9E=9A=E4=B8=BE=E6=8E=A5=E5=8F=A3=E9=A3=8E?= =?UTF-8?q?=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/api/__tests__/sysEnums.spec.ts | 14 +++-- frontend/src/api/sysEnums.ts | 16 +++-- .../config/EntityAuditMetaObjectHandler.java | 28 +++++++++ .../common/controller/SysEnumController.java | 60 +++++++++++++------ .../bruce/common/domain/model/BaseEntity.java | 9 +-- .../handler/GlobalExceptionHandler.java | 30 ++++++++++ .../service/impl/SysEnumServiceImpl.java | 42 ++++++++++--- .../EntityAuditMetaObjectHandlerTests.java | 36 +++++++++++ .../common/entity/EntityStructureTests.java | 19 ++++++ .../handler/GlobalExceptionHandlerTests.java | 25 ++++++++ 10 files changed, 238 insertions(+), 41 deletions(-) create mode 100644 src/main/java/com/bruce/common/config/EntityAuditMetaObjectHandler.java create mode 100644 src/main/java/com/bruce/common/handler/GlobalExceptionHandler.java create mode 100644 src/test/java/com/bruce/common/config/EntityAuditMetaObjectHandlerTests.java create mode 100644 src/test/java/com/bruce/common/handler/GlobalExceptionHandlerTests.java diff --git a/frontend/src/api/__tests__/sysEnums.spec.ts b/frontend/src/api/__tests__/sysEnums.spec.ts index efc5df6..21d67cd 100644 --- a/frontend/src/api/__tests__/sysEnums.spec.ts +++ b/frontend/src/api/__tests__/sysEnums.spec.ts @@ -1,10 +1,10 @@ import { describe, expect, it, vi } from 'vitest'; import { batchSave, deleteById, listForManagement, saveOrUpdate } from '../sysEnums'; -import { del, post } from '../request'; +import { post } from '../request'; vi.mock('../request', () => ({ - del: vi.fn(), + get: vi.fn(), post: vi.fn(), })); @@ -12,7 +12,7 @@ describe('sys enum api', () => { it('queries system enums with management filters', () => { listForManagement({ catalog: 'common', keyword: '启用' }); - expect(post).toHaveBeenCalledWith('/sys-enums/manage/query', { + expect(post).toHaveBeenCalledWith('/sys-enum/queryForManagement', { catalog: 'common', keyword: '启用', }); @@ -22,13 +22,15 @@ describe('sys enum api', () => { saveOrUpdate({ catalog: 'common', type: 'status', name: '启用', value: 1 }); deleteById('123'); - expect(post).toHaveBeenCalledWith('/sys-enums', { + expect(post).toHaveBeenCalledWith('/sys-enum/save', { catalog: 'common', type: 'status', name: '启用', value: 1, }); - expect(del).toHaveBeenCalledWith('/sys-enums/123'); + expect(post).toHaveBeenCalledWith('/sys-enum/delete', undefined, { + params: { id: '123' }, + }); }); it('batch saves enum groups', () => { @@ -46,7 +48,7 @@ describe('sys enum api', () => { ], }); - expect(post).toHaveBeenCalledWith('/sys-enums/batch', { + expect(post).toHaveBeenCalledWith('/sys-enum/batchSave', { catalog: 'common', type: 'enable_status', items: [ diff --git a/frontend/src/api/sysEnums.ts b/frontend/src/api/sysEnums.ts index c245e5c..01cf1c1 100644 --- a/frontend/src/api/sysEnums.ts +++ b/frontend/src/api/sysEnums.ts @@ -1,4 +1,4 @@ -import { del, get, post } from './request'; +import { get, post } from './request'; export interface SysEnum { id?: string; @@ -34,21 +34,25 @@ export interface SysEnumBatchSaveRequest { } export function listForManagement(query: SysEnumManageQuery) { - return post('/sys-enums/manage/query', query); + return post('/sys-enum/queryForManagement', query); } export function getById(id: string) { - return get(`/sys-enums/${id}`); + return get('/sys-enum/detail', { + params: { id }, + }); } export function saveOrUpdate(data: SysEnumSaveRequest) { - return post('/sys-enums', data); + return post('/sys-enum/save', data); } export function batchSave(data: SysEnumBatchSaveRequest) { - return post('/sys-enums/batch', data); + return post('/sys-enum/batchSave', data); } export function deleteById(id: string) { - return del(`/sys-enums/${id}`); + return post('/sys-enum/delete', undefined, { + params: { id }, + }); } diff --git a/src/main/java/com/bruce/common/config/EntityAuditMetaObjectHandler.java b/src/main/java/com/bruce/common/config/EntityAuditMetaObjectHandler.java new file mode 100644 index 0000000..b8237ee --- /dev/null +++ b/src/main/java/com/bruce/common/config/EntityAuditMetaObjectHandler.java @@ -0,0 +1,28 @@ +package com.bruce.common.config; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import org.apache.ibatis.reflection.MetaObject; +import org.springframework.stereotype.Component; + +import java.util.Date; + +@Component +public class EntityAuditMetaObjectHandler implements MetaObjectHandler { + + private static final String SYSTEM_USER = "system"; + + @Override + public void insertFill(MetaObject metaObject) { + Date now = new Date(); + strictInsertFill(metaObject, "createTime", Date.class, now); + strictInsertFill(metaObject, "updateTime", Date.class, now); + strictInsertFill(metaObject, "createBy", String.class, SYSTEM_USER); + strictInsertFill(metaObject, "updateBy", String.class, SYSTEM_USER); + } + + @Override + public void updateFill(MetaObject metaObject) { + strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); + strictUpdateFill(metaObject, "updateBy", String.class, SYSTEM_USER); + } +} diff --git a/src/main/java/com/bruce/common/controller/SysEnumController.java b/src/main/java/com/bruce/common/controller/SysEnumController.java index 4c48a14..402a392 100644 --- a/src/main/java/com/bruce/common/controller/SysEnumController.java +++ b/src/main/java/com/bruce/common/controller/SysEnumController.java @@ -9,64 +9,88 @@ import com.bruce.common.dto.response.SysEnumResponse; import com.bruce.common.service.ISysEnumService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; 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 java.util.List; @Tag(name = "系统枚举管理") +@Slf4j @RestController -@RequestMapping("/api/sys-enums") +@RequestMapping("/api/sys-enum") public class SysEnumController { @Autowired private ISysEnumService sysEnumService; @Operation(summary = "查询全部系统枚举") - @GetMapping + @PostMapping("/list") public RequestResult> list() { - return RequestResult.success(sysEnumService.listResponses()); + log.info("SysEnumController.list start"); + List responses = sysEnumService.listResponses(); + log.info("SysEnumController.list success, count={}", responses.size()); + return RequestResult.success(responses); } @Operation(summary = "根据模块和类型查询系统枚举") @PostMapping("/query") public RequestResult> queryByCatalogAndType(@RequestBody SysEnumQueryRequest request) { - return RequestResult.success(sysEnumService.listByCatalogAndTypeResponses(request)); + log.info("SysEnumController.queryByCatalogAndType start, request={}", request); + List responses = sysEnumService.listByCatalogAndTypeResponses(request); + log.info("SysEnumController.queryByCatalogAndType success, count={}", responses.size()); + return RequestResult.success(responses); } @Operation(summary = "管理端查询系统枚举") - @PostMapping("/manage/query") + @PostMapping("/queryForManagement") public RequestResult> queryForManagement(@RequestBody(required = false) SysEnumManageQueryRequest request) { - return RequestResult.success(sysEnumService.listForManagement(request)); + log.info("SysEnumController.queryForManagement start, request={}", request); + List responses = sysEnumService.listForManagement(request); + log.info("SysEnumController.queryForManagement success, count={}", responses.size()); + return RequestResult.success(responses); } @Operation(summary = "查询系统枚举详情") - @GetMapping("/{id}") - public RequestResult getById(@PathVariable Long id) { - return RequestResult.success(sysEnumService.getResponseById(id)); + @GetMapping("/detail") + public RequestResult getById(@RequestParam("id") Long id) { + log.info("SysEnumController.getById start, id={}", id); + SysEnumResponse response = sysEnumService.getResponseById(id); + log.info("SysEnumController.getById success, id={}, found={}", id, response != null); + return RequestResult.success(response); } @Operation(summary = "新增或修改系统枚举") - @PostMapping + @PostMapping("/save") public RequestResult saveOrUpdate(@RequestBody SysEnumSaveRequest request) { - return RequestResult.success(sysEnumService.saveOrUpdate(request)); + log.info("SysEnumController.saveOrUpdate start, request={}", request); + Boolean result = sysEnumService.saveOrUpdate(request); + log.info("SysEnumController.saveOrUpdate success, id={}, catalog={}, type={}, value={}, result={}", + request.getId(), request.getCatalog(), request.getType(), request.getValue(), result); + return RequestResult.success(result); } @Operation(summary = "批量新增系统枚举") - @PostMapping("/batch") + @PostMapping("/batchSave") public RequestResult batchSave(@RequestBody SysEnumBatchSaveRequest request) { - return RequestResult.success(sysEnumService.batchSave(request)); + log.info("SysEnumController.batchSave start, request={}", request); + Boolean result = sysEnumService.batchSave(request); + log.info("SysEnumController.batchSave success, catalog={}, type={}, itemCount={}, result={}", + request.getCatalog(), request.getType(), request.getItems() == null ? 0 : request.getItems().size(), result); + return RequestResult.success(result); } @Operation(summary = "删除系统枚举") - @DeleteMapping("/{id}") - public RequestResult deleteById(@PathVariable Long id) { - return RequestResult.success(sysEnumService.removeById(id)); + @PostMapping("/delete") + public RequestResult deleteById(@RequestParam("id") Long id) { + log.info("SysEnumController.deleteById start, id={}", id); + Boolean result = sysEnumService.removeById(id); + log.info("SysEnumController.deleteById success, id={}, result={}", id, result); + return RequestResult.success(result); } } diff --git a/src/main/java/com/bruce/common/domain/model/BaseEntity.java b/src/main/java/com/bruce/common/domain/model/BaseEntity.java index 7b9fd86..a1b03ad 100644 --- a/src/main/java/com/bruce/common/domain/model/BaseEntity.java +++ b/src/main/java/com/bruce/common/domain/model/BaseEntity.java @@ -1,5 +1,6 @@ package com.bruce.common.domain.model; +import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; @@ -19,21 +20,21 @@ public class BaseEntity { private Long id; @Schema(description = "创建者") - @TableField(value = "create_by") + @TableField(value = "create_by", fill = FieldFill.INSERT) private String createBy; @Schema(description = "创建时间", example = "2026-05-18 20:00:00") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - @TableField(value = "create_time") + @TableField(value = "create_time", fill = FieldFill.INSERT) private Date createTime; @Schema(description = "更新者") - @TableField(value = "update_by") + @TableField(value = "update_by", fill = FieldFill.INSERT_UPDATE) private String updateBy; @Schema(description = "更新时间", example = "2026-05-18 20:00:00") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - @TableField(value = "update_time") + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) private Date updateTime; @Schema(description = "版本") diff --git a/src/main/java/com/bruce/common/handler/GlobalExceptionHandler.java b/src/main/java/com/bruce/common/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..a2bb67a --- /dev/null +++ b/src/main/java/com/bruce/common/handler/GlobalExceptionHandler.java @@ -0,0 +1,30 @@ +package com.bruce.common.handler; + +import com.bruce.common.domain.model.RequestResult; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(IllegalArgumentException.class) + public ResponseEntity> handleIllegalArgumentException(IllegalArgumentException exception) { + log.warn("GlobalExceptionHandler.handleIllegalArgumentException, message={}", exception.getMessage(), exception); + return buildResponse(HttpStatus.BAD_REQUEST, exception.getMessage()); + } + + @ExceptionHandler(Exception.class) + public ResponseEntity> handleException(Exception exception) { + log.error("GlobalExceptionHandler.handleException", exception); + return buildResponse(HttpStatus.INTERNAL_SERVER_ERROR, "系统内部错误,请稍后重试"); + } + + private ResponseEntity> buildResponse(HttpStatus status, String message) { + return ResponseEntity.status(status) + .body(RequestResult.fail(String.valueOf(status.value()), message)); + } +} diff --git a/src/main/java/com/bruce/common/service/impl/SysEnumServiceImpl.java b/src/main/java/com/bruce/common/service/impl/SysEnumServiceImpl.java index 866cc87..525ff31 100644 --- a/src/main/java/com/bruce/common/service/impl/SysEnumServiceImpl.java +++ b/src/main/java/com/bruce/common/service/impl/SysEnumServiceImpl.java @@ -9,6 +9,7 @@ import com.bruce.common.dto.request.SysEnumSaveRequest; import com.bruce.common.dto.response.SysEnumResponse; import com.bruce.common.mapper.SysEnumMapper; import com.bruce.common.service.ISysEnumService; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; @@ -16,36 +17,47 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +@Slf4j @Service public class SysEnumServiceImpl extends ServiceImpl implements ISysEnumService { @Override public List listByCatalogAndType(SysEnumQueryRequest request) { + log.info("SysEnumServiceImpl.listByCatalogAndType start, request={}", request); if (request == null) { throw new IllegalArgumentException("查询请求不能为空"); } - return lambdaQuery() + List result = lambdaQuery() .eq(StringUtils.hasText(request.getCatalog()), SysEnum::getCatalog, request.getCatalog()) .eq(StringUtils.hasText(request.getType()), SysEnum::getType, request.getType()) .orderByAsc(SysEnum::getSort) .list(); + log.info("SysEnumServiceImpl.listByCatalogAndType success, count={}", result.size()); + return result; } @Override public List listResponses() { - return toResponses(list()); + log.info("SysEnumServiceImpl.listResponses start"); + List responses = toResponses(list()); + log.info("SysEnumServiceImpl.listResponses success, count={}", responses.size()); + return responses; } @Override public List listByCatalogAndTypeResponses(SysEnumQueryRequest request) { - return toResponses(listByCatalogAndType(request)); + log.info("SysEnumServiceImpl.listByCatalogAndTypeResponses start"); + List responses = toResponses(listByCatalogAndType(request)); + log.info("SysEnumServiceImpl.listByCatalogAndTypeResponses success, count={}", responses.size()); + return responses; } @Override public List listForManagement(SysEnumManageQueryRequest request) { + log.info("SysEnumServiceImpl.listForManagement start, request={}", request); SysEnumManageQueryRequest queryRequest = request == null ? new SysEnumManageQueryRequest() : request; String keyword = queryRequest.getKeyword(); - return toResponses(lambdaQuery() + List responses = toResponses(lambdaQuery() .eq(StringUtils.hasText(queryRequest.getCatalog()), SysEnum::getCatalog, queryRequest.getCatalog()) .eq(StringUtils.hasText(queryRequest.getType()), SysEnum::getType, queryRequest.getType()) .and(StringUtils.hasText(keyword), wrapper -> wrapper @@ -63,15 +75,21 @@ public class SysEnumServiceImpl extends ServiceImpl impl .orderByAsc(SysEnum::getSort) .orderByAsc(SysEnum::getId) .list()); + log.info("SysEnumServiceImpl.listForManagement success, count={}", responses.size()); + return responses; } @Override public SysEnumResponse getResponseById(Long id) { - return SysEnumResponse.fromEntity(getById(id)); + log.info("SysEnumServiceImpl.getResponseById start, id={}", id); + SysEnumResponse response = SysEnumResponse.fromEntity(getById(id)); + log.info("SysEnumServiceImpl.getResponseById success, id={}, found={}", id, response != null); + return response; } @Override public boolean saveOrUpdate(SysEnumSaveRequest request) { + log.info("SysEnumServiceImpl.saveOrUpdate start, request={}", request); if (request == null) { throw new IllegalArgumentException("保存请求不能为空"); } @@ -85,11 +103,15 @@ public class SysEnumServiceImpl extends ServiceImpl impl sysEnum.setStrvalue(request.getStrvalue()); sysEnum.setSort(request.getSort()); sysEnum.setRemark(request.getRemark()); - return super.saveOrUpdate(sysEnum); + boolean result = super.saveOrUpdate(sysEnum); + log.info("SysEnumServiceImpl.saveOrUpdate success, id={}, catalog={}, type={}, value={}, result={}", + request.getId(), request.getCatalog(), request.getType(), request.getValue(), result); + return result; } @Override public boolean batchSave(SysEnumBatchSaveRequest request) { + log.info("SysEnumServiceImpl.batchSave start, request={}", request); List existingEnums = lambdaQuery() .eq(request != null && StringUtils.hasText(request.getCatalog()), SysEnum::getCatalog, request == null ? null : request.getCatalog()) .eq(request != null && StringUtils.hasText(request.getType()), SysEnum::getType, request == null ? null : request.getType()) @@ -109,10 +131,14 @@ public class SysEnumServiceImpl extends ServiceImpl impl return sysEnum; }) .toList(); - return saveBatch(enums); + boolean result = saveBatch(enums); + log.info("SysEnumServiceImpl.batchSave success, catalog={}, type={}, itemCount={}, result={}", + request.getCatalog(), request.getType(), enums.size(), result); + return result; } public void validateBatchSaveRequest(SysEnumBatchSaveRequest request, List existingEnums) { + log.info("SysEnumServiceImpl.validateBatchSaveRequest start"); if (request == null) { throw new IllegalArgumentException("批量保存请求不能为空"); } @@ -153,6 +179,8 @@ public class SysEnumServiceImpl extends ServiceImpl impl throw new IllegalArgumentException("枚举值已存在: " + value); } } + log.info("SysEnumServiceImpl.validateBatchSaveRequest success, catalog={}, type={}, requestValueCount={}, existingValueCount={}", + request.getCatalog(), request.getType(), requestValues.size(), existingValues.size()); } private List toResponses(List enums) { diff --git a/src/test/java/com/bruce/common/config/EntityAuditMetaObjectHandlerTests.java b/src/test/java/com/bruce/common/config/EntityAuditMetaObjectHandlerTests.java new file mode 100644 index 0000000..650774c --- /dev/null +++ b/src/test/java/com/bruce/common/config/EntityAuditMetaObjectHandlerTests.java @@ -0,0 +1,36 @@ +package com.bruce.common.config; + +import com.bruce.rag.entity.RagStore; +import org.apache.ibatis.reflection.SystemMetaObject; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +class EntityAuditMetaObjectHandlerTests { + + @Test + void insertFillShouldPopulateAuditFields() { + EntityAuditMetaObjectHandler handler = new EntityAuditMetaObjectHandler(); + RagStore entity = new RagStore(); + + handler.insertFill(SystemMetaObject.forObject(entity)); + + assertNotNull(entity.getCreateTime()); + assertNotNull(entity.getUpdateTime()); + assertEquals("system", entity.getCreateBy()); + assertEquals("system", entity.getUpdateBy()); + } + + @Test + void updateFillShouldRefreshUpdateAuditFields() { + EntityAuditMetaObjectHandler handler = new EntityAuditMetaObjectHandler(); + RagStore entity = new RagStore(); + entity.setUpdateBy("oldUser"); + + handler.updateFill(SystemMetaObject.forObject(entity)); + + assertNotNull(entity.getUpdateTime()); + assertEquals("system", entity.getUpdateBy()); + } +} diff --git a/src/test/java/com/bruce/common/entity/EntityStructureTests.java b/src/test/java/com/bruce/common/entity/EntityStructureTests.java index 7467916..ec37d1f 100644 --- a/src/test/java/com/bruce/common/entity/EntityStructureTests.java +++ b/src/test/java/com/bruce/common/entity/EntityStructureTests.java @@ -1,6 +1,8 @@ package com.bruce.common.entity; +import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.Version; import com.bruce.common.domain.model.BaseEntity; @@ -65,4 +67,21 @@ class EntityStructureTests { assertTrue(Arrays.stream(SysEnum.class.getDeclaredFields()).noneMatch(field -> "version".equals(field.getName()))); assertTrue(Arrays.stream(SysAttachment.class.getDeclaredFields()).noneMatch(field -> "version".equals(field.getName()))); } + + @Test + void auditFieldsShouldUseMybatisPlusAutoFill() throws NoSuchFieldException { + TableField createBy = BaseEntity.class.getDeclaredField("createBy").getAnnotation(TableField.class); + TableField createTime = BaseEntity.class.getDeclaredField("createTime").getAnnotation(TableField.class); + TableField updateBy = BaseEntity.class.getDeclaredField("updateBy").getAnnotation(TableField.class); + TableField updateTime = BaseEntity.class.getDeclaredField("updateTime").getAnnotation(TableField.class); + + assertNotNull(createBy); + assertNotNull(createTime); + assertNotNull(updateBy); + assertNotNull(updateTime); + assertEquals(FieldFill.INSERT, createBy.fill()); + assertEquals(FieldFill.INSERT, createTime.fill()); + assertEquals(FieldFill.INSERT_UPDATE, updateBy.fill()); + assertEquals(FieldFill.INSERT_UPDATE, updateTime.fill()); + } } diff --git a/src/test/java/com/bruce/common/handler/GlobalExceptionHandlerTests.java b/src/test/java/com/bruce/common/handler/GlobalExceptionHandlerTests.java new file mode 100644 index 0000000..a6d5c22 --- /dev/null +++ b/src/test/java/com/bruce/common/handler/GlobalExceptionHandlerTests.java @@ -0,0 +1,25 @@ +package com.bruce.common.handler; + +import com.bruce.common.domain.model.RequestResult; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +class GlobalExceptionHandlerTests { + + @Test + void shouldReturnStructuredBadRequestForIllegalArgumentException() { + GlobalExceptionHandler handler = new GlobalExceptionHandler(); + ResponseEntity> response = handler.handleIllegalArgumentException( + new IllegalArgumentException("知识库编码已存在: TEST-1")); + + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + assertNotNull(response.getBody()); + assertEquals("400", response.getBody().getResultcode()); + assertEquals("知识库编码已存在: TEST-1", response.getBody().getMessage()); + assertEquals(null, response.getBody().getData()); + } +}