api接口代码提交

feature/yangjinping_branch
1545558448 1 year ago
parent dcd9d9117c
commit 5b455bcfc6

39
api/.gitignore vendored

@ -0,0 +1,39 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
.idea/*
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.intelligentHealthCare</groupId>
<artifactId>IntelligentHealthCare</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.intelligentHealthCare</groupId>
<artifactId>api</artifactId>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--devtools热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-security</artifactId>-->
<!-- </dependency>-->
<!--nacos依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- nacos的配置管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.intelligentHealthCare</groupId>
<artifactId>feign-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 引入图形验证码依赖 -->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 指定该 Main Class 为全局的唯一入口 -->
<mainClass>com.intelligentHealthCare.ApiApplication</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<!-- 将依赖到的包都放进去 -->
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,185 @@
package com.intelligentHealthCare;
import com.intelligentHealthCare.annotation.NoAuth;
import com.intelligentHealthCare.config.CommonAppProperty;
import com.intelligentHealthCare.config.DefaultFeignConfiguration;
import com.intelligentHealthCare.remote.ApiServiceRemote;
import com.intelligentHealthCare.security.UrlMethodAccessDecision;
import com.querydsl.core.util.ArrayUtils;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.*;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@SpringBootApplication
@EnableDiscoveryClient
@RefreshScope
@EnableAspectJAutoProxy
@Slf4j
@EnableFeignClients(basePackages = {"com.intelligentHealthCare"}, defaultConfiguration = {DefaultFeignConfiguration.class})
@EnableCaching
public class ApiApplication {
private final static String BASE_PACKAGE = "com.intelligentHealthCare.api.controller";
private final static String RESOURCE_PATTERN = "/**/*.class";
public static void main(String[] args) throws ClassNotFoundException {
ApplicationContext context = SpringApplication.run(ApiApplication.class, args);
ApiServiceRemote apiServiceRemote = context.getBean(ApiServiceRemote.class);
UrlMethodAccessDecision urlMethodAccessDecision = context.getBean(UrlMethodAccessDecision.class);
CommonAppProperty commonAppProperty = context.getBean(CommonAppProperty.class);
init(apiServiceRemote, urlMethodAccessDecision, commonAppProperty);
}
public static void init(ApiServiceRemote apiServiceRemote, UrlMethodAccessDecision urlMethodAccessDecision, CommonAppProperty commonAppProperty) {
//spring工具类可以获取指定路径下的全部类
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
ClassUtils.convertClassNameToResourcePath(BASE_PACKAGE) + RESOURCE_PATTERN;
List<com.intelligentHealthCare.entity.Api> resultApi = apiServiceRemote.getAll();
LinkedList<com.intelligentHealthCare.entity.Api> apis = new LinkedList<>();
LinkedList<String> noAuthApis = new LinkedList<>();
try {
Resource[] resources = resourcePatternResolver.getResources(pattern);
//MetadataReader 的工厂类
MetadataReaderFactory readerfactory = new CachingMetadataReaderFactory(resourcePatternResolver);
for (Resource resource : resources) {
//用于读取类信息
MetadataReader reader = readerfactory.getMetadataReader(resource);
//扫描到的class
String classname = reader.getClassMetadata().getClassName();
Class<?> clazz = Class.forName(classname);
//判断是否有指定主解
RequestMapping annotation = clazz.getAnnotation(RequestMapping.class);
Api apiAnnotation = clazz.getAnnotation(Api.class);
String prefixUrl = "";
String prefixName = "";
if (annotation != null) {
prefixUrl = annotation.value()[0].replace("${app.baseService}", commonAppProperty.getBaseService());
}
if (apiAnnotation != null) {
prefixName = apiAnnotation.tags()[0];
}
if (prefixName.equals("") && prefixName.equals("")) {
continue;
}
Method[] methods = clazz.getMethods();
for (Method method : methods) {
AtomicBoolean checkSameMethod = new AtomicBoolean(false);
com.intelligentHealthCare.entity.Api api = new com.intelligentHealthCare.entity.Api();
Operation operation = method.getAnnotation(Operation.class);
PostMapping postMapping = method.getAnnotation(PostMapping.class);
DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
PutMapping putMapping = method.getAnnotation(PutMapping.class);
GetMapping getMapping = method.getAnnotation(GetMapping.class);
NoAuth noAuth = method.getAnnotation(NoAuth.class);
if (operation == null) {
continue;
}
api.setName(prefixName + "-" + operation.summary());
if (postMapping != null) {
if (!ArrayUtils.isEmpty(postMapping.value())) {
api.setRest(prefixUrl + postMapping.value()[0]);
} else {
api.setRest(prefixUrl);
}
api.setMethod("POST");
}
if (deleteMapping != null) {
if (!ArrayUtils.isEmpty(deleteMapping.value())) {
api.setRest(prefixUrl + deleteMapping.value()[0]);
} else {
api.setRest(prefixUrl);
}
api.setMethod("DELETE");
}
if (putMapping != null) {
if (!ArrayUtils.isEmpty(putMapping.value())) {
api.setRest(prefixUrl + putMapping.value()[0]);
} else {
api.setRest(prefixUrl);
}
api.setMethod("PUT");
}
if (getMapping != null) {
if (!ArrayUtils.isEmpty(getMapping.value())) {
api.setRest(prefixUrl + getMapping.value()[0]);
} else {
api.setRest(prefixUrl);
}
api.setMethod("GET");
}
if (noAuth != null) {
noAuthApis.add(api.getRest());
continue;
}
resultApi.forEach(i -> {
//相同菜单
if (i.getName().equals(api.getName()) && i.getRest().equals(api.getRest()) && i.getMethod().equals(api.getMethod())) {
checkSameMethod.set(true);
return;
}
//方法和名称相同但是api路径不相同的api更新api路径
if (i.getName().equals(api.getName()) && !i.getRest().equals(api.getRest()) && i.getMethod().equals(api.getMethod())) {
api.setId(i.getId());
return;
}
//名称相同,路径不同,方法不同,更新路径和方法
if (i.getName().equals(api.getName()) && !i.getRest().equals(api.getRest()) && !i.getMethod().equals(api.getMethod())) {
api.setId(i.getId());
return;
}
//路径相同,方法相同,名称不同,更新名称
if (!i.getName().equals(api.getName()) && i.getRest().equals(api.getRest()) && i.getMethod().equals(api.getMethod())) {
api.setId(i.getId());
return;
}
//路径相同,名称相同,方法不同,更新方法
if (i.getName().equals(api.getName()) && i.getRest().equals(api.getRest()) && !i.getMethod().equals(api.getMethod())) {
api.setId(i.getId());
return;
}
});
if (checkSameMethod.get()) {
continue;
}
if (api.getMethod() != null && api.getName() != null && api.getRest() != null) {
apis.add(api);
}
}
}
log.info("所有的api信息" + resultApi);
log.info("需要认证且未添加到数据库API" + apis);
log.info("无需认证API路径" + noAuthApis);
urlMethodAccessDecision.setAnonymousUrls(noAuthApis);
if (!apis.isEmpty()) {
apiServiceRemote.batchSave(apis);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

@ -0,0 +1,14 @@
package com.intelligentHealthCare.annotation;
import java.lang.annotation.*;
/**
* @author yang
* @version 1.0
* @date Created in 2023/10/4 17:48
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NoAuth {
}

@ -0,0 +1,125 @@
package com.intelligentHealthCare.aop;
import com.alibaba.fastjson.JSON;
import com.intelligentHealthCare.annotation.NoAuth;
import com.intelligentHealthCare.entity.SystemLog;
import com.intelligentHealthCare.enums.ResultCodeEnum;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.remote.SystemLogServiceRemote;
import com.intelligentHealthCare.security.SecurityUser;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
/**
* @author yang
* @version 1.0
* @date Created in 2023/10/22 08:50
*/
@Aspect
@Component
@Slf4j
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
public class SystemLogAop {
private final HttpServletRequest request;
private final SystemLogServiceRemote systemLogServiceRemote;
private SystemLog systemLog;
@Before("execution(* com.intelligentHealthCare.api.controller..*(..))")
public void beforeMethodExecution(JoinPoint joinPoint) throws UnsupportedEncodingException {
Object[] args = joinPoint.getArgs();
Object target = joinPoint.getTarget();
Class<?> targetClass = target.getClass();
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
// 获取类上的注解信息
Api api = targetClass.getAnnotation(Api.class);
Operation operation = method.getAnnotation(Operation.class);
NoAuth noAuth = method.getAnnotation(NoAuth.class);
String requestURI = URLDecoder.decode(request.getRequestURI(), StandardCharsets.UTF_8.toString());
String requestMethod = request.getMethod();
String userIP = getClientIp(request);
SecurityUser securityUser = null;
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication != null && authentication.getPrincipal() instanceof SecurityUser){
securityUser = (SecurityUser) authentication.getPrincipal();
}
systemLog = SystemLog.builder().userIp(userIP).method(requestMethod).moudle(api.tags()[0])
.operation(operation.summary()).url(requestURI).param(Arrays.toString(args))
.accountId(securityUser == null ? "未知用户" : securityUser.getAccount().getId())
.nickName(securityUser == null ? "未知用户" : securityUser.getAccount().getNickname())
.isDangerous(userIP == null || (securityUser == null && noAuth == null)).account(securityUser == null ? "" : securityUser.getAccount().getUsername()).build();
}
@AfterReturning(pointcut = "execution(* com.intelligentHealthCare.api.controller..*(..))", returning = "returnValue")
public void afterMethodExecution(JoinPoint joinPoint, Object returnValue) {
systemLog.setIsSuccess(true);
Result result = null;
if(returnValue instanceof Result) {
result = (Result) returnValue;
}
if(result != null) {
result.setStatus(ResultCodeEnum.SUCCESS);
}
systemLog.setResult(JSON.toJSONString(result));
systemLogServiceRemote.saveSystemLog(systemLog);
}
@AfterThrowing(pointcut = "execution(* com.intelligentHealthCare.api.controller..*(..))", throwing = "exception")
public void afterMethodException(JoinPoint joinPoint, Throwable exception) {
systemLog.setIsSuccess(false);
systemLog.setResult(exception.getMessage());
systemLogServiceRemote.saveSystemLog(systemLog);
}
public String getClientIp(HttpServletRequest request) {
String ipAddress = request.getHeader("X-Forwarded-For");
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if (ipAddress.equals("127.0.0.1")) {
// 根据网卡取本机配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress = inet.getHostAddress();
}
}
// 多个代理的情况第一个IP为客户端真实IP多个IP按照","分割
if (ipAddress != null && ipAddress.length() > 15) {
if (ipAddress.indexOf(",") > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
return ipAddress;
}
}

@ -0,0 +1,61 @@
package com.intelligentHealthCare.api.controller;
import com.intelligentHealthCare.annotation.NoAuth;
import com.intelligentHealthCare.dto.AccountDto;
import com.intelligentHealthCare.entity.Account;
import com.intelligentHealthCare.enums.ResultCodeEnum;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.security.SecurityUser;
import com.intelligentHealthCare.service.impl.AccountHandle;
import com.intelligentHealthCare.vo.AccountVo;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("/${app.baseService}/account")
@Api(tags = "账号管理")
public class AccountController {
@Autowired
private AccountHandle accountHandle;
@PostMapping("/register")
@Operation(summary = "账号注册")
@NoAuth
public Result<Account> register(@RequestBody Account account){
return Result.<Account>builder().data(accountHandle.register(account)).build();
}
@PostMapping("/login")
@Operation(summary = "登录")
@NoAuth
public Result<String> login(@RequestBody AccountVo accountVo, HttpServletRequest httpServletRequest){
Account account = new Account();
BeanUtils.copyProperties(accountVo, account);
return Result.<String>builder().data(accountHandle.login(account, accountVo.getCode(), httpServletRequest.getRemoteAddr())).status(ResultCodeEnum.SUCCESS).build();
}
@PostMapping("/logout")
@Operation(summary = "退出登录")
@NoAuth
public Result<Boolean> logout(){
return Result.<Boolean>builder().data(accountHandle.logout()).status(ResultCodeEnum.SUCCESS).build();
}
@GetMapping("/getAccountInfo")
@Operation(summary = "获取当前账号信息")
@NoAuth
public Result<AccountDto> getAccountInfo() {
SecurityUser securityUser = (SecurityUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
AccountDto accountDto = new AccountDto();
BeanUtils.copyProperties(securityUser.getAccount(), accountDto);
return Result.<AccountDto>builder().data(accountDto).status(ResultCodeEnum.SUCCESS).build();
}
}

@ -0,0 +1,71 @@
package com.intelligentHealthCare.api.controller;
import com.intelligentHealthCare.config.CommonAppProperty;
import com.intelligentHealthCare.entity.CommonStaticFile;
import com.intelligentHealthCare.pojo.BaseFile;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.remote.CommonStaticFileRemoteService;
import feign.Response;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
/**
* @author yang
* @version 1.0
* @date Created in 2023/11/14 14:18
*/
@RestController
@Api(tags = "公共静态资源文件管理")
@RequestMapping("/${app.baseService}/commonStaticFile")
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
public class CommonStaticFileControllerTest {
private final CommonStaticFileRemoteService commonStaticFileRemoteService;
private final CommonAppProperty commonAppProperty;
@PostMapping
@Operation(summary = "保存实体")
public Result<CommonStaticFile> save(@RequestBody CommonStaticFile commonStaticFile){
return Result.<CommonStaticFile>builder().data(commonStaticFileRemoteService.save(commonStaticFile)).build();
}
@DeleteMapping("/{id}")
@Operation(summary = "删除实体")
public Result<Boolean> delete(@PathVariable("id") String id){
return Result.<Boolean>builder().data(commonStaticFileRemoteService.delete(id)).build();
}
@GetMapping("/{id}")
@Operation(summary = "查询实体根据id")
public Result<CommonStaticFile> getById(@PathVariable("id") String id){
return Result.<CommonStaticFile>builder().data(commonStaticFileRemoteService.getById(id)).build();
}
@GetMapping("/loadStaticFile/**")
@Operation(summary = "下载静态资源文件")
public ResponseEntity<Resource> loadStaticFile(HttpServletRequest httpServletRequest, @RequestParam("filename") String filename){
String requestURI = httpServletRequest.getRequestURI();
String replace = requestURI.replace("/"+ commonAppProperty.getBaseService() + "/commonStaticFile/loadStaticFile/", "");
ResponseEntity responseEntity = commonStaticFileRemoteService.loadStaticFile(replace);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.addAll(responseEntity.getHeaders());
httpHeaders.add(HttpHeaders.CONTENT_DISPOSITION,"attachment; filename=" + filename);
return ResponseEntity.ok().headers(httpHeaders).body((Resource) responseEntity.getBody());
}
@PostMapping(path = "/saveStaticFile")
@Operation(summary = "保存静态资源文件")
public Result<BaseFile> saveStaticFile(@NotNull(message = "文件不能为空")MultipartFile file){
return Result.<BaseFile>builder().data(commonStaticFileRemoteService.saveStaticFile(file)).build();
}
}

@ -0,0 +1,73 @@
package com.intelligentHealthCare.api.controller;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.intelligentHealthCare.annotation.NoAuth;
import com.intelligentHealthCare.exception.BizException;
import com.intelligentHealthCare.utils.RedisCache;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.concurrent.TimeUnit;
/**
* @author yang
* @version 1.0
* @date Created in 2023/10/31 22:49
*/
@Controller
@RequestMapping("/${app.baseService}/kaptcha")
@Api(tags = "验证码管理")
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
@Slf4j
public class KaptchaController {
private final DefaultKaptcha defaultKaptcha;
private final RedisCache redisCache;
@GetMapping("/getCodeImg/*")
@Operation(summary = "获取验证码")
@NoAuth
public void img(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws Exception {
byte[] captchaChallengeAsJpeg = null;
ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
try {
String createText = defaultKaptcha.createText();
// 生产验证码字符串并保存到 Redis 中ip-rightCode有效期为 10 分钟
String ip = httpServletRequest.getRemoteAddr();
log.info("ip" + ip + "rightCode = " + createText);
redisCache.setCacheObject(ip, createText, 10, TimeUnit.MINUTES);
// 使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
BufferedImage challenge = defaultKaptcha.createImage(createText);
ImageIO.write(challenge, "jpg", jpegOutputStream);
} catch (IllegalArgumentException e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// 定义response输出类型为image/jpeg类型使用response输出流输出图片的byte数组
captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
httpServletResponse.setHeader("Cache-Control", "no-store");
httpServletResponse.setHeader("Pragma", "no-cache");
httpServletResponse.setDateHeader("Expires", 0);
httpServletResponse.setContentType("image/jpeg");
ServletOutputStream responseOutputStream = httpServletResponse.getOutputStream();
responseOutputStream.write(captchaChallengeAsJpeg);
responseOutputStream.flush();
responseOutputStream.close();
}
}

@ -0,0 +1,75 @@
package com.intelligentHealthCare.api.controller.client;
import com.intelligentHealthCare.config.CommonAppProperty;
import com.intelligentHealthCare.entity.Article;
import com.intelligentHealthCare.pojo.BaseFile;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.remote.ArticleServiceRemote;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
/**
* @author deng
* @version 1.0
* @date Created in 2024/4/27 09:58
*/
@RestController
@Api(tags = "文章管理")
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
@RequestMapping("/${app.baseService}/article")
public class ArticleController {
private final ArticleServiceRemote articleServiceRemote;
private final CommonAppProperty commonAppProperty;
@PostMapping
@Operation(summary = "保存实体")
public Result<Article> save(@RequestBody Article article) {
return Result.<Article>builder().data(articleServiceRemote.save(article)).build();
}
@DeleteMapping("/{id}")
@Operation(summary = "删除实体")
public Result<Boolean> delete(@PathVariable("id") String id) {
return Result.<Boolean>builder().data(articleServiceRemote.delete(id)).build();
}
@GetMapping("/{id}")
@Operation(summary = "查询实体根据id")
public Result<Article> getById(@PathVariable("id") String id) {
return Result.<Article>builder().data(articleServiceRemote.getById(id)).build();
}
@GetMapping("/loadStaticFile/**")
@Operation(summary = "下载静态资源文件")
public ResponseEntity<Resource> loadStaticFile(HttpServletRequest httpServletRequest) {
String requestURI = httpServletRequest.getRequestURI();
String replace = requestURI.replace("/" + commonAppProperty.getBaseService() + "/article/loadStaticFile/", "");
ResponseEntity responseEntity = articleServiceRemote.loadStaticFile(replace);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.addAll(responseEntity.getHeaders());
return ResponseEntity.ok().headers(httpHeaders).body((Resource) responseEntity.getBody());
}
@PostMapping(path = "/saveStaticFile")
@Operation(summary = "保存静态资源文件")
public Result<BaseFile> saveStaticFile(@RequestBody @NotNull(message = "文件不能为空") MultipartFile file) {
return Result.<BaseFile>builder().data(articleServiceRemote.saveStaticFile(file)).build();
}
@PostMapping(path = "/uploadVideo")
@Operation(summary = "上传视频")
public Result<BaseFile> uploadVideo(@RequestBody @NotNull(message = "文件不能为空") MultipartFile file) {
return Result.<BaseFile>builder().data(articleServiceRemote.saveStaticFile(file)).build();
}
}

@ -0,0 +1,66 @@
package com.intelligentHealthCare.api.controller.organization;
import com.intelligentHealthCare.condition.StaffCondition;
import com.intelligentHealthCare.dto.StaffDto;
import com.intelligentHealthCare.entity.Department;
import com.intelligentHealthCare.pojo.ConditionAndPageInfo;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.remote.DepartmentRemote;
import com.intelligentHealthCare.remote.StaffServiceRemote;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@Api(tags = "部门管理")
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
@RequestMapping("/${app.baseService}/department")
public class DepartmentController {
private final DepartmentRemote departmentRemote;
private final StaffServiceRemote staffServiceRemote;
@GetMapping
@Operation(summary = "获取全部部门")
public Result getall(@RequestParam("departmentCondition") String departmentName){
List<Department> getall = departmentRemote.getall(departmentName);
return Result.builder().data(getall).build();
}
@PostMapping("/add")
@Operation(summary = "插入部门")
public Result add(@RequestBody Department department){
departmentRemote.add(department);
return Result.builder().data("成功").build();
}
@DeleteMapping("/{id}")
@Operation(summary = "删除部门")
public Result<Object> deleteByid(@PathVariable("id") String id){
String s = departmentRemote.deleteByid(id);
return Result.builder().data(s).build();
}
@GetMapping("/{id}")
@Operation(summary = "回显部门")
public Result<Object> echoData(@PathVariable("id") String id){
Department department = departmentRemote.echoData(id);
return Result.builder().data(department).build();
}
@PutMapping
@Operation(summary = "修改部门")
public Result<Department> update(@RequestBody Department department){
return Result.<Department>builder().data(departmentRemote.update(department)).build();
}
@PostMapping("/getDepartmentStaffTree")
@Operation(summary = "获取部门员工数据树形结构")
public Result<Page<StaffDto>> getDepartmentStaffTree(@RequestBody ConditionAndPageInfo<StaffCondition> conditionAndPageInfo){
return Result.<Page<StaffDto>>builder().data(departmentRemote.getDepartmentStaffTree(conditionAndPageInfo)).build();
}
}

@ -0,0 +1,62 @@
package com.intelligentHealthCare.api.controller.organization;
import com.intelligentHealthCare.dto.OfficeDto;
import com.intelligentHealthCare.entity.Department;
import com.intelligentHealthCare.entity.Office;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.remote.DepartmentRemote;
import com.intelligentHealthCare.remote.OfficeServiceRemote;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@Api(tags = "职务管理")
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
@RequestMapping("/${app.baseService}/office")
public class OfficeController {
private final OfficeServiceRemote officeServiceRemote;
private final DepartmentRemote departmentRemote;
@GetMapping("/getTree")
@Operation(summary = "获取职务信息")
public Result getTree(){
List<Office> getTree = officeServiceRemote.getTree();
return Result.builder().data(getTree).build();
}
@DeleteMapping("/{id}")
@Operation(summary = "根据Id删除数据")
public Result<Boolean> deleteById(@PathVariable("id") String officeId){
return Result.<Boolean>builder().data(officeServiceRemote.delete(officeId)).build();
}
@PostMapping("/saveOfficeAndDepartmentOffice")
@Operation(summary = "保存实体并保存与部门关系")
public Result<OfficeDto> saveOfficeAndDepartmentOffice(@RequestBody OfficeDto officeDto){
return Result.<OfficeDto>builder().data(officeServiceRemote.saveOfficeAndDepartmentOffice(officeDto)).build();
}
@GetMapping("/getDepartmentsTree")
@Operation(summary = "获取部门树")
public Result<List<Department>> getDepartmentsTree(){
return Result.<List<Department>>builder().data(departmentRemote.getall("")).build();
}
@GetMapping("/{id}")
@Operation(summary = "获取职务通过id")
public Result<Office> getById(@PathVariable("id")String id){
return Result.<Office>builder().data(officeServiceRemote.getById(id)).build();
}
@PutMapping("/update")
@Operation(summary = "修改实体")
public Result<OfficeDto> updateDto(@RequestBody OfficeDto officeDto){
return Result.<OfficeDto>builder().data(officeServiceRemote.updateDto(officeDto)).build();
}
}

@ -0,0 +1,96 @@
package com.intelligentHealthCare.api.controller.organization;
import com.intelligentHealthCare.condition.KeywordCondition;
import com.intelligentHealthCare.config.CommonAppProperty;
import com.intelligentHealthCare.dto.StaffDto;
import com.intelligentHealthCare.entity.Office;
import com.intelligentHealthCare.entity.Role;
import com.intelligentHealthCare.enums.ResultCodeEnum;
import com.intelligentHealthCare.pojo.ConditionAndPageInfo;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.remote.CommonStaticFileRemoteService;
import com.intelligentHealthCare.remote.OfficeServiceRemote;
import com.intelligentHealthCare.remote.RoleServiceRemote;
import com.intelligentHealthCare.remote.StaffServiceRemote;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* @author yang
* @version 1.0
* @date Created in 2023/12/14 15:22
*/
@RestController
@Api(tags = "批量添加员工")
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
@RequestMapping("/${app.baseService}/staffBatchOperation")
public class StaffBatchOperationController {
private final StaffServiceRemote staffServiceRemote;
private final RoleServiceRemote roleServiceRemote;
private final OfficeServiceRemote officeServiceRemote;
private final CommonAppProperty commonAppProperty;
private final CommonStaticFileRemoteService commonStaticFileRemoteService;
@PostMapping("/batchAdd")
@Operation(summary = "批量添加员工")
public Result<List<StaffDto>> batchAdd(@RequestBody List<StaffDto> staffDto){
staffDto.forEach(i -> {
//加密密码
if(StringUtils.hasText(i.getStaffPassword())) {
i.setStaffPassword(new BCryptPasswordEncoder().encode(i.getStaffPassword()));
}
});
return Result.<List<StaffDto>>builder().data(staffServiceRemote.batchAddStaff(staffDto)).build();
}
@PostMapping("/checkBatchStaff")
@Operation(summary = "检查员工是否允许添加")
public Result<List<StaffDto>> checkBatchStaff(@RequestBody List<StaffDto> staffDtos){
return Result.<List<StaffDto>>builder().data(staffServiceRemote.checkBatchStaff(staffDtos)).build();
}
@PostMapping("/getRolePage")
@Operation(summary = "获取角色信息分页")
public Result<Page<Role>> page(@RequestBody ConditionAndPageInfo<KeywordCondition> conditionAndPageInfo){
return Result.<Page<Role>>builder().data(roleServiceRemote.getFilterList(conditionAndPageInfo)).status(ResultCodeEnum.SUCCESS).build();
}
@GetMapping("/existSameAccount/{account}")
@Operation(summary = "检查是否存在相同账号")
public Result<Boolean> existSameAccount(@PathVariable("account")String account){
return Result.<Boolean>builder().data(staffServiceRemote.existSameAccount(account)).build();
}
@GetMapping("/getOfficeTree")
@Operation(summary = "获取职务信息")
public Result<List<Office>> getTree(){
return Result.<List<Office>>builder().data(officeServiceRemote.getTree()).build();
}
@GetMapping("/downloadStaffImportFile/**")
@Operation(summary = "下载员工导入文件")
public ResponseEntity<Resource> loadStaticFile(HttpServletRequest httpServletRequest, @RequestParam("filename") String filename){
String requestURI = httpServletRequest.getRequestURI();
String replace = requestURI.replace("/"+ commonAppProperty.getBaseService() + "/staffBatchOperation/downloadStaffImportFile/", "");
return commonStaticFileRemoteService.loadStaticFile(replace);
// HttpHeaders httpHeaders = new HttpHeaders();
// httpHeaders.addAll(responseEntity.getHeaders());
// httpHeaders.add(HttpHeaders.CONTENT_DISPOSITION,"attachment; filename=" + filename);
// return ResponseEntity.ok().headers(httpHeaders).body((Resource) responseEntity.getBody());
}
}

@ -0,0 +1,102 @@
package com.intelligentHealthCare.api.controller.organization;
import com.intelligentHealthCare.condition.KeywordCondition;
import com.intelligentHealthCare.condition.StaffCondition;
import com.intelligentHealthCare.dto.StaffDto;
import com.intelligentHealthCare.entity.Office;
import com.intelligentHealthCare.entity.Role;
import com.intelligentHealthCare.enums.ResultCodeEnum;
import com.intelligentHealthCare.pojo.ConditionAndPageInfo;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.remote.OfficeServiceRemote;
import com.intelligentHealthCare.remote.OfficeStaffServiceRemote;
import com.intelligentHealthCare.remote.RoleServiceRemote;
import com.intelligentHealthCare.remote.StaffServiceRemote;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.security.core.parameters.P;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author deng
* @version 1.0
* @date Created in 2023/11/17 11:45
*/
@RestController
@Api(tags = "员工管理")
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
@RequestMapping("/${app.baseService}/staff")
public class StaffController {
private final OfficeStaffServiceRemote officeStaffServiceRemote;
private final OfficeServiceRemote officeServiceRemote;
private final RoleServiceRemote roleServiceRemote;
private final StaffServiceRemote staffServiceRemote;
@PostMapping("/page")
@Operation(summary = "获取人员信息分页")
public Result<Page<StaffDto>> getStaffDtoPage(@RequestBody ConditionAndPageInfo<StaffCondition> conditionAndPageInfo){
return Result.<Page<StaffDto>>builder().data(staffServiceRemote.getStaffDtoPage(conditionAndPageInfo)).build();
}
@GetMapping("/getOfficeTree")
@Operation(summary = "获取职务信息")
public Result<List<Office>> getTree(){
return Result.<List<Office>>builder().data(officeServiceRemote.getTree()).build();
}
@PostMapping("/getRolePage")
@Operation(summary = "获取角色信息分页")
public Result<Page<Role>> page(@RequestBody ConditionAndPageInfo<KeywordCondition> conditionAndPageInfo){
return Result.<Page<Role>>builder().data(roleServiceRemote.getFilterList(conditionAndPageInfo)).status(ResultCodeEnum.SUCCESS).build();
}
@PostMapping("/saveStaffAndOffice")
@Operation(summary = "保存员工并且保存和职务的关系")
public Result<StaffDto> saveStaffAndOffice(@RequestBody StaffDto staffDto){
//加密密码
if(StringUtils.hasText(staffDto.getStaffPassword())) {
staffDto.setStaffPassword(new BCryptPasswordEncoder().encode(staffDto.getStaffPassword()));
}
return Result.<StaffDto>builder().data(staffServiceRemote.saveStaffAndOffice(staffDto)).build();
}
@GetMapping("/getStaff/{id}")
@Operation(summary = "根据id获取员工信息")
public Result<StaffDto> findByIdDto(@PathVariable("id")String id){
return Result.<StaffDto>builder().data(staffServiceRemote.findByIdDto(id)).build();
}
@PutMapping("/updateStaff")
@Operation(summary = "修改员工信息")
public Result<StaffDto> updateStaffDto(@RequestBody StaffDto staffDto){
return Result.<StaffDto>builder().data(staffServiceRemote.updateStaffDto(staffDto)).build();
}
@DeleteMapping("/{id}")
@Operation(summary = "删除员工")
public Result<Boolean> deleteById(@PathVariable("id")String id){
return Result.<Boolean>builder().data(staffServiceRemote.delete(id)).build();
}
@GetMapping("/existSameAccount/{account}")
@Operation(summary = "检查是否存在相同账号")
public Result<Boolean> existSameAccount(@PathVariable("account")String account){
return Result.<Boolean>builder().data(staffServiceRemote.existSameAccount(account)).build();
}
@GetMapping("/updateAccountEnabledStatus/{account}/{accountEnabledStatus}")
@Operation(summary = "修改账号启用状态")
public Result<Boolean> updateAccountEnabledStatus(@PathVariable("account") String account, @PathVariable("accountEnabledStatus") Boolean accountEnabledStatus){
return Result.<Boolean>builder().data(staffServiceRemote.updateAccountEnabledStatus(account, accountEnabledStatus)).build();
}
}

@ -0,0 +1,149 @@
package com.intelligentHealthCare.api.controller.personnel;
import com.intelligentHealthCare.condition.KeywordCondition;
import com.intelligentHealthCare.condition.VolunteerCondition;
import com.intelligentHealthCare.condition.workflow.HistoryTaskCondition;
import com.intelligentHealthCare.condition.workflow.TaskCondition;
import com.intelligentHealthCare.constant.ProcessConstant;
import com.intelligentHealthCare.dto.VolunteerDto;
import com.intelligentHealthCare.dto.workflow.BaseWorkflowDto;
import com.intelligentHealthCare.dto.workflow.HistoricTaskDTO;
import com.intelligentHealthCare.dto.workflow.TaskDto;
import com.intelligentHealthCare.entity.Volunteer;
import com.intelligentHealthCare.enums.VolunteerAuditStatus;
import com.intelligentHealthCare.exception.BizException;
import com.intelligentHealthCare.pojo.ConditionAndPageInfo;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.remote.RemoteVolunteerService;
import com.intelligentHealthCare.remote.workflow.WorkflowServiceRemote;
import com.intelligentHealthCare.security.SecurityUser;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.task.model.Task;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.persistence.entity.HistoricTaskInstanceEntityImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author yang
* @version 1.0
* @date Created in 2024/1/23 21:32
* @description
*/
@RestController
@RequestMapping("/${app.baseService}/volunteer")
@Api(tags = "志愿者管理")
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
public class VolunteerController {
private final RemoteVolunteerService remoteVolunteerService;
private final WorkflowServiceRemote workflowServiceRemote;
@Operation(summary = "保存实体")
@PostMapping
public Result<VolunteerDto> save(@RequestBody VolunteerDto volunteerDto){
return Result.<VolunteerDto>builder().data(remoteVolunteerService.saveDto(volunteerDto)).build();
}
@Operation(summary = "修改实体")
@PutMapping
public Result<VolunteerDto> update(@RequestBody VolunteerDto volunteerDto){
return Result.<VolunteerDto>builder().data(remoteVolunteerService.updateDto(volunteerDto)).build();
}
@Operation(summary = "获取志愿者信息分页")
@PostMapping("/page")
public Result<Page<VolunteerDto>> page(@RequestBody ConditionAndPageInfo<VolunteerCondition> conditionAndPageInfo){
//查询当前用户的所有任务
SecurityUser securityUser = (SecurityUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
List<Task> tasks = workflowServiceRemote.getTasks(TaskCondition.builder().assignee(securityUser.getUsername()).build());
conditionAndPageInfo.getCondition().setProcessInstanceId(tasks.stream().map(Task::getProcessInstanceId).collect(Collectors.toList()));
Page<VolunteerDto> filterListDto = remoteVolunteerService.getFilterListDto(conditionAndPageInfo);
filterListDto.forEach(v -> {
tasks.forEach(t ->{
if(!ObjectUtils.isEmpty(v.getProcessInstanceId()) && v.getProcessInstanceId().equals(t.getProcessInstanceId())){
v.setIsAudit(true);
v.setTaskId(t.getId());
}
});
});
return Result.<Page<VolunteerDto>>builder().data(filterListDto).build();
}
@GetMapping("/startVolunteerAccountApplyAudit/{volunteerId}")
@Operation(summary = "启动志愿者账号申请审核")
public Result<ProcessInstance> startVolunteerAccountApplyAudit(@PathVariable("volunteerId") String volunteerId){
//获取志愿者信息
VolunteerDto volunteerDto = remoteVolunteerService.getByIdDto(volunteerId);
if(ObjectUtils.isEmpty(volunteerDto)){
throw new BizException("志愿者信息不存在");
}
//设置流程启动信息(创建人业务数据id流程Key)
HashMap<String, Object> variables = new HashMap<>();
variables.put("draft", volunteerDto.getCreateBy());
BaseWorkflowDto baseWorkflowDto = BaseWorkflowDto.builder().variables(variables).businessKey(volunteerDto.getId()).processDefineKey(ProcessConstant.VOLUNTEER_ACCOUNT_APPLY_AUDIT).build();
ProcessInstance processInstance = workflowServiceRemote.startWorkflow(baseWorkflowDto);
//获取起草人任务节点
List<Task> tasks = workflowServiceRemote.getTasks(TaskCondition.builder().businessKey(volunteerDto.getId()).assignee(volunteerDto.getCreateBy()).build());
//完成起草人任务节点
workflowServiceRemote.completeTask(TaskDto.builder().taskId(tasks.get(0).getId()).build());
//更新审核状态
volunteerDto.setAuditStatus(VolunteerAuditStatus.AUDIT);
volunteerDto.setProcessInstanceId(processInstance.getId());
volunteerDto.setProcessDefineKey(processInstance.getProcessDefinitionKey());
remoteVolunteerService.updateDto(volunteerDto);
return Result.<ProcessInstance>builder().data(processInstance).build();
}
@GetMapping("/getProcess/{processId}")
@Operation(summary = "获取流程图")
public ResponseEntity<Resource> getProcess(@PathVariable("processId") String processId) {
ResponseEntity<Resource> process = workflowServiceRemote.getProcess(processId);
return process;
}
@PostMapping("/getHistories")
@Operation(summary = "获取历史记录")
public Result<List<HistoricTaskDTO>> getHistoryTask(@RequestBody HistoryTaskCondition historyTaskCondition){
return Result.<List<HistoricTaskDTO>>builder().data(workflowServiceRemote.getHistoryTask(historyTaskCondition)).build();
}
@Operation(summary = "完成任务")
@PostMapping("/completeTask")
public Result<Boolean> completeTask(@RequestBody TaskDto taskDto){
Boolean completeTask = workflowServiceRemote.completeTask(taskDto);
//获取业务数据
VolunteerDto volunteerDto = remoteVolunteerService.getByIdDto(taskDto.getBusinessKey());
//获取该业务数据的任务信息
List<HistoricTaskDTO> historyTask = workflowServiceRemote.getHistoryTask(HistoryTaskCondition.builder().businessKey(volunteerDto.getId()).build());
if(!historyTask.isEmpty()){
//查看审核是否被退回,退回则修改业务数据状态
if(historyTask.get(historyTask.size() - 1).getName().equals(historyTask.get(0).getName())){
//审核被退回
volunteerDto.setAuditStatus(VolunteerAuditStatus.AUDIT_BACK);
}else{
volunteerDto.setAuditStatus(VolunteerAuditStatus.AUDIT);
}
remoteVolunteerService.updateDto(volunteerDto);
}
return Result.<Boolean>builder().data(completeTask).build();
}
@GetMapping("/{id}")
@Operation(summary = "根据志愿者id获取志愿者信息")
public Result<VolunteerDto> getVolunteerById(@PathVariable("id")String id){
return Result.<VolunteerDto>builder().data(remoteVolunteerService.getByIdDto(id)).build();
}
}

@ -0,0 +1,86 @@
package com.intelligentHealthCare.api.controller.system;
import com.intelligentHealthCare.annotation.NoAuth;
import com.intelligentHealthCare.dto.MenuDto;
import com.intelligentHealthCare.entity.Menu;
import com.intelligentHealthCare.enums.ResultCodeEnum;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.remote.MenuServiceRemote;
import com.intelligentHealthCare.security.SecurityUser;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author yang
* @version 1.0
* @date Created in 2023/9/27 21:58
*/
@RestController
@Api(tags = "菜单管理")
@RequestMapping("/${app.baseService}/menu")
public class MenuController {
@Autowired
private MenuServiceRemote menuServiceRemote;
@Operation(summary = "根据账号id获取菜单树")
@GetMapping("/tree/getMenuTreeByAccountId")
@NoAuth
public Result<List<MenuDto>> getMenuTreeByAccountId(){
SecurityUser securityUser = (SecurityUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return Result.<List<MenuDto>>builder().data(menuServiceRemote.getMenuTreeByAccountId(securityUser.getAccount().getId())).status(ResultCodeEnum.SUCCESS).build();
}
@Operation(summary = "获取菜单树")
@GetMapping("/tree/getMenuTree")
public Result<List<MenuDto>> getMenuTree(){
return Result.<List<MenuDto>>builder().data(menuServiceRemote.getMenuTree()).status(ResultCodeEnum.SUCCESS).build();
}
@Operation(summary = "添加菜单")
@PostMapping
public Result<com.intelligentHealthCare.entity.Menu> add(@RequestBody Menu menu){
return Result.<Menu>builder().data(menuServiceRemote.save(menu)).status(ResultCodeEnum.SUCCESS).build();
}
@Operation(summary = "删除菜单")
@DeleteMapping("/{id}")
public Result<Boolean> delete(@PathVariable("id")String id){
return Result.<Boolean>builder().data(menuServiceRemote.delete(id)).status(ResultCodeEnum.SUCCESS).build();
}
@Operation(summary = "修改菜单")
@PutMapping
public Result<Menu> update(@RequestBody Menu menu){
return Result.<Menu>builder().data(menuServiceRemote.update(menu)).status(ResultCodeEnum.SUCCESS).build();
}
@Operation(summary = "获取单个菜单")
@GetMapping("/{id}")
public Result<Menu> get(@PathVariable("id") String id){
return Result.<Menu>builder().data(menuServiceRemote.getById(id)).status(ResultCodeEnum.SUCCESS).build();
}
@GetMapping("/getParentMenu")
@Operation(summary = "获取父级菜单")
public Result<List<Menu>> getParentMenu(){
return Result.<List<Menu>>builder().data(menuServiceRemote.getParentMenu()).status(ResultCodeEnum.SUCCESS).build();
}
@GetMapping("/existSameMenuTitle/{menuTitle}")
@Operation(summary = "检查是否存在相同的菜单名称")
public Result<Boolean> existSameMenuTitle(@PathVariable("menuTitle")String menuTitle){
return Result.<Boolean>builder().data(menuServiceRemote.existSameMenuTitle(menuTitle)).status(ResultCodeEnum.SUCCESS).build();
}
@GetMapping("/existSameMenuPath")
@Operation(summary = "检查是否存在相同的菜单路径")
public Result<Boolean> existSameMenuPath(@RequestParam("menuPath")String menuPath){
return Result.<Boolean>builder().data(menuServiceRemote.existSameMenuPath(menuPath)).status(ResultCodeEnum.SUCCESS).build();
}
}

@ -0,0 +1,92 @@
package com.intelligentHealthCare.api.controller.system;
import com.intelligentHealthCare.annotation.NoAuth;
import com.intelligentHealthCare.condition.KeywordCondition;
import com.intelligentHealthCare.controller.ApiAbstractSimpleController;
import com.intelligentHealthCare.dto.ApiDto;
import com.intelligentHealthCare.entity.Menu;
import com.intelligentHealthCare.entity.Role;
import com.intelligentHealthCare.enums.ResultCodeEnum;
import com.intelligentHealthCare.pojo.ConditionAndPageInfo;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.remote.ApiServiceRemote;
import com.intelligentHealthCare.remote.MenuServiceRemote;
import com.intelligentHealthCare.remote.RoleServiceRemote;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.Cacheable;
import java.util.List;
/**
* @author yang
* @version 1.0
* @date Created in 2023/10/3 16:54
*/
@RestController
@Api(tags = "角色管理")
@RequestMapping("/${app.baseService}/role")
public class RoleController{
@Autowired
private RoleServiceRemote roleServiceRemote;
@Autowired
private ApiServiceRemote apiServiceRemote;
@Autowired
private MenuServiceRemote menuServiceRemote;
@PostMapping("/page")
@Operation(summary = "获取角色信息分页")
public Result<Page<Role>> page(@RequestBody ConditionAndPageInfo<KeywordCondition> conditionAndPageInfo){
return Result.<Page<Role>>builder().data(roleServiceRemote.getFilterList(conditionAndPageInfo)).status(ResultCodeEnum.SUCCESS).build();
}
@PostMapping
@Operation(summary = "新增角色")
public Result<Role> add(@RequestBody Role role){
return Result.<Role>builder().data(roleServiceRemote.save(role)).status(ResultCodeEnum.SUCCESS).build();
}
@DeleteMapping("/{id}")
@Operation(summary = "删除角色")
public Result<Boolean> remove(@PathVariable("id") String id){
return Result.<Boolean>builder().data(roleServiceRemote.delete(id)).status(ResultCodeEnum.SUCCESS).build();
}
@PutMapping
@Operation(summary = "修改角色")
public Result<Role> update(@RequestBody Role role){
return Result.<Role>builder().data(roleServiceRemote.update(role)).status(ResultCodeEnum.SUCCESS).build();
}
@GetMapping("/{id}")
@Operation(summary = "根据id获取实体")
public Result<Role> getById(@PathVariable("id")String id){
return Result.<Role>builder().data(roleServiceRemote.getById(id)).status(ResultCodeEnum.SUCCESS).build();
}
@GetMapping("/existSameName/{roleName}")
@Operation(summary = "检查是否存在相同名称的角色")
public Result<Boolean> existSameName(@PathVariable("roleName")String roleName){
return Result.<Boolean>builder().data(roleServiceRemote.existSameName(roleName)).status(ResultCodeEnum.SUCCESS).build();
}
@GetMapping("/getAllAndAssigned/{id}")
@Operation(summary = "获取所有接口信息并携带已分配的接口")
public Result<List<ApiDto>> getAllAndAssigned(@PathVariable("id")String id){
return Result.<List<ApiDto>>builder().data(apiServiceRemote.getAllAndAssigned(id)).status(ResultCodeEnum.SUCCESS).build();
}
@PostMapping("/updateRoleApiPermission/{roleId}")
@Operation(summary = "更改角色和api的关系")
public Result<Boolean> updateRoleApiPermission(@RequestBody List<ApiDto> apiDtoList, @PathVariable("roleId")String roleId){
return Result.<Boolean>builder().data(apiServiceRemote.updateRoleApiPermission(apiDtoList, roleId)).status(ResultCodeEnum.SUCCESS).build();
}
}

@ -0,0 +1,40 @@
package com.intelligentHealthCare.api.controller.system;
import com.intelligentHealthCare.condition.SystemCondition;
import com.intelligentHealthCare.dto.SystemLogDto;
import com.intelligentHealthCare.enums.ResultCodeEnum;
import com.intelligentHealthCare.pojo.ConditionAndPageInfo;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.remote.SystemLogServiceRemote;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
/**
* @author yang
* @version 1.0
* @date Created in 2023/10/3 16:54
*/
@RestController
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
@Api(tags = "系统日志")
@RequestMapping("/${app.baseService}/systemLog")
public class SystemLogController {
private final SystemLogServiceRemote systemLogServiceRemote;
@PostMapping("/page")
@Operation(summary = "获取系统日志分页")
public Result<Page<SystemLogDto>> page(@RequestBody ConditionAndPageInfo<SystemCondition> conditionAndPageInfo) {
return Result.<Page<SystemLogDto>>builder().data(systemLogServiceRemote.getFilterListDto(conditionAndPageInfo)).status(ResultCodeEnum.SUCCESS).build();
}
@DeleteMapping("/deleteBatch")
@Operation(summary = "删除截至到某个时间段的日志")
public Result<Boolean> deleteBatch(@RequestBody SystemLogDto systemLogDto){
return Result.<Boolean>builder().data(systemLogServiceRemote.deleteBatch(systemLogDto)).build();
}
}

@ -0,0 +1,37 @@
package com.intelligentHealthCare.api.controller.workflow.modelManage;
import com.intelligentHealthCare.condition.KeywordCondition;
import com.intelligentHealthCare.pojo.ConditionAndPageInfo;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.remote.workflow.ModelManageServiceRemote;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.activiti.api.process.model.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
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;
/**
* @author yang
* @version 1.0
* @date Created in 2024/3/5 09:33
* @description
*/
@RestController
@Api(tags = "已部署模型管理")
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
@RequestMapping("/${app.baseService}/deploymentModel")
public class DeploymentModel {
private final ModelManageServiceRemote modelManageServiceRemote;
@PostMapping("/getDeploymentModelPage")
@Operation(summary = "获取已部署的模型分页")
public Result<Page<ProcessDefinition>> getDeploymentModelPage(@RequestBody ConditionAndPageInfo<KeywordCondition> conditionAndPageInfo){
return Result.<Page<ProcessDefinition>>builder().data(modelManageServiceRemote.getDeploymentModelPage(conditionAndPageInfo)).build();
}
}

@ -0,0 +1,49 @@
package com.intelligentHealthCare.api.controller.workflow.modelManage;
import com.intelligentHealthCare.condition.StaffCondition;
import com.intelligentHealthCare.dto.StaffDto;
import com.intelligentHealthCare.dto.workflow.ModelDto;
import com.intelligentHealthCare.pojo.ConditionAndPageInfo;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.remote.StaffServiceRemote;
import com.intelligentHealthCare.remote.workflow.ModelManageServiceRemote;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
/**
* @author yang
* @version 1.0
* @date Created in 2024/2/28 14:19
* @description
*/
@RestController
@Api(tags = "模型创建")
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
@RequestMapping("/${app.baseService}/modelCreate")
public class ModelCreate {
private final StaffServiceRemote staffServiceRemote;
private final ModelManageServiceRemote modelManageServiceRemote;
@PostMapping("/getStaffPage")
@Operation(summary = "获取人员信息分页")
public Result<Page<StaffDto>> getStaffDtoPage(@RequestBody ConditionAndPageInfo<StaffCondition> conditionAndPageInfo){
return Result.<Page<StaffDto>>builder().data(staffServiceRemote.getStaffDtoPage(conditionAndPageInfo)).build();
}
@PostMapping("/updateModel")
@Operation(summary = "更新模型")
public Result<ModelDto> updateModel(@RequestBody ModelDto modelDto){
return Result.<ModelDto>builder().data(modelManageServiceRemote.updateModel(modelDto)).build();
}
@GetMapping("/{id}")
@Operation(summary = "根据模型id获取流程")
public Result<String> getProcessByModelId(@PathVariable("id") String id){
return Result.<String>builder().data(modelManageServiceRemote.getProcessByModelId(id)).build();
}
}

@ -0,0 +1,81 @@
package com.intelligentHealthCare.api.controller.workflow.modelManage;
import com.intelligentHealthCare.condition.KeywordCondition;
import com.intelligentHealthCare.condition.workflow.ModelCondition;
import com.intelligentHealthCare.pojo.ConditionAndPageInfo;
import com.intelligentHealthCare.pojo.Result;
import com.intelligentHealthCare.remote.workflow.ModelManageServiceRemote;
import com.intelligentHealthCare.utils.SortUtil;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.activiti.engine.impl.persistence.entity.DeploymentEntityImpl;
import org.activiti.engine.impl.persistence.entity.ModelEntityImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.activiti.engine.repository.Model;
/**
* @author yang
* @version 1.0
* @date Created in 2024/2/29 21:49
* @description
*/
@RestController
@Api(tags = "模型定义")
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
@RequestMapping("/${app.baseService}/modelDefine")
public class ModelDefine {
private final ModelManageServiceRemote modelManageServiceRemote;
/**
*
* @param key
* @param name
* @param description
*/
@GetMapping("/modelCreate/{key}/{name}/{description}")
@Operation(summary = "创建模型")
public Result modelCreate(@PathVariable("key")String key, @PathVariable("name")String name, @PathVariable("description")String description){
modelManageServiceRemote.modelCreate(key, name, description);
return Result.builder().build();
}
/**
*
* @param conditionAndPageInfo
* @return
*/
@PostMapping("/page")
@Operation(summary = "分页获取所有的模型")
public Result<Page<ModelEntityImpl>> modelPage(@RequestBody ConditionAndPageInfo<ModelCondition> conditionAndPageInfo){
return Result.<Page<ModelEntityImpl>>builder().data(modelManageServiceRemote.modelPage(conditionAndPageInfo)).build();
}
/**
* id
* @param modelId
* @return
*/
@DeleteMapping("/deleteModelById/{modelId}")
@Operation(summary = "根据模型id删除模型")
public Result<Boolean> deleteModelById(@PathVariable("modelId")String modelId){
return Result.<Boolean>builder().data(modelManageServiceRemote.deleteModelById(modelId)).build();
}
/**
* id
* @param modelId
*/
@GetMapping("/deploymentModel/{modelId}")
@Operation(summary = "根据模型id部署模型")
public Result deploymentModel(@PathVariable("modelId")String modelId){
modelManageServiceRemote.deploymentModel(modelId);
return Result.builder().build();
}
}

@ -0,0 +1,10 @@
package com.intelligentHealthCare.api.controller.workflow.modelManage;
/**
* @author yang
* @version 1.0
* @date Created in 2024/2/29 21:43
* @description
*/
public class Workflow {
}

@ -0,0 +1,42 @@
package com.intelligentHealthCare.config;
import com.intelligentHealthCare.utils.JwtUtil;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* @author yang
* @version 1.0
* @date Created in 2023/11/1 15:57
*/
@Data
@ConfigurationProperties(prefix = "app")
@Component
public class CommonAppProperty {
/**
*
*/
private String baseService;
/**
*
*/
@Value("${app.security.JWT-KEY}")
private String JWT_KEY;
/**
*
*/
@Value("${app.security.JWT-TTL}")
private Long JWT_TTL;
@PostConstruct
public void initJwtUtil(){
JwtUtil.JWT_KEY = JWT_KEY;
JwtUtil.JWT_TTL = JWT_TTL;
}
}

@ -0,0 +1,44 @@
package com.intelligentHealthCare.config;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import com.google.code.kaptcha.util.Config;
import java.util.Properties;
//kaptcha配置类
@Component
public class KaptchaConfig {
@Bean
public DefaultKaptcha getDefaultKaptcha() {
com.google.code.kaptcha.impl.DefaultKaptcha defaultKaptcha = new com.google.code.kaptcha.impl.DefaultKaptcha();
Properties properties = new Properties();
// 图片边框
properties.setProperty("kaptcha.border", "yes");
// 边框颜色
properties.setProperty("kaptcha.border.color", "black");
// 字体颜色
properties.setProperty("kaptcha.textproducer.font.color", "black");
// 图片宽
properties.setProperty("kaptcha.image.width", "135");
// 图片高
properties.setProperty("kaptcha.image.height", "32");
//使用哪些字符生成验证码
properties.setProperty("kaptcha.textproducer.char.string", "ACEHKTW247");
// 字体大小
properties.setProperty("kaptcha.textproducer.font.size", "30");
// session key
properties.setProperty("kaptcha.session.key", "code");
// 验证码长度
properties.setProperty("kaptcha.textproducer.char.length", "4");
// 字体
properties.setProperty("kaptcha.textproducer.font.names", "Arial");
//干扰线颜色
properties.setProperty("kaptcha.noise.color", "black");
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}

@ -0,0 +1,90 @@
package com.intelligentHealthCare.config;
import com.intelligentHealthCare.exception.AccessDeniedHandlerException;
import com.intelligentHealthCare.exception.AuthenticationEntryPointException;
import com.intelligentHealthCare.exception.AuthenticationFailureException;
import com.intelligentHealthCare.filter.JwtAuthenticationTokenFilter;
import com.intelligentHealthCare.security.UrlMethodAccessDecision;
import com.intelligentHealthCare.security.UrlMethodAccessDecisionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class SpringSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Autowired
private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
@Autowired
private AccessDeniedHandlerException accessDeniedHandlerException;
@Autowired
private AuthenticationEntryPointException authenticationEntryPointException;
@Autowired
private AuthenticationFailureException authenticationFailureException;
@Autowired
private UrlMethodAccessDecisionManager urlMethodAccessDecisionManager;
/**
* HTTP seguridad
*
* @param http HttpSecurity
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// 禁用CSRF保护
.csrf().disable()
// 设置会话管理策略为无状态
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
// 配置请求授权
.authorizeRequests()
// 设置访问决策管理器
.accessDecisionManager(urlMethodAccessDecisionManager)
// 所有请求都需要认证
.anyRequest().authenticated();
// 在过滤器链中添加JWT认证过滤器
http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
// 配置异常处理,包括访问拒绝和认证入口点
http.exceptionHandling().accessDeniedHandler(accessDeniedHandlerException).authenticationEntryPoint(authenticationEntryPointException);
// 配置表单登录失败处理器
http.formLogin().failureHandler(authenticationFailureException);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}

@ -0,0 +1,37 @@
package com.intelligentHealthCare.exception;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.intelligentHealthCare.enums.ResultCodeEnum;
import com.intelligentHealthCare.pojo.Result;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author yang
* @version 1.0
* @date Created in 2023/9/28 21:07
*/
@Component
public class AccessDeniedHandlerException implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
Result<Object> result = Result.builder().data(e.getMessage()).status(ResultCodeEnum.NoPermission).build();
// 设置响应的内容类型为JSON
httpServletResponse.setContentType("application/json");
httpServletResponse.setCharacterEncoding("UTF-8");
// 将result对象转换为JSON字符串
String jsonResult = new ObjectMapper().writeValueAsString(result);
// 将JSON字符串写入响应输出流
PrintWriter writer = httpServletResponse.getWriter();
writer.write(jsonResult);
writer.flush();
}
}

@ -0,0 +1,36 @@
package com.intelligentHealthCare.exception;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.intelligentHealthCare.enums.ResultCodeEnum;
import com.intelligentHealthCare.pojo.Result;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author yang
* @version 1.0
* @date Created in 2023/9/28 21:16
*/
@Component
public class AuthenticationEntryPointException implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
Result<Object> result = Result.builder().data("账号过期,请重新登录").status(ResultCodeEnum.Unauth).build();
// 设置响应的内容类型为JSON
httpServletResponse.setContentType("application/json");
httpServletResponse.setCharacterEncoding("UTF-8");
// 将result对象转换为JSON字符串
String jsonResult = new ObjectMapper().writeValueAsString(result);
// 将JSON字符串写入响应输出流
PrintWriter writer = httpServletResponse.getWriter();
writer.write(jsonResult);
writer.flush();
}
}

@ -0,0 +1,23 @@
package com.intelligentHealthCare.exception;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author yang
* @version 1.0
* @date Created in 2023/9/28 16:41
*/
@Component
public class AuthenticationFailureException implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
throw new SystemException("认证异常");
}
}

@ -0,0 +1,18 @@
package com.intelligentHealthCare.exception;
import org.springframework.security.core.AuthenticationException;
/**
* @author yang
* @version 1.0
* @date Created in 2023/9/29 15:09
*/
public class CustomAuthenticationException extends AuthenticationException {
public CustomAuthenticationException(String msg, Throwable t) {
super(msg, t);
}
public CustomAuthenticationException(String msg) {
super(msg);
}
}

@ -0,0 +1,110 @@
package com.intelligentHealthCare.filter;
import com.intelligentHealthCare.dto.RequestModuleDto;
import com.intelligentHealthCare.entity.Api;
import com.intelligentHealthCare.exception.AuthenticationEntryPointException;
import com.intelligentHealthCare.exception.CustomAuthenticationException;
import com.intelligentHealthCare.remote.ApiServiceRemote;
import com.intelligentHealthCare.security.SecurityUser;
import com.intelligentHealthCare.utils.JwtUtil;
import com.intelligentHealthCare.utils.RedisCache;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.server.PathContainer;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPatternParser;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@Component
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
private final RedisCache redisCache;
private final ApiServiceRemote apiServiceRemote;
public static RequestModuleDto requestModuleDto;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
packageRequestModule(request);
//获取token
Cookie[] cookies = request.getCookies();
String token = "";
if (cookies != null) {
for (Cookie cookie : cookies) {
String name = cookie.getName();
String value = cookie.getValue();
// 在这里对获取到的Cookie进行处理
if(name.equals("token")){
token = value;
break;
}
}
}
if (!StringUtils.hasText(token)) {
//放行
filterChain.doFilter(request, response);
return;
}
//解析token
String userid;
Claims claims = JwtUtil.parseJWT(token);
// 检查令牌是否过期
userid = claims.getSubject();
//从redis中获取用户信息
SecurityUser securityUser = (SecurityUser) redisCache.getCacheObject(userid);
//存入SecurityContextHolder
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(securityUser, null, securityUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
//放行
filterChain.doFilter(request, response);
}
/**
*
* @param httpServletRequest
*/
public void packageRequestModule(HttpServletRequest httpServletRequest){
requestModuleDto = new RequestModuleDto();
requestModuleDto.setUrl(httpServletRequest.getRequestURI());
requestModuleDto.setMethod(httpServletRequest.getMethod());
List<Api> apis = apiServiceRemote.getAll();
PathPatternParser pathPatternParser = new PathPatternParser();
apis.forEach(api -> {
PathPattern pathPattern = pathPatternParser.parse(api.getRest());
// 使用matchingCondition确保精确匹配
PathPattern.PathMatchInfo pathMatchInfo = pathPattern.matchAndExtract(PathContainer.parsePath(httpServletRequest.getRequestURI()));
if (pathMatchInfo != null && pathMatchInfo.getUriVariables().isEmpty() && api.getMethod().equals(httpServletRequest.getMethod())) {
requestModuleDto.setModule(api.getName().split("-")[0]);
requestModuleDto.setOperation(api.getName().split("-")[1]);
requestModuleDto.setFullOperation(api.getName());
}
});
}
}

@ -0,0 +1,23 @@
package com.intelligentHealthCare.interceptor;
import com.intelligentHealthCare.security.SecurityUser;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
@Configuration
public class AccountHeaderInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
SecurityUser securityUser = null;
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication != null && authentication.getPrincipal() instanceof SecurityUser){
securityUser = (SecurityUser) authentication.getPrincipal();
}
if(securityUser != null){
template.header("userId", securityUser.getAccount().getId());
}
}
}

