From fa580a5dd48c8f6ff7ae8f269c06e4f9acfaf1ff Mon Sep 17 00:00:00 2001 From: Chuck1sn Date: Tue, 17 Jun 2025 12:17:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=B2=97=E4=BD=8D=E3=80=81?= =?UTF-8?q?=E8=A7=92=E8=89=B2=E5=92=8C=E6=9D=83=E9=99=90=E7=9A=84=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=9B=B4=E6=96=B0=E7=9B=B8?= =?UTF-8?q?=E5=85=B3API=E6=8E=A5=E5=8F=A3=E5=92=8C=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=EF=BC=8C=E4=BC=98=E5=8C=96=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E5=92=8C=E6=9D=83=E9=99=90=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/zl/mjga/controller/AiController.java | 43 +++- .../java/com/zl/mjga/model/urp/Actions.java | 10 +- frontend/src/api/schema/openapi.json | 69 +++++ frontend/src/api/types/schema.d.ts | 108 ++++++++ frontend/src/components/common/Assistant.vue | 239 ++++++++++++++++-- frontend/src/composables/ai/useAiAction.ts | 33 +++ 6 files changed, 467 insertions(+), 35 deletions(-) diff --git a/backend/src/main/java/com/zl/mjga/controller/AiController.java b/backend/src/main/java/com/zl/mjga/controller/AiController.java index 3bf8fd3..3c912b9 100644 --- a/backend/src/main/java/com/zl/mjga/controller/AiController.java +++ b/backend/src/main/java/com/zl/mjga/controller/AiController.java @@ -5,8 +5,7 @@ import com.zl.mjga.dto.PageResponseDto; import com.zl.mjga.dto.ai.LlmQueryDto; import com.zl.mjga.dto.ai.LlmVm; import com.zl.mjga.exception.BusinessException; -import com.zl.mjga.repository.DepartmentRepository; -import com.zl.mjga.repository.UserRepository; +import com.zl.mjga.repository.*; import com.zl.mjga.service.AiChatService; import com.zl.mjga.service.EmbeddingService; import com.zl.mjga.service.LlmService; @@ -20,9 +19,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.jooq.generated.mjga.enums.LlmCodeEnum; -import org.jooq.generated.mjga.tables.pojos.AiLlmConfig; -import org.jooq.generated.mjga.tables.pojos.Department; -import org.jooq.generated.mjga.tables.pojos.User; +import org.jooq.generated.mjga.tables.pojos.*; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; @@ -41,6 +38,10 @@ public class AiController { private final EmbeddingService embeddingService; private final UserRepository userRepository; private final DepartmentRepository departmentRepository; + private final PositionRepository positionRepository; + private final RoleRepository repository; + private final PermissionRepository permissionRepository; + private final RoleRepository roleRepository; @PostMapping(value = "/action/execute", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux actionExecute(Principal principal, @RequestBody String userMessage) { @@ -124,7 +125,7 @@ public class AiController { userRepository.deleteByUsername(username); } - @PreAuthorize("hasAuthority(T(com.zl.mjga.model.urp.EPermission).WRITE_USER_ROLE_PERMISSION)") + @PreAuthorize("hasAuthority(T(com.zl.mjga.model.urp.EPermission).WRITE_DEPARTMENT_PERMISSION)") @DeleteMapping("/action/department") void deleteDepartment(@RequestParam String name) { Department department = departmentRepository.fetchOneByName(name); @@ -134,6 +135,36 @@ public class AiController { departmentRepository.deleteByName(name); } + @PreAuthorize("hasAuthority(T(com.zl.mjga.model.urp.EPermission).WRITE_POSITION_PERMISSION)") + @DeleteMapping("/action/position") + void deletePosition(@RequestParam String name) { + Position position = positionRepository.fetchOneByName(name); + if (position == null) { + throw new BusinessException("该岗位不存在"); + } + positionRepository.deleteById(position.getId()); + } + + @PreAuthorize("hasAuthority(T(com.zl.mjga.model.urp.EPermission).WRITE_USER_ROLE_PERMISSION)") + @DeleteMapping("/action/role") + void deleteRole(@RequestParam String name) { + Role role = roleRepository.fetchOneByName(name); + if (role == null) { + throw new BusinessException("该角色不存在"); + } + roleRepository.deleteById(role.getId()); + } + + @PreAuthorize("hasAuthority(T(com.zl.mjga.model.urp.EPermission).WRITE_USER_ROLE_PERMISSION)") + @DeleteMapping("/action/permission") + void deletePermission(@RequestParam String name) { + Permission permission = permissionRepository.fetchOneByName(name); + if (permission == null) { + throw new BusinessException("该权限不存在"); + } + permissionRepository.deleteById(permission.getId()); + } + @PostMapping("/chat/refresh") void createNewConversation(Principal principal) { aiChatService.evictChatMemory(principal.getName()); diff --git a/backend/src/main/java/com/zl/mjga/model/urp/Actions.java b/backend/src/main/java/com/zl/mjga/model/urp/Actions.java index 2fce6b8..5655e6b 100644 --- a/backend/src/main/java/com/zl/mjga/model/urp/Actions.java +++ b/backend/src/main/java/com/zl/mjga/model/urp/Actions.java @@ -7,9 +7,15 @@ import lombok.Getter; @Getter public enum Actions { CREATE_USER("CREATE_USER", "创建用户"), - CREATE_DEPARTMENT("CREATE_DEPARTMENT", "创建部门"), DELETE_USER("DELETE_USER", "删除用户"), - DELETE_DEPARTMENT("DELETE_DEPARTMENT", "删除部门"); + CREATE_DEPARTMENT("CREATE_DEPARTMENT", "创建部门"), + DELETE_DEPARTMENT("DELETE_DEPARTMENT", "删除部门"), + CREATE_POSITION("CREATE_POSITION", "创建岗位"), + DELETE_POSITION("DELETE_POSITION", "删除岗位"), + CREATE_ROLE("CREATE_ROLE", "创建角色"), + DELETE_ROLE("CREATE_ROLE", "删除角色"), + CREATE_PERMISSION("CREATE_PERMISSION", "创建权限"), + DELETE_PERMISSION("DELETE_PERMISSION", "删除权限"); public static final String INDEX_KEY = "action"; private final String code; private final String content; diff --git a/frontend/src/api/schema/openapi.json b/frontend/src/api/schema/openapi.json index de79c17..252ef5b 100644 --- a/frontend/src/api/schema/openapi.json +++ b/frontend/src/api/schema/openapi.json @@ -1210,6 +1210,75 @@ } } }, + "/ai/action/role": { + "delete": { + "tags": [ + "ai-controller" + ], + "operationId": "deleteRole_1", + "parameters": [ + { + "name": "name", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/ai/action/position": { + "delete": { + "tags": [ + "ai-controller" + ], + "operationId": "deletePosition_1", + "parameters": [ + { + "name": "name", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/ai/action/permission": { + "delete": { + "tags": [ + "ai-controller" + ], + "operationId": "deletePermission_1", + "parameters": [ + { + "name": "name", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/ai/action/department": { "delete": { "tags": [ diff --git a/frontend/src/api/types/schema.d.ts b/frontend/src/api/types/schema.d.ts index 5caca68..0279ced 100644 --- a/frontend/src/api/types/schema.d.ts +++ b/frontend/src/api/types/schema.d.ts @@ -596,6 +596,54 @@ export interface paths { patch?: never; trace?: never; }; + "/ai/action/role": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + delete: operations["deleteRole_1"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/ai/action/position": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + delete: operations["deletePosition_1"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/ai/action/permission": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + delete: operations["deletePermission_1"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/ai/action/department": { parameters: { query?: never; @@ -1866,6 +1914,66 @@ export interface operations { }; }; }; + deleteRole_1: { + parameters: { + query: { + name: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + deletePosition_1: { + parameters: { + query: { + name: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + deletePermission_1: { + parameters: { + query: { + name: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; deleteDepartment_1: { parameters: { query: { diff --git a/frontend/src/components/common/Assistant.vue b/frontend/src/components/common/Assistant.vue index 45a2e72..387469c 100644 --- a/frontend/src/components/common/Assistant.vue +++ b/frontend/src/components/common/Assistant.vue @@ -18,21 +18,16 @@
- - + :content="commandContentMap[chatElement.command!]" :handleSubmit="commandActionMap[chatElement.command!]" + v-if="chatElement.command?.startsWith('DELETE_')" /> @@ -88,6 +83,30 @@ currentDeleteDepartmentName = undefined departmentDeleteModal!.hide(); }" :onSubmit="handleDeleteDepartmentSubmit" title="确定删除该部门吗" content="删除部门"> + + + + + + + + +