Compare commits
7 Commits
feature/di
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
de2084a67f | ||
![]() |
2ea43b840c | ||
![]() |
795fabf823 | ||
0d30f40f0e | |||
d1834b404b | |||
![]() |
f0066d4c64 | ||
087591fc20 |
@ -1,17 +0,0 @@
|
||||
package com.zsc.edu.dify.framework;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
/**
|
||||
* @author zhuang
|
||||
*/
|
||||
@Configuration
|
||||
public class RestClientConfig {
|
||||
|
||||
@Bean
|
||||
public RestClient restClient() {
|
||||
return RestClient.builder().build();
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.zsc.edu.dify.framework;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import reactor.netty.http.client.HttpClient;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* @author zhuang
|
||||
*/
|
||||
@Configuration
|
||||
public class WebClientConfig {
|
||||
|
||||
@Bean
|
||||
public RestClient restClient() {
|
||||
// 配置超时参数
|
||||
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
|
||||
requestFactory.setConnectTimeout((int) Duration.ofMinutes(30).toMillis()); // 设置连接超时时间为5秒
|
||||
requestFactory.setReadTimeout((int) Duration.ofMinutes(30).toMillis()); // 设置读取超时时间为5秒
|
||||
|
||||
return RestClient.builder()
|
||||
.requestFactory(requestFactory)
|
||||
.build();
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package com.zsc.edu.dify.framework.json;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -13,7 +14,8 @@ public class JsonConfig {
|
||||
|
||||
@Bean
|
||||
public Jackson2ObjectMapperBuilderCustomizer customizer() {
|
||||
return builder -> builder.serializationInclusion(JsonInclude.Include.NON_NULL)
|
||||
return builder -> builder
|
||||
.serializationInclusion(JsonInclude.Include.NON_NULL)
|
||||
.serializationInclusion(JsonInclude.Include.NON_EMPTY);
|
||||
}
|
||||
}
|
||||
|
@ -8,12 +8,14 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.authorization.AuthorizationDeniedException;
|
||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||
import org.springframework.security.web.csrf.MissingCsrfTokenException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author harry_yao
|
||||
@ -35,12 +37,17 @@ public class CustomAccessDeniedHandler implements AccessDeniedHandler {
|
||||
// 会话已注销,返回401
|
||||
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
||||
result = new ExceptionResult("凭证已过期,请重新登录", HttpStatus.UNAUTHORIZED.value(),
|
||||
LocalDateTime.now());
|
||||
LocalDateTime.now());
|
||||
} else if (ex instanceof AuthorizationDeniedException) {
|
||||
// 会话已存在,禁止重复登录,返回401
|
||||
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
||||
result = new ExceptionResult("当前账号已在其他设备登录,请先退出再尝试登录", HttpStatus.UNAUTHORIZED.value(),
|
||||
LocalDateTime.now());
|
||||
} else {
|
||||
// 403
|
||||
response.setStatus(HttpStatus.FORBIDDEN.value());
|
||||
result = new ExceptionResult("禁止操作", HttpStatus.FORBIDDEN.value(),
|
||||
LocalDateTime.now());
|
||||
LocalDateTime.now());
|
||||
}
|
||||
response.getWriter().print(objectMapper.writeValueAsString(result));
|
||||
response.flushBuffer();
|
||||
|
@ -24,7 +24,7 @@ public class CustomSessionInformationExpiredStrategy implements SessionInformati
|
||||
response.setContentType("application/json;charset=utf-8");
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
response.getWriter().print(objectMapper.writeValueAsString(Map.of(
|
||||
"msg", "会话已过期(有可能是您同时登录了太多的太多的客户端)",
|
||||
"msg", "会话已过期(有可能是您同时登录了太多的客户端)",
|
||||
"code", HttpStatus.UNAUTHORIZED.value(),
|
||||
"timestamp", LocalDateTime.now()
|
||||
)));
|
||||
|
@ -55,3 +55,4 @@ public class JpaUserDetailsServiceImpl implements UserDetailsService {
|
||||
return UserDetailsImpl.from(user, permissions);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,30 +0,0 @@
|
||||
package com.zsc.edu.dify.framework.security;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.core.session.SessionRegistry;
|
||||
import org.springframework.security.core.session.SessionRegistryImpl;
|
||||
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.session.HttpSessionEventPublisher;
|
||||
|
||||
/**
|
||||
* @author harry_yao
|
||||
*/
|
||||
@Configuration
|
||||
public class SecurityBeanConfig {
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SessionRegistry sessionRegistry() {
|
||||
return new SessionRegistryImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HttpSessionEventPublisher httpSessionEventPublisher() {
|
||||
return new HttpSessionEventPublisher();
|
||||
}
|
||||
}
|
@ -10,14 +10,18 @@ import org.springframework.security.authentication.ProviderManager;
|
||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
|
||||
import org.springframework.security.core.session.SessionRegistry;
|
||||
import org.springframework.security.core.session.SessionRegistryImpl;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
|
||||
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
|
||||
import org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy;
|
||||
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
||||
import org.springframework.security.web.session.HttpSessionEventPublisher;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@ -34,100 +38,78 @@ public class SpringSecurityConfig {
|
||||
private final CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
|
||||
private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
|
||||
private final CustomAccessDeniedHandler customAccessDeniedHandler;
|
||||
private final SessionRegistry sessionRegistry;
|
||||
private final SecurityBeanConfig securityBeanConfig;
|
||||
private final CustomSessionInformationExpiredStrategy customSessionInformationExpiredStrategy;
|
||||
// private final SessionRegistry sessionRegistry;
|
||||
|
||||
@Resource
|
||||
private final DataSource dataSource;
|
||||
|
||||
// @Bean
|
||||
// public BCryptPasswordEncoder bCryptPasswordEncoder() {
|
||||
// return new BCryptPasswordEncoder();
|
||||
// };
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SessionRegistry sessionRegistry() {
|
||||
return new SessionRegistryImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HttpSessionEventPublisher httpSessionEventPublisher() {
|
||||
return new HttpSessionEventPublisher();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ConcurrentSessionControlAuthenticationStrategy concurrentSessionControlAuthenticationStrategy() {
|
||||
ConcurrentSessionControlAuthenticationStrategy concurrentSessionControlAuthenticationStrategy = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
|
||||
concurrentSessionControlAuthenticationStrategy.setMaximumSessions(1);
|
||||
concurrentSessionControlAuthenticationStrategy.setExceptionIfMaximumExceeded(true);
|
||||
return concurrentSessionControlAuthenticationStrategy;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PersistentTokenRepository persistentTokenRepository() {
|
||||
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
|
||||
tokenRepository.setDataSource(dataSource);
|
||||
return tokenRepository;
|
||||
|
||||
}
|
||||
|
||||
@Bean
|
||||
AuthenticationManager authenticationManager() {
|
||||
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
|
||||
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
|
||||
daoAuthenticationProvider.setPasswordEncoder(securityBeanConfig.passwordEncoder());
|
||||
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
|
||||
return new ProviderManager(daoAuthenticationProvider);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JsonAuthenticationFilter jsonAuthenticationFilter() throws Exception {
|
||||
public JsonAuthenticationFilter jsonAuthenticationFilter() {
|
||||
JsonAuthenticationFilter filter = new JsonAuthenticationFilter();
|
||||
filter.setAuthenticationSuccessHandler(customAuthenticationSuccessHandler);
|
||||
filter.setAuthenticationFailureHandler(customAuthenticationFailureHandler);
|
||||
filter.setFilterProcessesUrl("/api/rest/user/login");
|
||||
filter.setAuthenticationManager(authenticationManager());
|
||||
// 将登录后的请求信息保存到Session中,不然会报null
|
||||
filter.setSecurityContextRepository(new HttpSessionSecurityContextRepository());
|
||||
// filter.setSessionAuthenticationStrategy(concurrentSessionControlAuthenticationStrategy());
|
||||
// filter.setSecurityContextRepository(httpSessionSecurityContextRepository());
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
|
||||
return http
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.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/**").authenticated()
|
||||
.requestMatchers("/api/**").authenticated()
|
||||
)
|
||||
// 不用注解,直接通过判断路径实现动态访问权限
|
||||
// .requestMatchers("/api/**").access((authentication, object) -> {
|
||||
// //表示请求的 URL 地址和数据库的地址是否匹配上了
|
||||
// boolean isMatch = false;
|
||||
// //获取当前请求的 URL 地址
|
||||
// String requestURI = object.getRequest().getRequestURI();
|
||||
// List<MenuWithRoleVO> menuWithRole = menuService.getMenuWithRole();
|
||||
// for (MenuWithRoleVO m : menuWithRole) {
|
||||
// AntPathMatcher antPathMatcher = new AntPathMatcher();
|
||||
// if (antPathMatcher.match(m.getUrl(), requestURI)) {
|
||||
// isMatch = true;
|
||||
// //说明找到了请求的地址了
|
||||
// //这就是当前请求需要的角色
|
||||
// List<Role> roles = m.getRoles();
|
||||
// //获取当前登录用户的角色
|
||||
// Collection<? extends GrantedAuthority> authorities = authentication.get().getAuthorities();
|
||||
// for (GrantedAuthority authority : authorities) {
|
||||
// for (Role role : roles) {
|
||||
// if (authority.getAuthority().equals(role.getName())) {
|
||||
// //说明当前登录用户具备当前请求所需要的角色
|
||||
// return new AuthorizationDecision(true);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (!isMatch) {
|
||||
// //说明请求的 URL 地址和数据库的地址没有匹配上,对于这种请求,统一只要登录就能访问
|
||||
// if (authentication.get() instanceof AnonymousAuthenticationToken) {
|
||||
// return new AuthorizationDecision(false);
|
||||
// } else {
|
||||
// //说明用户已经认证了
|
||||
// return new AuthorizationDecision(true);
|
||||
// }
|
||||
// }
|
||||
// return new AuthorizationDecision(false);
|
||||
// }))
|
||||
.addFilterAt(jsonAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
|
||||
.formLogin(form -> form
|
||||
.loginPage("/user/login")
|
||||
.loginProcessingUrl("/api/rest/user/login")
|
||||
.successHandler(customAuthenticationSuccessHandler)
|
||||
.failureHandler(customAuthenticationFailureHandler))
|
||||
.loginPage("/user/login")
|
||||
.loginProcessingUrl("/api/rest/user/login")
|
||||
.successHandler(customAuthenticationSuccessHandler)
|
||||
.failureHandler(customAuthenticationFailureHandler))
|
||||
.logout(logout -> logout
|
||||
.logoutUrl("/api/rest/user/logout")
|
||||
.logoutSuccessHandler((request, response, authentication) -> {}))
|
||||
@ -139,12 +121,14 @@ public class SpringSecurityConfig {
|
||||
.rememberMe(rememberMe -> rememberMe
|
||||
.userDetailsService(userDetailsService)
|
||||
.tokenRepository(persistentTokenRepository()))
|
||||
.csrf(csrf -> csrf.ignoringRequestMatchers("v1/**","/api/internal/**", "/api/rest/user/logout","/api/rest/user/register"))
|
||||
.csrf(csrf -> csrf
|
||||
.sessionAuthenticationStrategy(concurrentSessionControlAuthenticationStrategy())
|
||||
.ignoringRequestMatchers("v1/**","/api/internal/**", "/api/rest/user/logout","/api/rest/user/register"))
|
||||
.sessionManagement(session -> session
|
||||
.maximumSessions(3)
|
||||
.sessionRegistry(sessionRegistry)
|
||||
.expiredSessionStrategy(customSessionInformationExpiredStrategy))
|
||||
.build();
|
||||
|
||||
.maximumSessions(1)
|
||||
.maxSessionsPreventsLogin(true)
|
||||
.sessionRegistry(sessionRegistry())
|
||||
.expiredSessionStrategy(customSessionInformationExpiredStrategy)
|
||||
).build();
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -98,4 +99,36 @@ public class UserDetailsImpl implements UserDetails {
|
||||
return enableState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
UserDetailsImpl that = (UserDetailsImpl) o;
|
||||
return Objects.equals(id, that.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, username, password, enableState, name, dept, role, roles, authorities, permissions, dataScopeDeptIds, deptId, createId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserDetailsImpl{" +
|
||||
"id=" + id +
|
||||
", username='" + username + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", enableState=" + enableState +
|
||||
", name='" + name + '\'' +
|
||||
", dept=" + dept +
|
||||
", role=" + role +
|
||||
", roles=" + roles +
|
||||
", authorities=" + authorities +
|
||||
", permissions=" + permissions +
|
||||
", dataScopeDeptIds=" + dataScopeDeptIds +
|
||||
", deptId=" + deptId +
|
||||
", createId=" + createId +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
package com.zsc.edu.dify.modules.dify.controller;
|
||||
|
||||
import com.zsc.edu.dify.exception.ExceptionUtil;
|
||||
import com.zsc.edu.dify.framework.mybatisplus.DataPermission;
|
||||
import com.zsc.edu.dify.framework.security.SecurityUtil;
|
||||
import com.zsc.edu.dify.modules.dify.entity.AppEntity;
|
||||
import com.zsc.edu.dify.modules.dify.service.AppEntityService;
|
||||
import com.zsc.edu.dify.modules.dify.service.DifyWorkflowService;
|
||||
import com.zsc.edu.dify.modules.operationLog.entity.OperationLogAnnotation;
|
||||
import io.github.guoshiqiufeng.dify.workflow.dto.request.WorkflowRunRequest;
|
||||
@ -10,6 +13,8 @@ import jakarta.annotation.Resource;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/ppt")
|
||||
public class PPTController {
|
||||
@ -17,17 +22,30 @@ public class PPTController {
|
||||
@Resource
|
||||
private DifyWorkflowService difyWorkflowService;
|
||||
|
||||
@Resource
|
||||
private AppEntityService appEntityService;
|
||||
|
||||
/**
|
||||
* 运行从可研申报书生成科技项目PPT_工作流
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/run")
|
||||
@PreAuthorize("hasAuthority('dify:ppt:run')")
|
||||
@PostMapping("/run/{appId}")
|
||||
@OperationLogAnnotation(content = "'dify工作流'", operationType = "运行")
|
||||
public WorkflowRunResponse runWorkflow(@RequestBody WorkflowRunRequest request) {
|
||||
public WorkflowRunResponse runWorkflow(@RequestBody WorkflowRunRequest request, @PathVariable String appId) {
|
||||
request.setUserId(SecurityUtil.getUserInfo().id.toString());
|
||||
return ExceptionUtil.difyException(() -> difyWorkflowService.run(request, "ee3889b6-50fa-463e-b956-3b93447727fc"));
|
||||
return ExceptionUtil.difyException(() -> difyWorkflowService.run(request, appId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据appType获取应用列表
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/apps")
|
||||
@DataPermission
|
||||
public List<AppEntity> getAppsByAppType(){
|
||||
return appEntityService.selectByAppType(AppEntity.AppType.PPT.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,17 +1,19 @@
|
||||
package com.zsc.edu.dify.modules.dify.controller;
|
||||
|
||||
import com.zsc.edu.dify.exception.ExceptionUtil;
|
||||
import com.zsc.edu.dify.framework.mybatisplus.DataPermission;
|
||||
import com.zsc.edu.dify.framework.security.SecurityUtil;
|
||||
import com.zsc.edu.dify.modules.dify.entity.AppEntity;
|
||||
import com.zsc.edu.dify.modules.dify.service.AppEntityService;
|
||||
import com.zsc.edu.dify.modules.dify.service.DifyWorkflowService;
|
||||
import com.zsc.edu.dify.modules.operationLog.entity.OperationLogAnnotation;
|
||||
import io.github.guoshiqiufeng.dify.workflow.dto.request.WorkflowRunRequest;
|
||||
import io.github.guoshiqiufeng.dify.workflow.dto.response.WorkflowRunResponse;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
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.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/spider2")
|
||||
@ -19,17 +21,29 @@ public class Spider2Controller {
|
||||
@Resource
|
||||
private DifyWorkflowService difyWorkflowService;
|
||||
|
||||
@Resource
|
||||
private AppEntityService appEntityService;
|
||||
|
||||
/**
|
||||
* 运行广州公共资源交易中心 招标小助手
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/run")
|
||||
@PreAuthorize("hasAuthority('dify:spider2:run')")
|
||||
@PostMapping("/run/{appId}")
|
||||
@OperationLogAnnotation(content = "'dify工作流'", operationType = "运行")
|
||||
public WorkflowRunResponse runWorkflow(@RequestBody WorkflowRunRequest request) {
|
||||
public WorkflowRunResponse runWorkflow(@RequestBody WorkflowRunRequest request, @PathVariable String appId) {
|
||||
request.setUserId(SecurityUtil.getUserInfo().id.toString());
|
||||
return ExceptionUtil.difyException(() -> difyWorkflowService.run(request, "c736edd0-925d-4877-9223-56aab7342311"));
|
||||
return ExceptionUtil.difyException(() -> difyWorkflowService.run(request, appId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据appType获取应用列表
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/apps")
|
||||
@DataPermission
|
||||
public List<AppEntity> getAppsByAppType(){
|
||||
return appEntityService.selectByAppType(AppEntity.AppType.SCRAPER.getValue());
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.zsc.edu.dify.modules.dify.dto.SpiderDto;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
@ -19,13 +20,15 @@ import java.util.Collections;
|
||||
public class SpiderController {
|
||||
|
||||
@Resource
|
||||
private ObjectMapper objectMapper;
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private static final String SPIDER_URL = "http://47.112.173.8:6806/api/v1";
|
||||
private static final String API_KEY = "77c068fd-d5b6-4c33-97d8-db5511a09b26";
|
||||
@Value("${quanguo.url}")
|
||||
private String SPIDER_URL;
|
||||
|
||||
@Value("${quanguo.api-key}")
|
||||
private String API_KEY;
|
||||
|
||||
@PostMapping("/run")
|
||||
@PreAuthorize("hasAuthority('dify:spider:run')")
|
||||
public JSONObject run(@RequestBody SpiderDto dto) throws JsonProcessingException {
|
||||
dto.setLlm_api_key(API_KEY);
|
||||
String body = objectMapper.writeValueAsString(dto);
|
||||
@ -38,7 +41,6 @@ public class SpiderController {
|
||||
}
|
||||
|
||||
@PostMapping("/status")
|
||||
@PreAuthorize("hasAuthority('dify:spider:status')")
|
||||
public JSONObject status() {
|
||||
return WebClient.create(SPIDER_URL).post().uri("/crawl_status")
|
||||
.retrieve()
|
||||
@ -47,7 +49,6 @@ public class SpiderController {
|
||||
}
|
||||
|
||||
@PostMapping("/logs")
|
||||
@PreAuthorize("hasAuthority('dify:spider:log')")
|
||||
public JSONObject logs() {
|
||||
return WebClient.create(SPIDER_URL).post().uri("/logs")
|
||||
.retrieve()
|
||||
@ -56,7 +57,6 @@ public class SpiderController {
|
||||
}
|
||||
|
||||
@PostMapping("/stop")
|
||||
@PreAuthorize("hasAuthority('dify:spider:stop')")
|
||||
public JSONObject stop() {
|
||||
return WebClient.create(SPIDER_URL).post().uri("/stop_crawl")
|
||||
.retrieve()
|
||||
|
@ -45,7 +45,6 @@ public class V1ChatController {
|
||||
* apikey 建议在数据库进行存储,前端调用时传智能体 id,从数据库查询
|
||||
*/
|
||||
@PostMapping("/completions/{appId}")
|
||||
@PreAuthorize("hasAnyAuthority('dify:chat:send','dify:word:send')")
|
||||
@OperationLogAnnotation(content = "'dify对话'", operationType = "发送")
|
||||
public ChatMessageSendResponse sendChatMessage(
|
||||
@RequestBody ChatMessageSendRequest sendRequest,
|
||||
@ -81,7 +80,6 @@ public class V1ChatController {
|
||||
* @return 会话列表
|
||||
*/
|
||||
@PostMapping("/conversations/{appId}")
|
||||
@PreAuthorize("hasAnyAuthority('dify:chat:query','dify:word:query')")
|
||||
public DifyPageResult<MessageConversationsResponse> conversations(
|
||||
@RequestBody MessageConversationsRequest request,
|
||||
@PathVariable String appId
|
||||
@ -98,7 +96,6 @@ public class V1ChatController {
|
||||
* @return 消息列表
|
||||
*/
|
||||
@PostMapping("/messages/{appid}")
|
||||
@PreAuthorize("hasAnyAuthority('dify:chat:query','dify:word:query')")
|
||||
public DifyPageResult<MessagesResponseVO> messages(
|
||||
@RequestBody MessagesRequest request,
|
||||
@PathVariable String appid
|
||||
@ -115,7 +112,6 @@ public class V1ChatController {
|
||||
* @param taskId 任务id
|
||||
*/
|
||||
@PatchMapping("/stream/stop")
|
||||
@PreAuthorize("hasAnyAuthority('dify:chat:stop','dify:word:stop')")
|
||||
public void stopMessagesStream(@RequestParam String taskId, @RequestParam String appId) {
|
||||
String apiKey = appEntityService.getApikey(appId);
|
||||
String userId = SecurityUtil.getUserInfo().id.toString();
|
||||
@ -128,13 +124,12 @@ public class V1ChatController {
|
||||
* @param conversationId 会话id
|
||||
*/
|
||||
@DeleteMapping("/conversation")
|
||||
@PreAuthorize("hasAnyAuthority('dify:chat:delete','dify:word:delete')")
|
||||
@OperationLogAnnotation(content = "'dify对话'", operationType = "删除")
|
||||
public void deleteConversation(@RequestParam String conversationId, @RequestParam String appId) {
|
||||
String apiKey = appEntityService.getApikey(appId);
|
||||
String userId = SecurityUtil.getUserInfo().id.toString();
|
||||
try{
|
||||
difyChat.deleteConversation(conversationId, apiKey,userId);
|
||||
difyChat.deleteConversation(conversationId, apiKey, userId);
|
||||
}catch (RuntimeException e){
|
||||
throw new ApiException("删除会话失败"+e.getMessage());
|
||||
}
|
||||
@ -147,7 +142,6 @@ public class V1ChatController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/messages/suggested")
|
||||
@PreAuthorize("hasAnyAuthority('dify:chat:query','dify:word:query')")
|
||||
public List<String> messagesSuggested(String messageId,String appId){
|
||||
String apiKey = appEntityService.getApikey(appId);
|
||||
String userId = SecurityUtil.getUserInfo().id.toString();
|
||||
@ -160,7 +154,6 @@ public class V1ChatController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/parameters/{appid}")
|
||||
@PreAuthorize("hasAnyAuthority('dify:chat:query','dify:word:query')")
|
||||
public AppParametersResponseVO parameters(@PathVariable String appid){
|
||||
String apiKey = appEntityService.getApikey(appid);
|
||||
return ExceptionUtil.difyException(()->difyChat.parameters(apiKey));
|
||||
|
@ -28,7 +28,6 @@ public class V1DatasetController {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/page")
|
||||
@PreAuthorize("hasAuthority('dify:dataset:query')")
|
||||
public DifyPageResult<DatasetResponse> page(@RequestBody DatasetPageRequest request){
|
||||
request.setApiKey(apiKey);
|
||||
return difyDataset.page(request);
|
||||
@ -41,7 +40,6 @@ public class V1DatasetController {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/createDocumentByFile")
|
||||
@PreAuthorize("hasAuthority('dify:dataset:create')")
|
||||
@OperationLogAnnotation(content = "'dify知识库文档'", operationType = "新建")
|
||||
public DocumentCreateResponse createDocumentByFile(DocumentCreateByFileRequest request){
|
||||
return ExceptionUtil.difyException(() -> difyDataset.createDocumentByFile(request));
|
||||
@ -54,7 +52,6 @@ public class V1DatasetController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/pageDocument")
|
||||
@PreAuthorize("hasAuthority('dify:dataset:query')")
|
||||
public DifyPageResult<DocumentInfo> pageDocument(@RequestBody DatasetPageDocumentRequest request){
|
||||
request.setApiKey(apiKey);
|
||||
return difyDataset.pageDocument(request);
|
||||
@ -68,7 +65,6 @@ public class V1DatasetController {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/uploadFileInfo")
|
||||
@PreAuthorize("hasAuthority('dify:dataset:query')")
|
||||
public UploadFileInfoResponse uploadFileInfo(String datasetId, String documentId){
|
||||
return difyDataset.uploadFileInfo(datasetId, documentId,apiKey);
|
||||
}
|
||||
@ -81,7 +77,6 @@ public class V1DatasetController {
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping("/deleteDocument")
|
||||
@PreAuthorize("hasAuthority('dify:dataset:delete')")
|
||||
@OperationLogAnnotation(content = "'dify知识库文档'", operationType = "删除")
|
||||
public void deleteDocument(String datasetId, String documentId){
|
||||
difyDataset.deleteDocument(datasetId, documentId, apiKey);
|
||||
@ -94,7 +89,6 @@ public class V1DatasetController {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/createSegment")
|
||||
@PreAuthorize("hasAuthority('dify:dataset:create')")
|
||||
@OperationLogAnnotation(content = "'dify知识库文档分段'", operationType = "新建")
|
||||
public SegmentResponse createSegment(@RequestBody SegmentCreateRequest request){
|
||||
return difyDataset.createSegment(request);
|
||||
@ -107,7 +101,6 @@ public class V1DatasetController {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/createSegmentChildChunk")
|
||||
@PreAuthorize("hasAuthority('dify:dataset:create')")
|
||||
@OperationLogAnnotation(content = "'dify知识库文档子分段'", operationType = "新建")
|
||||
public SegmentChildChunkCreateResponse createSegmentChildChunk(@RequestBody SegmentChildChunkCreateRequest request){
|
||||
return difyDataset.createSegmentChildChunk(request);
|
||||
@ -120,7 +113,6 @@ public class V1DatasetController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/retrieve")
|
||||
@PreAuthorize("hasAuthority('dify:dataset:retrieve')")
|
||||
public RetrieveResponse retrieve(@RequestBody RetrieveRequest request){
|
||||
return difyDataset.retrieve(request);
|
||||
}
|
||||
|
@ -2,28 +2,37 @@ package com.zsc.edu.dify.modules.dify.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.zsc.edu.dify.framework.mybatisplus.DataPermission;
|
||||
import com.zsc.edu.dify.modules.dify.dto.WorkflowDeptDto;
|
||||
import com.zsc.edu.dify.modules.dify.entity.AppEntity;
|
||||
import com.zsc.edu.dify.modules.dify.entity.WorkflowDept;
|
||||
import com.zsc.edu.dify.modules.dify.service.AppEntityService;
|
||||
import com.zsc.edu.dify.modules.dify.service.WorkflowDeptService;
|
||||
import com.zsc.edu.dify.modules.operationLog.entity.OperationLogAnnotation;
|
||||
import io.github.guoshiqiufeng.dify.server.DifyServer;
|
||||
import io.github.guoshiqiufeng.dify.server.dto.response.ApiKeyResponseVO;
|
||||
import io.github.guoshiqiufeng.dify.server.dto.response.AppsResponseVO;
|
||||
import io.github.guoshiqiufeng.dify.server.dto.response.DatasetApiKeyResponseVO;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@AllArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/server")
|
||||
public class V1ServerController {
|
||||
|
||||
@Resource
|
||||
private DifyServer difyServer;
|
||||
@Resource
|
||||
|
||||
private AppEntityService appEntityService;
|
||||
|
||||
private final WorkflowDeptService workflowDeptService;
|
||||
|
||||
/**
|
||||
* 获取应用列表
|
||||
* @param mode 模式 chat\agent-chat\completion\advanced-chat\workflow
|
||||
@ -31,10 +40,8 @@ public class V1ServerController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/apps")
|
||||
@PreAuthorize("hasAuthority('dify:server:query')")
|
||||
@DataPermission
|
||||
public List<AppsResponseVO> getApps(String mode, String name) {
|
||||
return appEntityService.getApps(mode, name);
|
||||
public List<AppEntity> getApps(String mode, String name, Integer type) {
|
||||
return appEntityService.getApps(mode, name, type);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,7 +50,6 @@ public class V1ServerController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAuthority('dify:server:query')")
|
||||
public AppsResponseVO getApp(@PathVariable("id") String id) {
|
||||
return difyServer.app(id);
|
||||
}
|
||||
@ -54,7 +60,6 @@ public class V1ServerController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api-key/{id}")
|
||||
@PreAuthorize("hasAuthority('dify:server:query')")
|
||||
public List<ApiKeyResponseVO> getAppApiKey(@PathVariable("id") String id) {
|
||||
return difyServer.getAppApiKey(id);
|
||||
}
|
||||
@ -65,7 +70,6 @@ public class V1ServerController {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api-key/init/{id}")
|
||||
@PreAuthorize("hasAuthority('dify:server:init')")
|
||||
public List<ApiKeyResponseVO> initAppApiKey(@PathVariable("id") String id) {
|
||||
return difyServer.initAppApiKey(id);
|
||||
}
|
||||
@ -75,7 +79,6 @@ public class V1ServerController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api-key/dataset")
|
||||
@PreAuthorize("hasAuthority('dify:server:query')")
|
||||
public List<DatasetApiKeyResponseVO> getDatasetApiKey() {
|
||||
return difyServer.getDatasetApiKey();
|
||||
}
|
||||
@ -85,7 +88,6 @@ public class V1ServerController {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api-key/dataset/init")
|
||||
@PreAuthorize("hasAuthority('dify:server:init')")
|
||||
public List<DatasetApiKeyResponseVO> initDatasetApiKey() {
|
||||
return difyServer.initDatasetApiKey();
|
||||
}
|
||||
@ -97,7 +99,6 @@ public class V1ServerController {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/app/{id}/toggle")
|
||||
@PreAuthorize("hasAuthority('dify:server:update')")
|
||||
@OperationLogAnnotation(content = "'dify服务启用状态'", operationType = "更新")
|
||||
public boolean enabledApp(@PathVariable String id) {
|
||||
return appEntityService.enabledApp(id);
|
||||
@ -108,7 +109,6 @@ public class V1ServerController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/apps/enabled")
|
||||
@PreAuthorize("hasAuthority('dify:server:query')")
|
||||
@DataPermission
|
||||
public List<AppEntity> getEnableApps() {
|
||||
LambdaQueryWrapper<AppEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
@ -122,9 +122,21 @@ public class V1ServerController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/apps/type")
|
||||
@PreAuthorize("hasAuthority('dify:server:query')")
|
||||
@DataPermission
|
||||
// @DataPermission
|
||||
public List<AppEntity> getAppsByAppType(Integer appType){
|
||||
return appEntityService.selectByAppType(appType);
|
||||
}
|
||||
|
||||
@PostMapping("/link")
|
||||
public ResponseEntity<String> link(@RequestBody WorkflowDeptDto workflowDeptDto) {
|
||||
List<WorkflowDept> workflowDepts = new ArrayList<>();
|
||||
for (Long deptId: workflowDeptDto.getDeptIds()) {
|
||||
workflowDepts.add(new WorkflowDept(workflowDeptDto.getWorkflowId(), deptId));
|
||||
}
|
||||
// 删除旧的关联关系
|
||||
workflowDeptService.remove(new LambdaQueryWrapper<WorkflowDept>().eq(WorkflowDept::getWorkflowId, workflowDeptDto.getWorkflowId()));
|
||||
return workflowDeptService.saveBatch(workflowDepts) ?
|
||||
ResponseEntity.ok("关联成功") :
|
||||
ResponseEntity.status(HttpStatus.BAD_REQUEST).body("关联失败");
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,6 @@ public class V1WorkflowController {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/run/{appId}")
|
||||
@PreAuthorize("hasAnyAuthority('dify:workflow:run','dify:ppt:run','dify:spider2:run')")
|
||||
@OperationLogAnnotation(content = "'dify工作流'", operationType = "运行")
|
||||
public WorkflowRunResponse runWorkflow(@RequestBody WorkflowRunRequest request, @PathVariable String appId) {
|
||||
request.setUserId(SecurityUtil.getUserInfo().id.toString());
|
||||
@ -79,7 +78,6 @@ public class V1WorkflowController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/info/{appId}")
|
||||
@PreAuthorize("hasAnyAuthority('dify:workflow:info','dify:ppt:info','dify:spider2:info')")
|
||||
public WorkflowInfoResponse info(String workflowRunId, @PathVariable String appId) {
|
||||
String apiKey =appEntityService.getApikey(appId);
|
||||
return ExceptionUtil.difyException(() -> difyWorkflow.info(workflowRunId, apiKey));
|
||||
@ -92,7 +90,6 @@ public class V1WorkflowController {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/logs/{appId}")
|
||||
@PreAuthorize("hasAnyAuthority('dify:workflow:log','dify:ppt:log','dify:spider2:log')")
|
||||
public DifyPageResult<WorkflowLogs> logs(@RequestBody WorkflowLogsRequest request, @PathVariable String appId) {
|
||||
String apiKey = appEntityService.getApikey(appId);
|
||||
request.setApiKey(apiKey);
|
||||
@ -107,7 +104,6 @@ public class V1WorkflowController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/list/{appId}")
|
||||
@PreAuthorize("hasAnyAuthority('dify:workflow:query','dify:ppt:query','dify:spider2:query')")
|
||||
@DataPermission
|
||||
public List<WorkflowData> list(@PathVariable String appId){
|
||||
return difyWorkflowService.list(new QueryWrapper<WorkflowData>().eq("app_id",appId));
|
||||
@ -120,7 +116,6 @@ public class V1WorkflowController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/detail/{id}")
|
||||
@PreAuthorize("hasAnyAuthority('dify:workflow:query','dify:ppt:query','dify:spider2:query')")
|
||||
@DataPermission
|
||||
public WorkflowData detail(@PathVariable Long id){
|
||||
return difyWorkflowService.detail(id);
|
||||
@ -133,7 +128,6 @@ public class V1WorkflowController {
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping("/delete/{id}")
|
||||
@PreAuthorize("hasAuthority('dify:workflow:delete')")
|
||||
@OperationLogAnnotation(content = "'dify工作流日志'", operationType = "删除")
|
||||
public boolean delete(@PathVariable Long id){
|
||||
return difyWorkflowService.delete(id);
|
||||
@ -146,7 +140,6 @@ public class V1WorkflowController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/query")
|
||||
@PreAuthorize("hasAuthority('dify:workflow:query')")
|
||||
@DataPermission
|
||||
public Page<WorkflowData> query(Page<WorkflowData> page){
|
||||
return difyWorkflowService.query(page);
|
||||
|
@ -1,7 +1,9 @@
|
||||
package com.zsc.edu.dify.modules.dify.controller;
|
||||
|
||||
import com.zsc.edu.dify.exception.ExceptionUtil;
|
||||
import com.zsc.edu.dify.framework.mybatisplus.DataPermission;
|
||||
import com.zsc.edu.dify.framework.security.SecurityUtil;
|
||||
import com.zsc.edu.dify.modules.dify.entity.AppEntity;
|
||||
import com.zsc.edu.dify.modules.dify.service.AppEntityService;
|
||||
import com.zsc.edu.dify.modules.operationLog.entity.OperationLogAnnotation;
|
||||
import io.github.guoshiqiufeng.dify.chat.DifyChat;
|
||||
@ -11,6 +13,8 @@ import jakarta.annotation.Resource;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/word")
|
||||
public class WordController {
|
||||
@ -27,12 +31,21 @@ public class WordController {
|
||||
* 用户 id可以改为从上下文(token)获取,
|
||||
* apikey 建议在数据库进行存储,前端调用时传智能体 id,从数据库查询
|
||||
*/
|
||||
@PostMapping("/completions")
|
||||
@PreAuthorize("hasAuthority('dify:word:send')")
|
||||
@PostMapping("/completions/{appId}")
|
||||
@OperationLogAnnotation(content = "'dify对话'", operationType = "发送")
|
||||
public ChatMessageSendResponse sendChatMessage(@RequestBody ChatMessageSendRequest sendRequest){
|
||||
sendRequest.setApiKey(appEntityService.getApikey("baca08c1-e92b-4dc9-a445-3584803f54d4"));
|
||||
public ChatMessageSendResponse sendChatMessage(@RequestBody ChatMessageSendRequest sendRequest, @PathVariable String appId){
|
||||
sendRequest.setApiKey(appEntityService.getApikey(appId));
|
||||
sendRequest.setUserId(SecurityUtil.getUserInfo().id.toString());
|
||||
return ExceptionUtil.difyException(()->difyChat.send(sendRequest));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据appType获取应用列表
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/apps")
|
||||
@DataPermission
|
||||
public List<AppEntity> getAppsByAppType(){
|
||||
return appEntityService.selectByAppType(AppEntity.AppType.WORD.getValue());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
package com.zsc.edu.dify.modules.dify.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class WorkflowDeptDto {
|
||||
@NotNull
|
||||
private String workflowId;
|
||||
@NotNull
|
||||
private Long[] deptIds;
|
||||
}
|
@ -19,7 +19,6 @@ import java.util.Map;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Getter
|
||||
@Setter
|
||||
@Data
|
||||
@TableName("apps_entity")
|
||||
public class AppEntity extends AppsResponseVO {
|
||||
|
||||
@ -70,4 +69,9 @@ public class AppEntity extends AppsResponseVO {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
public AppEntity(String id, Long deptId) {
|
||||
this.setId(id);
|
||||
this.deptId = deptId;
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Data
|
||||
@TableName("workflow_data")
|
||||
public class WorkflowData{
|
||||
@TableId
|
||||
|
@ -0,0 +1,12 @@
|
||||
package com.zsc.edu.dify.modules.dify.entity;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class WorkflowDept {
|
||||
private String workflowId;
|
||||
private Long deptId;
|
||||
}
|
@ -2,10 +2,15 @@ package com.zsc.edu.dify.modules.dify.repo;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.zsc.edu.dify.modules.dify.entity.AppEntity;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface AppEntityRepository extends BaseMapper<AppEntity> {
|
||||
|
||||
@Select("select api_key from apps_entity where id = #{appId}")
|
||||
String selectApiKey(String appId);
|
||||
|
||||
List<AppEntity> selectByAppType(@Param("deptId") Long deptId, @Param("appType") Integer appType);
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package com.zsc.edu.dify.modules.dify.repo;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.zsc.edu.dify.modules.dify.entity.WorkflowDept;
|
||||
|
||||
public interface WorkflowDeptRepository extends BaseMapper<WorkflowDept> {
|
||||
}
|
@ -2,12 +2,11 @@ package com.zsc.edu.dify.modules.dify.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.zsc.edu.dify.modules.dify.entity.AppEntity;
|
||||
import io.github.guoshiqiufeng.dify.server.dto.response.AppsResponseVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface AppEntityService extends IService<AppEntity> {
|
||||
List<AppsResponseVO> getApps(String mode, String name);
|
||||
List<AppEntity> getApps(String mode, String name, Integer appType);
|
||||
|
||||
boolean enabledApp(String id);
|
||||
|
||||
|
@ -3,9 +3,12 @@ package com.zsc.edu.dify.modules.dify.service.Impl;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.zsc.edu.dify.exception.ConstraintException;
|
||||
import com.zsc.edu.dify.framework.security.SecurityUtil;
|
||||
import com.zsc.edu.dify.modules.dify.entity.AppEntity;
|
||||
import com.zsc.edu.dify.modules.dify.entity.WorkflowDept;
|
||||
import com.zsc.edu.dify.modules.dify.mapper.AppEntityMapper;
|
||||
import com.zsc.edu.dify.modules.dify.repo.AppEntityRepository;
|
||||
import com.zsc.edu.dify.modules.dify.repo.WorkflowDeptRepository;
|
||||
import com.zsc.edu.dify.modules.dify.service.AppEntityService;
|
||||
import io.github.guoshiqiufeng.dify.server.DifyServer;
|
||||
import io.github.guoshiqiufeng.dify.server.dto.response.ApiKeyResponseVO;
|
||||
@ -14,6 +17,7 @@ import jakarta.annotation.Resource;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -23,16 +27,23 @@ import java.util.*;
|
||||
@AllArgsConstructor
|
||||
@Service
|
||||
public class AppEntityServiceImpl extends ServiceImpl<AppEntityRepository, AppEntity> implements AppEntityService {
|
||||
@Resource
|
||||
private AppEntityMapper appEntityMapper;
|
||||
@Resource
|
||||
private DifyServer difyServer;
|
||||
@Resource
|
||||
private AppEntityRepository appEntityRepository;
|
||||
|
||||
private final AppEntityMapper appEntityMapper;
|
||||
|
||||
private final DifyServer difyServer;
|
||||
|
||||
private final AppEntityRepository appEntityRepository;
|
||||
|
||||
private final WorkflowDeptRepository workflowDeptRepository;
|
||||
|
||||
|
||||
@Override
|
||||
public List<AppsResponseVO> getApps(String mode, String name) {
|
||||
return addApps(difyServer.apps(mode, name));
|
||||
public List<AppEntity> getApps(String mode, String name, Integer type) {
|
||||
return this.lambdaQuery()
|
||||
.eq(StringUtils.hasText(mode), AppEntity::getMode, mode)
|
||||
.eq(StringUtils.hasText(name), AppEntity::getName, name)
|
||||
.eq(Objects.nonNull(type), AppEntity::getAppType, type)
|
||||
.list();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,9 +108,8 @@ public class AppEntityServiceImpl extends ServiceImpl<AppEntityRepository, AppEn
|
||||
*/
|
||||
@Override
|
||||
public List<AppEntity> selectByAppType(Integer appType) {
|
||||
return this.lambdaQuery()
|
||||
.eq(AppEntity::getAppType, appType)
|
||||
.list();
|
||||
Long deptId = SecurityUtil.getUserInfo().getDept().getId();
|
||||
return baseMapper.selectByAppType(deptId, appType);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.zsc.edu.dify.modules.dify.service.Impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.zsc.edu.dify.modules.dify.entity.WorkflowDept;
|
||||
import com.zsc.edu.dify.modules.dify.repo.WorkflowDeptRepository;
|
||||
import com.zsc.edu.dify.modules.dify.service.WorkflowDeptService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class WorkflowDeptServiceImpl extends ServiceImpl<WorkflowDeptRepository, WorkflowDept> implements WorkflowDeptService {
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.zsc.edu.dify.modules.dify.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.zsc.edu.dify.modules.dify.entity.WorkflowDept;
|
||||
|
||||
public interface WorkflowDeptService extends IService<WorkflowDept> {
|
||||
}
|
@ -91,7 +91,7 @@ public class UserController {
|
||||
* @param dto 表单数据
|
||||
* @return 更新后的用户信息
|
||||
*/
|
||||
@OperationLogAnnotation(content = "信息", operationType = "更新")
|
||||
@OperationLogAnnotation(content = "'信息'", operationType = "更新")
|
||||
@PatchMapping("self")
|
||||
public Boolean selfUpdate(
|
||||
@AuthenticationPrincipal UserDetailsImpl userDetails,
|
||||
|
@ -11,6 +11,7 @@ import java.io.Serializable;
|
||||
*/
|
||||
@Data
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@TableName("sys_users_roles")
|
||||
public class UserRole implements Serializable {
|
||||
/**
|
||||
|
@ -2,6 +2,7 @@ package com.zsc.edu.dify.modules.system.repo;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.zsc.edu.dify.modules.system.entity.RoleMenu;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
@ -14,4 +15,7 @@ public interface RoleMenuRepository extends BaseMapper<RoleMenu> {
|
||||
|
||||
@Select("select * from sys_role_menu where role_id = #{id}")
|
||||
List<RoleMenu> findByRoleId(@Param("id") Long id);
|
||||
|
||||
@Delete("delete from sys_role_menu where role_id = #{id}")
|
||||
int deleteByRoleId(@Param("id") Long id);
|
||||
}
|
||||
|
@ -92,21 +92,14 @@ public class RoleServiceImpl extends ServiceImpl<RoleRepository, Role> implement
|
||||
selectyRole.setRemark(dto.getRemark());
|
||||
updateById(selectyRole);
|
||||
if (dto.getMenuIds() != null && !dto.getMenuIds().isEmpty()) {
|
||||
// 查询当前角色已有的菜单权限
|
||||
List<RoleMenu> existingRoleMenus = roleMenuRepository.findByRoleId(id);
|
||||
Set<Long> existingMenuIds = existingRoleMenus.stream()
|
||||
.map(RoleMenu::getMenuId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 筛选出不存在的菜单ID组合进行插入
|
||||
// 删除已有的菜单
|
||||
roleMenuRepository.deleteByRoleId(id);
|
||||
List<RoleMenu> roleMenusToInsert = dto.getMenuIds().stream()
|
||||
.filter(menuId -> !existingMenuIds.contains(menuId))
|
||||
.map(menuId -> new RoleMenu(id, menuId))
|
||||
.collect(Collectors.toList());
|
||||
// 插入新的关联菜单
|
||||
roleMenuRepository.insert(roleMenusToInsert);
|
||||
|
||||
if (!roleMenusToInsert.isEmpty()) {
|
||||
roleMenuRepository.insert(roleMenusToInsert);
|
||||
}
|
||||
}
|
||||
return selectyRole;
|
||||
}
|
||||
|
@ -148,7 +148,8 @@ public class UserServiceImpl extends ServiceImpl<UserRepository, User> implement
|
||||
throw new ConstraintException("角色不存在");
|
||||
}
|
||||
UserDetailsImpl userDetails = SecurityUtil.getUserInfo();
|
||||
boolean updated = lambdaUpdate().eq(User::getId, userDetails.getId())
|
||||
boolean updated = lambdaUpdate()
|
||||
.eq(User::getId, userDetails.getId())
|
||||
.set(User::getRoleId, roleId)
|
||||
.update();
|
||||
userDetails.setRole(role);
|
||||
@ -164,12 +165,7 @@ public class UserServiceImpl extends ServiceImpl<UserRepository, User> implement
|
||||
|
||||
public Boolean addUserRole(List<Long> roleIds, Long userId) {
|
||||
List<UserRole> userRoles = roleIds.stream()
|
||||
.map(roleId -> {
|
||||
UserRole userRole = new UserRole();
|
||||
userRole.setUserId(userId);
|
||||
userRole.setRoleId(roleId);
|
||||
return userRole;
|
||||
})
|
||||
.map(roleId -> new UserRole(userId, roleId))
|
||||
.collect(Collectors.toList());
|
||||
userRolesRepository.insert(userRoles);
|
||||
return true;
|
||||
|
@ -59,6 +59,10 @@ spring:
|
||||
socketFactoryClass: javax.net.ssl.SSLSocketFactory
|
||||
#表示开启 DEBUG 模式,这样,邮件发送过程的日志会在控制台打印出来,方便排查错误
|
||||
debug: true
|
||||
http:
|
||||
client:
|
||||
connect-timeout: 1800000
|
||||
read-timeout: 1800000
|
||||
|
||||
storage:
|
||||
attachment: ./storage/attachment
|
||||
@ -70,9 +74,16 @@ jwt:
|
||||
|
||||
dify:
|
||||
url: http://47.112.173.8:6800/ # 请替换为实际的 Dify 服务地址
|
||||
# url: http://172.16.35.190 # 请替换为实际的 Dify 服务地址
|
||||
server:
|
||||
email: 2913129173@qq.com # 请替换为实际的 Dify 服务邮箱,若不需要调用 server相关接口可不填
|
||||
password: tian14384, # 请替换为实际的 Dify 服务密码,若不需要调用 server相关接口可不填
|
||||
# email: admin@admin.com # 请替换为实际的 Dify 服务邮箱,若不需要调用 server相关接口可不填
|
||||
# password: Anheng@keji_777 # 请替换为实际的 Dify 服务密码,若不需要调用 server相关接口可不填
|
||||
dataset:
|
||||
api-key: dataset-kN5WTJ8jR877YfN1A34JceVg # 请替换为实际的知识库api-key, 若不需要调用知识库可不填
|
||||
|
||||
quanguo:
|
||||
url: http://${QUANGUO_HOST:47.112.173.8:6806/api/v1}
|
||||
api-key: ${QUANGUO_API_KEY:77c068fd-d5b6-4c33-97d8-db5511a09b26}
|
||||
|
||||
|
@ -3,21 +3,35 @@ server:
|
||||
|
||||
mybatis-plus:
|
||||
type-aliases-package: com.zsc.edu.dify.modules.*.entity
|
||||
mapper-locations: classpath:mappers/*/*.xml
|
||||
mapper-locations: classpath*:mappers/*/*.xml
|
||||
type-handlers-package: com.zsc.edu.dify.framework.mybatisplus
|
||||
configuration:
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
|
||||
map-underscore-to-camel-case: true
|
||||
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:postgresql://localhost:5432/gateway?ssl=false&TimeZone=Asia/Shanghai
|
||||
url: jdbc:postgresql://${POSTGRES_HOST:postgres}:5432/dify?ssl=false&TimeZone=Asia/Shanghai
|
||||
username: postgres
|
||||
password: 123456
|
||||
password: postgres
|
||||
driver-class-name: org.postgresql.Driver
|
||||
hikari:
|
||||
max-lifetime: 1800000
|
||||
idle-timeout: 600000
|
||||
validation-timeout: 5000
|
||||
data:
|
||||
redis:
|
||||
host: 43.139.10.64
|
||||
port: 16379
|
||||
password:
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 40MB
|
||||
max-request-size: 40MB
|
||||
jackson:
|
||||
# 属性为空不序列化
|
||||
default-property-inclusion: non_null
|
||||
mail:
|
||||
# 配置 SMTP 服务器地址
|
||||
host: smtp.qq.com
|
||||
@ -33,10 +47,29 @@ spring:
|
||||
properties:
|
||||
mail:
|
||||
smtp:
|
||||
auth: true
|
||||
starttls:
|
||||
enable: true
|
||||
socketFactoryClass: javax.net.ssl.SSLSocketFactory
|
||||
#表示开启 DEBUG 模式,这样,邮件发送过程的日志会在控制台打印出来,方便排查错误
|
||||
debug: true
|
||||
|
||||
storage:
|
||||
attachment: ./storage/attachment
|
||||
temp: ./storage/temp
|
||||
|
||||
jwt:
|
||||
secret: your_secret_key_here
|
||||
expiration: 3600
|
||||
|
||||
dify:
|
||||
url: http://${DIFY_HOST:localhost}/ # 请替换为实际的 Dify 服务地址
|
||||
server:
|
||||
email: ${DIFY_EMAIL:admin@admin.com} # 请替换为实际的 Dify 服务邮箱,若不需要调用 server相关接口可不填
|
||||
password: ${DIFY_PASSWORD:Anheng@keji_777} # 请替换为实际的 Dify 服务密码,若不需要调用 server相关接口可不填
|
||||
dataset:
|
||||
api-key: ${DIFY_DATASET_API_KEY:dataset-kN5WTJ8jR877YfN1A34JceVg} # 请替换为实际的知识库api-key, 若不需要调用知识库可不填
|
||||
|
||||
guangzhou:
|
||||
url: ${GUANGZHOU_HOST:http://47.112.173.8:6806/api/v1}
|
||||
api-key: ${GUANGZHOU_API_KEY:ed01e58b-c537-4837-9907-8d9bec2efa55}
|
@ -1,6 +1,6 @@
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
active: ${PROF_ACTIVE:dev}
|
||||
docker:
|
||||
compose:
|
||||
enabled: false
|
||||
|
21
src/main/resources/mappers/dify/AppEntityMapper.xml
Normal file
21
src/main/resources/mappers/dify/AppEntityMapper.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.zsc.edu.dify.modules.dify.repo.AppEntityRepository">
|
||||
|
||||
|
||||
<select id="selectByAppType" resultType="appEntity">
|
||||
select ae.* from apps_entity ae
|
||||
left join workflow_dept wd on wd.workflow_id = ae.id
|
||||
<where>
|
||||
<if test="deptId != null">
|
||||
and wd.dept_id = #{deptId}
|
||||
</if>
|
||||
<if test="appType != null">
|
||||
and ae.app_type = #{appType}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
20
src/main/resources/mappers/dify/AppEntityRepository.xml
Normal file
20
src/main/resources/mappers/dify/AppEntityRepository.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.zsc.edu.dify.modules.dify.repo.AppEntityRepository">
|
||||
|
||||
<select id="selectByAppType" resultType="com.zsc.edu.dify.modules.dify.entity.AppEntity">
|
||||
select ae.* from apps_entity ae
|
||||
left join workflow_dept wd on ae.id=wd.workflow_id
|
||||
<where>
|
||||
<if test="appType != null">
|
||||
and ae.app_type=#{appType}
|
||||
</if>
|
||||
<if test="deptId != null">
|
||||
and wd.dept_id=#{deptId}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
@ -0,0 +1,18 @@
|
||||
package com.zsc.edu.dify.modules.dify.repo;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@SpringBootTest
|
||||
class AppEntityRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
private AppEntityRepository appEntityRepository;
|
||||
@Test
|
||||
void selectByAppType() {
|
||||
appEntityRepository.selectByAppType(1L, 1);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user