@ -0,0 +1,31 @@
package com.intelligentHealthCare.security;
import com.intelligentHealthCare.entity.Account;
import com.intelligentHealthCare.remote.AccountServiceRemote;
import com.intelligentHealthCare.remote.RoleApiPermissionServiceRemote;
import com.intelligentHealthCare.repository.AccountRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
public class SecurityUserDetailService implements UserDetailsService {
private final AccountServiceRemote accountServiceRemote;
private final RoleApiPermissionServiceRemote roleApiPermissionServiceRemote;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Account byUserName = accountServiceRemote.findByUsername(username);
if(byUserName == null) {
return null;
}
//TODO 根据用户查询权限信息
return new SecurityUser(byUserName, roleApiPermissionServiceRemote.getAllByAccountId(byUserName.getId()));
}
}

@ -0,0 +1,85 @@
package com.intelligentHealthCare.security;
import com.intelligentHealthCare.dto.RequestModuleDto;
import com.intelligentHealthCare.filter.JwtAuthenticationTokenFilter;
import lombok.Getter;
import lombok.Setter;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.util.pattern.PathPatternParser;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author yang
* @version 1.0
* @date Created in 2023/9/27 15:56
*/
@Getter
@Setter
@Component
public class UrlMethodAccessDecision implements AccessDecisionVoter<Object> {
private List<String> anonymousUrls;
@Override
public boolean supports(ConfigAttribute configAttribute) {
return true;
}
@Override
public boolean supports(Class<?> aClass) {
return true;
}
@Override
public int vote(Authentication authentication, Object o, Collection<ConfigAttribute> collection) {
//获取请求模型
RequestModuleDto requestModuleDto = JwtAuthenticationTokenFilter.requestModuleDto;
FilterInvocation filterInvocation = (FilterInvocation) o;
String requestUrl = filterInvocation.getRequestUrl();
String method = filterInvocation.getHttpRequest().getMethod();
AntPathMatcher pathMatcher = new AntPathMatcher();
AtomicBoolean anonymousUrlMatch = new AtomicBoolean(false);
if(anonymousUrls != null) {
anonymousUrls.forEach(anonymousUrl -> {
if (pathMatcher.match(anonymousUrl, requestUrl)) {
anonymousUrlMatch.set(true);
}
});
}
if(anonymousUrlMatch.get()){
return ACCESS_GRANTED;
}
if(authentication.getPrincipal().equals("anonymousUser")){
throw new AccessDeniedException("没有 [" + requestModuleDto.getFullOperation() + "] 权限,请联系管理员分配");
}
SecurityUser securityUser = (SecurityUser) authentication.getPrincipal();
if(securityUser.getAccount().getSystemManager()){
return ACCESS_GRANTED;
}
AtomicBoolean hasAuth = new AtomicBoolean(false);
if(securityUser.getPermissions() != null) {
securityUser.getPermissions().forEach(api -> {
if (pathMatcher.match(api.getRest(), requestUrl) && method.equals(api.getMethod())) {
hasAuth.set(true);
return;
}
});
}
if(hasAuth.get()){
return ACCESS_GRANTED;
}
throw new AccessDeniedException("没有 [" + requestModuleDto.getFullOperation() + "] 权限,请联系管理员分配");
}
}

