From 79ed8b3b9c91f3896f29787dda1ab9384a7a09d8 Mon Sep 17 00:00:00 2001 From: vertoryao Date: Mon, 28 Apr 2025 16:15:18 +0800 Subject: [PATCH] =?UTF-8?q?refactor(dify):=20=E9=87=8D=E6=9E=84=20API=20?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=92=8C=E5=AE=89=E5=85=A8=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构 API接口路径,修改权限命名配置 - 移除了 WebFlux 相关代码,改为使用 Spring Security 配置 --- pom.xml | 18 ++-- .../{AppConfig.java => RestClientConfig.java} | 2 +- .../dify/framework/WebMvcConfiguration.java | 16 +-- .../mybatisplus/MybatisPlusConfig.java | 13 +++ .../security/SpringSecurityConfig.java | 2 +- .../flux/FluxUserDetailServiceImpl.java | 83 -------------- .../flux/SpringWebFluxSecurityConfig.java | 102 ------------------ .../dify/controller/V1ChatController.java | 62 ++++++++--- .../dify/controller/V1DatasetController.java | 28 ++--- .../dify/controller/V1ServerController.java | 22 ++-- .../dify/controller/V1WorkflowController.java | 42 +++++--- .../system/repo/flux/MenuFluxRepository.java | 16 --- .../system/repo/flux/RoleFluxRepository.java | 15 --- .../system/repo/flux/UserFluxRepository.java | 12 --- .../repo/flux/UserRoleFluxRepository.java | 16 --- src/main/resources/application-dev.yml | 12 +-- 16 files changed, 136 insertions(+), 325 deletions(-) rename src/main/java/com/zsc/edu/dify/framework/{AppConfig.java => RestClientConfig.java} (91%) delete mode 100644 src/main/java/com/zsc/edu/dify/framework/security/flux/FluxUserDetailServiceImpl.java delete mode 100644 src/main/java/com/zsc/edu/dify/framework/security/flux/SpringWebFluxSecurityConfig.java delete mode 100644 src/main/java/com/zsc/edu/dify/modules/system/repo/flux/MenuFluxRepository.java delete mode 100644 src/main/java/com/zsc/edu/dify/modules/system/repo/flux/RoleFluxRepository.java delete mode 100644 src/main/java/com/zsc/edu/dify/modules/system/repo/flux/UserFluxRepository.java delete mode 100644 src/main/java/com/zsc/edu/dify/modules/system/repo/flux/UserRoleFluxRepository.java diff --git a/pom.xml b/pom.xml index ef39dfe..a710ba9 100644 --- a/pom.xml +++ b/pom.xml @@ -119,15 +119,15 @@ true - - org.springframework.boot - spring-boot-starter-data-r2dbc - - - io.r2dbc - r2dbc-postgresql - 0.8.13.RELEASE - + + + + + + + + + org.mapstruct mapstruct diff --git a/src/main/java/com/zsc/edu/dify/framework/AppConfig.java b/src/main/java/com/zsc/edu/dify/framework/RestClientConfig.java similarity index 91% rename from src/main/java/com/zsc/edu/dify/framework/AppConfig.java rename to src/main/java/com/zsc/edu/dify/framework/RestClientConfig.java index a6625fd..d273deb 100644 --- a/src/main/java/com/zsc/edu/dify/framework/AppConfig.java +++ b/src/main/java/com/zsc/edu/dify/framework/RestClientConfig.java @@ -8,7 +8,7 @@ import org.springframework.web.client.RestClient; * @author zhuang */ @Configuration -public class AppConfig { +public class RestClientConfig { @Bean public RestClient restClient() { diff --git a/src/main/java/com/zsc/edu/dify/framework/WebMvcConfiguration.java b/src/main/java/com/zsc/edu/dify/framework/WebMvcConfiguration.java index 0aa1c39..db3dc02 100644 --- a/src/main/java/com/zsc/edu/dify/framework/WebMvcConfiguration.java +++ b/src/main/java/com/zsc/edu/dify/framework/WebMvcConfiguration.java @@ -46,12 +46,12 @@ public class WebMvcConfiguration implements WebMvcConfigurer { } } - @Override - public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/**") - .allowedOrigins("*") - .allowedMethods("GET", "POST", "PUT", "DELETE") - .allowedHeaders("*") - .exposedHeaders("*"); - } +// @Override +// public void addCorsMappings(CorsRegistry registry) { +// registry.addMapping("/**") +// .allowedOrigins("*") +// .allowedMethods("GET", "POST", "PUT", "DELETE") +// .allowedHeaders("*") +// .exposedHeaders("*"); +// } } diff --git a/src/main/java/com/zsc/edu/dify/framework/mybatisplus/MybatisPlusConfig.java b/src/main/java/com/zsc/edu/dify/framework/mybatisplus/MybatisPlusConfig.java index 0ece86b..e04477b 100644 --- a/src/main/java/com/zsc/edu/dify/framework/mybatisplus/MybatisPlusConfig.java +++ b/src/main/java/com/zsc/edu/dify/framework/mybatisplus/MybatisPlusConfig.java @@ -4,9 +4,20 @@ import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import jakarta.activation.DataSource; +import jakarta.annotation.Resource; +import org.apache.ibatis.session.ExecutorType; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +import javax.naming.Context; +import javax.naming.InitialContext; /** * @author Yao @@ -14,6 +25,7 @@ import org.springframework.context.annotation.Configuration; @MapperScan(basePackages = "com.zsc.edu.dify.modules.**.repo") @Configuration public class MybatisPlusConfig { + @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); @@ -25,4 +37,5 @@ public class MybatisPlusConfig { interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL)); return interceptor; } + } diff --git a/src/main/java/com/zsc/edu/dify/framework/security/SpringSecurityConfig.java b/src/main/java/com/zsc/edu/dify/framework/security/SpringSecurityConfig.java index dcb04a9..f9f8852 100644 --- a/src/main/java/com/zsc/edu/dify/framework/security/SpringSecurityConfig.java +++ b/src/main/java/com/zsc/edu/dify/framework/security/SpringSecurityConfig.java @@ -82,7 +82,7 @@ public class SpringSecurityConfig { .requestMatchers(HttpMethod.GET, "/api/rest/user/menu","/api/rest/user/register","/api/rest/user/send-email").permitAll() .requestMatchers(HttpMethod.POST, "/api/rest/user/login","/api/rest/user/register").permitAll() .requestMatchers("/api/rest/user/me").permitAll() - .requestMatchers("/v1/**").permitAll() + .requestMatchers("/v1/**").authenticated() .requestMatchers("/api/**").authenticated() ) // 不用注解,直接通过判断路径实现动态访问权限 diff --git a/src/main/java/com/zsc/edu/dify/framework/security/flux/FluxUserDetailServiceImpl.java b/src/main/java/com/zsc/edu/dify/framework/security/flux/FluxUserDetailServiceImpl.java deleted file mode 100644 index 338964f..0000000 --- a/src/main/java/com/zsc/edu/dify/framework/security/flux/FluxUserDetailServiceImpl.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.zsc.edu.dify.framework.security.flux; -import com.zsc.edu.dify.common.util.TreeUtil; -import com.zsc.edu.dify.exception.StateException; -import com.zsc.edu.dify.framework.security.UserDetailsImpl; -import com.zsc.edu.dify.modules.system.entity.Dept; -import com.zsc.edu.dify.modules.system.entity.Menu; -import com.zsc.edu.dify.modules.system.entity.Role; -import com.zsc.edu.dify.modules.system.entity.UserRole; -import com.zsc.edu.dify.modules.system.repo.flux.*; -import com.zsc.edu.dify.modules.system.service.DeptService; -import lombok.AllArgsConstructor; -import org.springframework.security.core.userdetails.ReactiveUserDetailsService; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.stereotype.Service; -import reactor.core.publisher.Mono; - -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * @author zhuang - */ -@AllArgsConstructor -@Service -public class FluxUserDetailServiceImpl implements ReactiveUserDetailsService { - - private final UserFluxRepository userRepo; - private final MenuFluxRepository menuRepository; - private final RoleFluxRepository roleFluxRepository; - private final UserRoleFluxRepository userRoleFluxRepository; - private final DeptService deptService; - @Override - public Mono findByUsername(String username) { - return userRepo.findByUsername(username) - .flatMap(user -> { - if (!user.getEnableState()) { - return Mono.error(new StateException("用户 '" + username + "' 已被禁用!请联系管理员")); - } - // 先获取UserRole列表,并从中提取roleIds - return userRoleFluxRepository.findByUserId(user.getId()).collectList() - .flatMap(userRoles -> Mono.zip( - roleFluxRepository.findByDeptId(user.getDeptId()), - deptService.listFluxTree(user.getDeptId()), - menuRepository.findByRoleId(user.getRoleId()) - )) - .flatMap(tuple -> { - Role role = (Role) tuple.getT1(); - List depts = (List) tuple.getT2(); - List menus = tuple.getT3(); - - user.setRole(role); - - Set dataScopeDeptIds = depts.stream() - .map(Dept::getId) - .collect(Collectors.toSet()); - user.setDataScopeDeptIds(dataScopeDeptIds); - - Set permissions = menus.stream() - .map(Menu::getPermissions) - .collect(Collectors.toSet()); - - return Mono.just(UserDetailsImpl.from(user, permissions)); - }); - }); - } - - - -// @Override -// public Mono findByUsername(String username) { -// return userRepo.findByUsername(username) -// .flatMap(user -> menuRepository.findByRoleId(user.getRoleId()) -// .map(ids-> userRoleFluxRepository.findByUserId(user.getId())) -// .map(roles-> roleFluxRepository.findByIdIn(ids)) -// .map(menus -> { -// Set permissions = menus.stream().map(Menu::getPermissions).collect(Collectors.toSet()); -// return UserDetailsImpl.from(user, permissions); -// }) -// ); -// } - -} diff --git a/src/main/java/com/zsc/edu/dify/framework/security/flux/SpringWebFluxSecurityConfig.java b/src/main/java/com/zsc/edu/dify/framework/security/flux/SpringWebFluxSecurityConfig.java deleted file mode 100644 index dadcd64..0000000 --- a/src/main/java/com/zsc/edu/dify/framework/security/flux/SpringWebFluxSecurityConfig.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.zsc.edu.dify.framework.security.flux; - -import com.zsc.edu.dify.framework.security.*; -import jakarta.annotation.Resource; -import lombok.AllArgsConstructor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; -import org.springframework.security.authentication.ReactiveAuthenticationManager; -import org.springframework.security.authentication.UserDetailsRepositoryReactiveAuthenticationManager; -import org.springframework.security.authorization.AuthorizationDecision; -import org.springframework.security.authorization.ReactiveAuthorizationManager; -import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; -import org.springframework.security.config.web.server.SecurityWebFiltersOrder; -import org.springframework.security.config.web.server.ServerHttpSecurity; -import org.springframework.security.core.userdetails.ReactiveUserDetailsService; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.web.server.SecurityWebFilterChain; -import org.springframework.security.web.server.ServerAuthenticationEntryPoint; -import org.springframework.security.web.server.authentication.AuthenticationWebFilter; -import org.springframework.security.web.server.authentication.ServerAuthenticationEntryPointFailureHandler; -import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler; -import org.springframework.security.web.server.authorization.AuthorizationContext; -import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler; -import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.cors.reactive.CorsConfigurationSource; -import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource; -import reactor.core.publisher.Mono; - -import javax.sql.DataSource; - -@EnableWebFluxSecurity -@AllArgsConstructor -@Configuration -public class SpringWebFluxSecurityConfig { - - private final ReactiveUserDetailsService userDetailsService; - private final CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler; - private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint; - private final CustomAccessDeniedHandler customAccessDeniedHandler; - private final SecurityBeanConfig securityBeanConfig; - - - @Bean - public ReactiveAuthenticationManager reactiveAuthenticationManager() { - UserDetailsRepositoryReactiveAuthenticationManager authenticationManager = - new UserDetailsRepositoryReactiveAuthenticationManager(userDetailsService); - authenticationManager.setPasswordEncoder(securityBeanConfig.passwordEncoder()); - return authenticationManager; - } - - @Bean - public ReactiveAuthorizationManager reactiveAuthorizationManager() { - return (authenticationMono, context) -> authenticationMono - .flatMap(authentication -> - userDetailsService.findByUsername(authentication.getName()) - .map(userDetails -> { - SecurityUtil.setUserInfo((UserDetailsImpl) userDetails); - return new AuthorizationDecision(true); - }) - ) - .defaultIfEmpty(new AuthorizationDecision(false)); - } - - @Bean - public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { - // 配置认证过滤器 - AuthenticationWebFilter authenticationFilter = new AuthenticationWebFilter(reactiveAuthenticationManager()); - authenticationFilter.setAuthenticationSuccessHandler((ServerAuthenticationSuccessHandler) customAuthenticationSuccessHandler); - authenticationFilter.setAuthenticationFailureHandler(new ServerAuthenticationEntryPointFailureHandler((ServerAuthenticationEntryPoint) customAuthenticationEntryPoint)); - authenticationFilter.setSecurityContextRepository(new WebSessionServerSecurityContextRepository()); - - return http - .authorizeExchange(exchanges -> exchanges - .pathMatchers("/v1/flux/**").access(reactiveAuthorizationManager()) // 通过自定义权限管理器进行权限校验 - .anyExchange().authenticated() - ) - .addFilterAt(authenticationFilter, SecurityWebFiltersOrder.AUTHENTICATION) - .exceptionHandling(handling -> handling - .authenticationEntryPoint((ServerAuthenticationEntryPoint) customAuthenticationEntryPoint) - .accessDeniedHandler((ServerAccessDeniedHandler) customAccessDeniedHandler) - ) - .csrf(ServerHttpSecurity.CsrfSpec::disable) - .cors(cors -> cors.configurationSource(corsConfigurationSource())) - .httpBasic(ServerHttpSecurity.HttpBasicSpec::disable) - .build(); - } - - @Bean - public CorsConfigurationSource corsConfigurationSource() { - CorsConfiguration config = new CorsConfiguration(); - config.addAllowedOrigin("*"); - config.addAllowedHeader("*"); - config.addAllowedMethod("*"); - config.setAllowCredentials(true); - - UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); - source.registerCorsConfiguration("/v1/flux/**", config); - return source; - } -} diff --git a/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1ChatController.java b/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1ChatController.java index 5843d8e..be05450 100644 --- a/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1ChatController.java +++ b/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1ChatController.java @@ -5,6 +5,7 @@ import io.github.guoshiqiufeng.dify.chat.DifyChat; import io.github.guoshiqiufeng.dify.chat.dto.request.ChatMessageSendRequest; import io.github.guoshiqiufeng.dify.chat.dto.request.MessageConversationsRequest; import io.github.guoshiqiufeng.dify.chat.dto.response.ChatMessageSendCompletionResponse; +import io.github.guoshiqiufeng.dify.chat.dto.response.ChatMessageSendResponse; import io.github.guoshiqiufeng.dify.chat.dto.response.MessageConversationsResponse; import io.github.guoshiqiufeng.dify.core.pojo.DifyPageResult; import jakarta.annotation.Resource; @@ -12,6 +13,7 @@ import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; /** * @author yanghq @@ -27,6 +29,25 @@ public class V1ChatController { @Resource private AppEntityRepository appEntityRepository; + /** + * 发送消息 + * + * @param sendRequest 消息参数 (可以自定义参数,调用 difyChat 实例时重新组装即可), + * 用户 id可以改为从上下文(token)获取, + * apikey 建议在数据库进行存储,前端调用时传智能体 id,从数据库查询 + */ + @PostMapping("/completions/{appid}") + @PreAuthorize("hasAuthority('dify:chat:query')") + public ChatMessageSendResponse sendChatMessage( + @RequestBody ChatMessageSendRequest sendRequest, + @PathVariable String appid + ) { + String apiKey = appEntityRepository.selectApiKey(appid); + sendRequest.setApiKey(apiKey); + return difyChat.send(sendRequest); + } + + /** * 发送消息(流式) * @@ -34,10 +55,14 @@ public class V1ChatController { * 用户 id可以改为从上下文(token)获取, * apikey 建议在数据库进行存储,前端调用时传智能体 id,从数据库查询 */ - @PostMapping(value = "/completions/{appId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE) - @PreAuthorize("hasAuthority('difyChat:query')") - public Flux sendChatMessageStream(@RequestBody ChatMessageSendRequest sendRequest, @PathVariable String appId) { - sendRequest.setApiKey(appEntityRepository.selectApiKey(appId)); + @PostMapping(value = "/completions/stream/{appid}", produces = MediaType.TEXT_EVENT_STREAM_VALUE) +// @PreAuthorize("hasAuthority('difyChat:query')") + public Flux sendChatMessageStream( + @RequestBody ChatMessageSendRequest sendRequest, + @PathVariable String appid + ) { + String apiKey = appEntityRepository.selectApiKey(appid); + sendRequest.setApiKey(apiKey); return difyChat.sendChatMessageStream(sendRequest); } @@ -47,10 +72,14 @@ public class V1ChatController { * @param request 请求参数 * @return 会话列表 */ - @PostMapping("/conversations") - @PreAuthorize("hasAuthority('difyChat:query')") - public DifyPageResult conversations(@RequestBody MessageConversationsRequest request) { - request.setApiKey("app-mM2UGTE5QVPLCwGvwifnV0g7"); + @PostMapping("/conversations/{appid}") + @PreAuthorize("hasAuthority('dify:chat:query')") + public DifyPageResult conversations( + @RequestBody MessageConversationsRequest request, + @PathVariable String appid + ) { + String apiKey = appEntityRepository.selectApiKey(appid); + request.setApiKey(apiKey); return difyChat.conversations(request); } @@ -60,10 +89,10 @@ public class V1ChatController { * @param taskId 任务id * @param userId 用户id */ - @PatchMapping("/stopMessagesStream") - @PreAuthorize("hasAuthority('difyChat:update')") - public void stopMessagesStream( String taskId, String userId) { - difyChat.stopMessagesStream("app-mM2UGTE5QVPLCwGvwifnV0g7", taskId, userId); + @PatchMapping("/stream/stop") + public void stopMessagesStream(@RequestParam String taskId, @RequestParam String userId, @RequestParam String appid) { + String apiKey = appEntityRepository.selectApiKey(appid); + difyChat.stopMessagesStream(apiKey, taskId, userId); } /** @@ -72,9 +101,10 @@ public class V1ChatController { * @param conversationId 会话id * @param userId 用户id */ - @DeleteMapping("/messages/suggested") - @PreAuthorize("hasAuthority('difyChat:delete')") - public void deleteConversation(String conversationId, String userId) { - difyChat.deleteConversation(conversationId, "app-mM2UGTE5QVPLCwGvwifnV0g7", userId); + @DeleteMapping("/conversation") + @PreAuthorize("hasAuthority('dify:chat:delete')") + public void deleteConversation(@RequestParam String conversationId, @RequestParam String userId, @RequestParam String appid) { + String apiKey = appEntityRepository.selectApiKey(appid); + difyChat.deleteConversation(conversationId, apiKey, userId); } } \ No newline at end of file diff --git a/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1DatasetController.java b/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1DatasetController.java index dba1bc3..c9f57f0 100644 --- a/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1DatasetController.java +++ b/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1DatasetController.java @@ -5,6 +5,7 @@ import io.github.guoshiqiufeng.dify.dataset.DifyDataset; import io.github.guoshiqiufeng.dify.dataset.dto.request.*; import io.github.guoshiqiufeng.dify.dataset.dto.response.*; import jakarta.annotation.Resource; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -13,6 +14,9 @@ import org.springframework.web.bind.annotation.*; public class V1DatasetController { @Resource private DifyDataset difyDataset; + + @Value("${dify.dataset.api-key}") + private String apiKey; /** * 分页查询知识库 @@ -21,9 +25,9 @@ public class V1DatasetController { * @return */ @PostMapping("/page") - @PreAuthorize("hasAuthority('difyDataSet:query')") + @PreAuthorize("hasAuthority('dify:dataset:query')") public DifyPageResult page(@RequestBody DatasetPageRequest request){ - request.setApiKey("dataset-kN5WTJ8jR877YfN1A34JceVg"); + request.setApiKey(apiKey); return difyDataset.page(request); } @@ -34,7 +38,7 @@ public class V1DatasetController { * @return */ @PostMapping("/createDocumentByFile") - @PreAuthorize("hasAuthority('difyDataSet:create')") + @PreAuthorize("hasAuthority('dify:dataset:create')") public DocumentCreateResponse createDocumentByFile(DocumentCreateByFileRequest request){ return difyDataset.createDocumentByFile(request); } @@ -46,9 +50,9 @@ public class V1DatasetController { * @return */ @GetMapping("/pageDocument") - @PreAuthorize("hasAuthority('difyDataSet:query')") + @PreAuthorize("hasAuthority('dify:dataset:query')") public DifyPageResult pageDocument(@RequestBody DatasetPageDocumentRequest request){ - request.setApiKey("dataset-kN5WTJ8jR877YfN1A34JceVg"); + request.setApiKey(apiKey); return difyDataset.pageDocument(request); } @@ -60,9 +64,9 @@ public class V1DatasetController { * @return */ @PostMapping("/uploadFileInfo") - @PreAuthorize("hasAuthority('difyDataSet:query')") + @PreAuthorize("hasAuthority('dify:dataset:query')") public UploadFileInfoResponse uploadFileInfo(String datasetId, String documentId){ - return difyDataset.uploadFileInfo(datasetId, documentId,"dataset-kN5WTJ8jR877YfN1A34JceVg"); + return difyDataset.uploadFileInfo(datasetId, documentId,apiKey); } /** @@ -73,9 +77,9 @@ public class V1DatasetController { * @return */ @DeleteMapping("/deleteDocument") - @PreAuthorize("hasAuthority('difyDataSet:delete')") + @PreAuthorize("hasAuthority('dify:dataset:delete')") public DocumentDeleteResponse deleteDocument(String datasetId, String documentId){ - return difyDataset.deleteDocument(datasetId, documentId, "app-mM2UGTE5QVPLCwGvwifnV0g7"); + return difyDataset.deleteDocument(datasetId, documentId, apiKey); } /** @@ -85,7 +89,7 @@ public class V1DatasetController { * @return */ @PostMapping("/createSegment") - @PreAuthorize("hasAuthority('difyDataSet:create')") + @PreAuthorize("hasAuthority('dify:dataset:create')") public SegmentResponse createSegment(@RequestBody SegmentCreateRequest request){ return difyDataset.createSegment(request); } @@ -97,7 +101,7 @@ public class V1DatasetController { * @return */ @PostMapping("/createSegmentChildChunk") - @PreAuthorize("hasAuthority('difyDataSet:create')") + @PreAuthorize("hasAuthority('dify:dataset:create')") public SegmentChildChunkCreateResponse createSegmentChildChunk(@RequestBody SegmentChildChunkCreateRequest request){ return difyDataset.createSegmentChildChunk(request); } @@ -109,7 +113,7 @@ public class V1DatasetController { * @return */ @GetMapping("/retrieve") - @PreAuthorize("hasAuthority('difyDataSet:query')") + @PreAuthorize("hasAuthority('dify:dataset:query')") public RetrieveResponse retrieve(@RequestBody RetrieveRequest request){ return difyDataset.retrieve(request); } diff --git a/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1ServerController.java b/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1ServerController.java index cf4d2ba..f6252e3 100644 --- a/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1ServerController.java +++ b/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1ServerController.java @@ -31,7 +31,7 @@ public class V1ServerController { * @return */ @GetMapping("/apps") - @PreAuthorize("hasAuthority('difyServer:query')") + @PreAuthorize("hasAuthority('dify:server:query')") public List getApps(String mode, String name) { return difyServerService.getApps(mode, name); } @@ -42,7 +42,7 @@ public class V1ServerController { * @return */ @GetMapping("/{id}") - @PreAuthorize("hasAuthority('difyServer:query')") + @PreAuthorize("hasAuthority('dify:server:query')") public AppsResponseVO getApp(@PathVariable("id") String id) { return difyServer.app(id); } @@ -53,7 +53,7 @@ public class V1ServerController { * @return */ @GetMapping("/api-key/{id}") - @PreAuthorize("hasAuthority('difyServer:query')") + @PreAuthorize("hasAuthority('dify:server:query')") public List getAppApiKey(@PathVariable("id") String id) { return difyServer.getAppApiKey(id); } @@ -64,7 +64,7 @@ public class V1ServerController { * @return */ @PostMapping("/api-key/init/{id}") - @PreAuthorize("hasAuthority('difyServer:create')") + @PreAuthorize("hasAuthority('dify:server:create')") public List initAppApiKey(@PathVariable("id") String id) { return difyServer.initAppApiKey(id); } @@ -74,7 +74,7 @@ public class V1ServerController { * @return */ @GetMapping("/api-key/dataset") - @PreAuthorize("hasAuthority('difyServer:query')") + @PreAuthorize("hasAuthority('dify:server:query')") public List getDatasetApiKey() { return difyServer.getDatasetApiKey(); } @@ -84,7 +84,7 @@ public class V1ServerController { * @return */ @PostMapping("/api-key/dataset/init") - @PreAuthorize("hasAuthority('difyServer:create')") + @PreAuthorize("hasAuthority('dify:server:create')") public List initDatasetApiKey() { return difyServer.initDatasetApiKey(); } @@ -95,8 +95,8 @@ public class V1ServerController { * @param id 应用id * @return */ - @PostMapping("/app/{id}") - @PreAuthorize("hasAuthority('difyServer:update')") + @PostMapping("/app/{id}/toggle") + @PreAuthorize("hasAuthority('dify:server:update')") public boolean enabledApp(@PathVariable String id) { return difyServerService.enabledApp(id); } @@ -105,9 +105,9 @@ public class V1ServerController { * 获取可用应用列表 * @return */ - @GetMapping("/apps/able") - @PreAuthorize("hasAuthority('difyServer:query')") - public List getAbleApps() { + @GetMapping("/apps/enabled") + @PreAuthorize("hasAuthority('dify:server:query')") + public List getEnableApps() { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(AppEntity::isEnabled, true); return difyServerService.list(queryWrapper); diff --git a/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1WorkflowController.java b/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1WorkflowController.java index 752bcf1..98eb790 100644 --- a/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1WorkflowController.java +++ b/src/main/java/com/zsc/edu/dify/modules/dify/controller/V1WorkflowController.java @@ -1,5 +1,6 @@ package com.zsc.edu.dify.modules.dify.controller; +import com.zsc.edu.dify.modules.dify.repo.AppEntityRepository; import io.github.guoshiqiufeng.dify.core.pojo.DifyPageResult; import io.github.guoshiqiufeng.dify.workflow.DifyWorkflow; import io.github.guoshiqiufeng.dify.workflow.dto.request.WorkflowLogsRequest; @@ -11,22 +12,27 @@ import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; @RestController -@RequestMapping("/v1/work") +@RequestMapping("/v1/workflow") public class V1WorkflowController { @Resource private DifyWorkflow difyWorkflow; + + @Resource + private AppEntityRepository appEntityRepository; + /** * 运行工作流 * * @param request * @return */ - @PostMapping("/run") - @PreAuthorize("hasAuthority('difyWorkFlow:query')") - public WorkflowRunResponse runWorkflow(@RequestBody WorkflowRunRequest request) { - request.setApiKey("app-ZpkQM6yy767oUTfNSBYq65nB"); + @PostMapping("/run/{appId}") + @PreAuthorize("hasAuthority('dify:workflow:run')") + public WorkflowRunResponse runWorkflow(@RequestBody WorkflowRunRequest request,@PathVariable String appId) { + String apiKey = appEntityRepository.selectApiKey(appId); + request.setApiKey(apiKey); return difyWorkflow.runWorkflow(request); } @@ -38,7 +44,6 @@ public class V1WorkflowController { */ @PostMapping("/run/stream") public Flux runWorkflowStream(@RequestBody WorkflowRunRequest request) { - request.setApiKey("app-ZpkQM6yy767oUTfNSBYq65nB"); return difyWorkflow.runWorkflowStream(request); } @@ -49,9 +54,10 @@ public class V1WorkflowController { * @param userId * @return */ - @PatchMapping("/stop") - public WorkflowStopResponse stopWorkflowStream( String taskId, String userId){ - return difyWorkflow.stopWorkflowStream("app-mM2UGTE5QVPLCwGvwifnV0g7", taskId, userId); + @PatchMapping("/stop/{appId}") + public WorkflowStopResponse stopWorkflowStream( String taskId, String userId, @PathVariable String appId) { + String apiKey = appEntityRepository.selectApiKey(appId); + return difyWorkflow.stopWorkflowStream(apiKey, taskId, userId); } /** @@ -60,10 +66,11 @@ public class V1WorkflowController { * @param workflowRunId * @return */ - @GetMapping("/info") - @PreAuthorize("hasAuthority('difyWorkFlow:query')") - public WorkflowInfoResponse info(String workflowRunId) { - return difyWorkflow.info(workflowRunId, "app-ZpkQM6yy767oUTfNSBYq65nB"); + @GetMapping("/info/{appId}") + @PreAuthorize("hasAuthority('dify:workflow:info')") + public WorkflowInfoResponse info(String workflowRunId, @PathVariable String appId) { + String apiKey = appEntityRepository.selectApiKey(appId); + return difyWorkflow.info(workflowRunId, apiKey); } /** @@ -72,10 +79,11 @@ public class V1WorkflowController { * @param request * @return */ - @PostMapping("/logs") - @PreAuthorize("hasAuthority('difyWorkFlow:query')") - public DifyPageResult logs(@RequestBody WorkflowLogsRequest request) { - request.setApiKey("app-ZpkQM6yy767oUTfNSBYq65nB"); + @PostMapping("/logs/{appId}") + @PreAuthorize("hasAuthority('difyWorkFlow:log')") + public DifyPageResult logs(@RequestBody WorkflowLogsRequest request, @PathVariable String appId) { + String apiKey = appEntityRepository.selectApiKey(appId); + request.setApiKey(apiKey); return difyWorkflow.logs(request); } } diff --git a/src/main/java/com/zsc/edu/dify/modules/system/repo/flux/MenuFluxRepository.java b/src/main/java/com/zsc/edu/dify/modules/system/repo/flux/MenuFluxRepository.java deleted file mode 100644 index af33517..0000000 --- a/src/main/java/com/zsc/edu/dify/modules/system/repo/flux/MenuFluxRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.zsc.edu.dify.modules.system.repo.flux; - -import com.zsc.edu.dify.modules.system.entity.Menu; -import org.springframework.data.r2dbc.repository.Query; -import org.springframework.data.repository.reactive.ReactiveCrudRepository; -import org.springframework.stereotype.Repository; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import java.util.List; -@Repository -public interface MenuFluxRepository extends ReactiveCrudRepository { - - @Query("select * from sys_menu where id in (select menu_id from sys_roles_menus where role_id = :roleId)") - Mono> findByRoleId(Long roleId); -} diff --git a/src/main/java/com/zsc/edu/dify/modules/system/repo/flux/RoleFluxRepository.java b/src/main/java/com/zsc/edu/dify/modules/system/repo/flux/RoleFluxRepository.java deleted file mode 100644 index 6723273..0000000 --- a/src/main/java/com/zsc/edu/dify/modules/system/repo/flux/RoleFluxRepository.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.zsc.edu.dify.modules.system.repo.flux; - -import com.zsc.edu.dify.modules.system.entity.Role; -import org.mapstruct.Mapper; -import org.springframework.data.repository.reactive.ReactiveCrudRepository; -import org.springframework.stereotype.Repository; -import reactor.core.publisher.Mono; - -import java.util.List; - -@Repository -public interface RoleFluxRepository extends ReactiveCrudRepository { - - Mono findByDeptId(Long id); -} diff --git a/src/main/java/com/zsc/edu/dify/modules/system/repo/flux/UserFluxRepository.java b/src/main/java/com/zsc/edu/dify/modules/system/repo/flux/UserFluxRepository.java deleted file mode 100644 index 4a0f208..0000000 --- a/src/main/java/com/zsc/edu/dify/modules/system/repo/flux/UserFluxRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.zsc.edu.dify.modules.system.repo.flux; - -import com.zsc.edu.dify.modules.system.entity.User; -import org.springframework.data.repository.reactive.ReactiveCrudRepository; -import org.springframework.stereotype.Repository; -import reactor.core.publisher.Mono; - -@Repository -public interface UserFluxRepository extends ReactiveCrudRepository { - - Mono findByUsername(String username); -} diff --git a/src/main/java/com/zsc/edu/dify/modules/system/repo/flux/UserRoleFluxRepository.java b/src/main/java/com/zsc/edu/dify/modules/system/repo/flux/UserRoleFluxRepository.java deleted file mode 100644 index b6e86a8..0000000 --- a/src/main/java/com/zsc/edu/dify/modules/system/repo/flux/UserRoleFluxRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.zsc.edu.dify.modules.system.repo.flux; - -import com.zsc.edu.dify.modules.system.entity.UserRole; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; -import org.springframework.data.repository.reactive.ReactiveCrudRepository; -import org.springframework.stereotype.Repository; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import java.util.List; -@Repository -public interface UserRoleFluxRepository extends ReactiveCrudRepository { - - Flux> findByUserId(Long userId); -} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 69a2e1c..d96a8ac 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -11,12 +11,12 @@ mybatis-plus: map-underscore-to-camel-case: true spring: - main: - allow-bean-definition-overriding: true - r2dbc: - url: r2dbc:postgresql://43.139.10.64:15432/dify?ssl=false&TimeZone=Asia/Shanghai - username: gitea - password: gitea +# main: +# allow-bean-definition-overriding: true +# r2dbc: +# url: r2dbc:postgresql://43.139.10.64:15432/dify?ssl=false&TimeZone=Asia/Shanghai +# username: gitea +# password: gitea datasource: url: jdbc:postgresql://43.139.10.64:15432/dify?ssl=false&TimeZone=Asia/Shanghai username: gitea