@ -0,0 +1,40 @@
package com.intelligentHealthCare.security;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.List;
@Component
public class UrlMethodAccessDecisionManager implements AccessDecisionManager {
private final AccessDecisionVoter<Object> accessDecisionVoter;
public UrlMethodAccessDecisionManager(AccessDecisionVoter<Object> accessDecisionVoter) {
this.accessDecisionVoter = accessDecisionVoter;
}
@Override
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
int result = accessDecisionVoter.vote(authentication, object, (List<ConfigAttribute>) configAttributes);
if (result == AccessDecisionVoter.ACCESS_DENIED) {
throw new AccessDeniedException("Access is denied");
}
}
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
}

@ -0,0 +1,77 @@
package com.intelligentHealthCare.service.impl;
import com.intelligentHealthCare.entity.Account;
import com.intelligentHealthCare.exception.BizException;
import com.intelligentHealthCare.exception.LoginFailException;
import com.intelligentHealthCare.remote.AccountServiceRemote;
import com.intelligentHealthCare.security.SecurityUser;
import com.intelligentHealthCare.utils.JwtUtil;
import com.intelligentHealthCare.utils.RedisCache;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
public class AccountHandle {
@Autowired
private final AuthenticationManager authenticationManager;
@Autowired
private final RedisCache redisCache;
@Autowired
private final AccountServiceRemote accountServiceRemote;
public String login(Account account, String code, String userIp) {
Object cacheCode = redisCache.getCacheObject(userIp);
if(cacheCode == null){
throw new BizException("验证码已过期");
} else if (!cacheCode.toString().equalsIgnoreCase(code)) {
throw new BizException("验证码有误");
}
redisCache.deleteObject(userIp);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(account.getUsername(), account.getPassword());
Authentication authenticate;
try {
authenticate = authenticationManager.authenticate(authenticationToken);
}catch (DisabledException disabledException){
throw new LoginFailException("账号已被停用");
}catch (BadCredentialsException e){
throw new LoginFailException("密码错误");
}catch (AuthenticationException e){
log.error("认证错误", e);
throw new LoginFailException("账号不存在");
}
SecurityUser loginAccount = (SecurityUser) authenticate.getPrincipal();
String jwt = JwtUtil.createJWT(loginAccount.getAccount().getId());
redisCache.setCacheObject(loginAccount.getAccount().getId(), loginAccount, 7, TimeUnit.DAYS);
return jwt;
}
public Boolean logout() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
SecurityUser loginAccount = (SecurityUser) authentication.getPrincipal();
return redisCache.deleteObject(loginAccount.getAccount().getId());
}
public Account register(Account account) {
account.setPassword(new BCryptPasswordEncoder().encode(account.getPassword()));
return accountServiceRemote.register(account);
}
}

@ -0,0 +1,79 @@
spring:
devtools:
restart:
enabled: true #设置开启热部署
additional-paths: src/main/java #重启目录
servlet:
multipart:
location: D:\intelligentHealthCare\resources\temp
max-file-size: 200MB
max-request-size: 200MB
datasource:
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/intelligentHealthCare?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
jpa:
properties:
hibernate:
format_sql: true
jdbc:
time_zone: Asia/Shanghai
hbm2ddl:
auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
jdbc:
time_zone: Asia/Shanghai
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
locale: zh_CN
default-property-inclusion: non_null
serialization:
write_dates_as_timestamps: false
profiles:
active: local
mail:
#配置smtp服务主机地址
# qq邮箱为smtp.qq.com 端口号465或587
# sina smtp.sina.cn
# aliyun smtp.aliyun.com
# 163 smtp.163.com 端口号465或994
host: smtp.qq.com
#配置密码,注意不是真正的密码,而是刚刚申请到的授权码
username: 1545558448@qq.com
password: akruwpztoznnigdf
#端口号465或587
port: 587
#默认的邮件编码为UTF-8
default-encoding: UTF-8
#其他参数
properties:
mail:
#配置SSL 加密工厂
smtp:
ssl:
#本地测试先放开ssl
enable: false
required: false
#开启debug模式这样邮件发送过程的日志会在控制台打印出来方便排查错误
debug: true
app:
baseService: api
resources-location: D:\intelligentHealthCare\resources\
default-sub-location: resources
remoteService: service
workflowService: workflow
clientService: clientService
security:
JWT-KEY: "INTELLIGENT" #认证令牌
JWT-TTL: 6048000000 #过期时间七天
logging:
level:
com.intelligentHealthCare: debug
platform:
name: "智能康养管理平台"
email: "1545558448@qq.com"
website: "127.0.0.1:5173"

@ -0,0 +1,37 @@
spring:
application:
name: api
cloud:
nacos:
config:
server-addr: localhost:8848
biz-service:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
server:
port: 8003
feign:
httpclient:
enabled: true #开启feign对httpclient的支持
max-connections: 200 #最大连接数量
max-connections-per-route: 50 #每个路由最大连接数量
# Feign org.springframework.data.domain.Page编码和解码
# Feign org.springframework.data.domain.Sort编码解码
connection-timeout: 30000 #连接超时时间
client:
config:
default:
connect-timeout: 30000 #链接超时
read-timeout: 60000 #超时
request-interceptors:
- com.intelligentHealthCare.interceptor.AccountHeaderInterceptor
autoconfiguration:
jackson:
# 如果为true则将提供PageJacksonModule、SortJacksonModule用jackson对Page进行编码和解码操作默认false
enabled: true
sentinel:
enabled: true #开启流量整合

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>api</id>
<classpath>
<dir name="D:/workspace/HealthManagerSystem/IntelligentHealthCare/api/target/classes">
</dir>
</classpath>
</application>
Loading…
Cancel
Save