diff --git a/api/.gitignore b/api/.gitignore
new file mode 100644
index 0000000..5eb155f
--- /dev/null
+++ b/api/.gitignore
@@ -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
\ No newline at end of file
diff --git a/api/pom.xml b/api/pom.xml
new file mode 100644
index 0000000..59b5ef2
--- /dev/null
+++ b/api/pom.xml
@@ -0,0 +1,89 @@
+
+
+ 4.0.0
+
+ com.intelligentHealthCare
+ IntelligentHealthCare
+ 1.0-SNAPSHOT
+
+
+ com.intelligentHealthCare
+ api
+ jar
+
+
+ 8
+ 8
+ UTF-8
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+ true
+
+
+
+
+
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-discovery
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-config
+
+
+
+ com.intelligentHealthCare
+ feign-api
+ 1.0-SNAPSHOT
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-sentinel
+
+
+
+
+ com.github.penggle
+ kaptcha
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ com.intelligentHealthCare.ApiApplication
+ ZIP
+
+
+
+
+
+ repackage
+
+
+
+
+
+
+
diff --git a/api/src/main/java/com/intelligentHealthCare/ApiApplication.java b/api/src/main/java/com/intelligentHealthCare/ApiApplication.java
new file mode 100644
index 0000000..af6a09d
--- /dev/null
+++ b/api/src/main/java/com/intelligentHealthCare/ApiApplication.java
@@ -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 resultApi = apiServiceRemote.getAll();
+ LinkedList apis = new LinkedList<>();
+ LinkedList 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);
+ }
+ }
+}
diff --git a/api/src/main/java/com/intelligentHealthCare/annotation/NoAuth.java b/api/src/main/java/com/intelligentHealthCare/annotation/NoAuth.java
new file mode 100644
index 0000000..12a4932
--- /dev/null
+++ b/api/src/main/java/com/intelligentHealthCare/annotation/NoAuth.java
@@ -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 {
+}
diff --git a/api/src/main/java/com/intelligentHealthCare/aop/SystemLogAop.java b/api/src/main/java/com/intelligentHealthCare/aop/SystemLogAop.java
new file mode 100644
index 0000000..8a87c39
--- /dev/null
+++ b/api/src/main/java/com/intelligentHealthCare/aop/SystemLogAop.java
@@ -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;
+ }
+
+}
diff --git a/api/src/main/java/com/intelligentHealthCare/api/controller/AccountController.java b/api/src/main/java/com/intelligentHealthCare/api/controller/AccountController.java
new file mode 100644
index 0000000..46b42a8
--- /dev/null
+++ b/api/src/main/java/com/intelligentHealthCare/api/controller/AccountController.java
@@ -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 register(@RequestBody Account account){
+ return Result.builder().data(accountHandle.register(account)).build();
+ }
+
+
+ @PostMapping("/login")
+ @Operation(summary = "登录")
+ @NoAuth
+ public Result login(@RequestBody AccountVo accountVo, HttpServletRequest httpServletRequest){
+ Account account = new Account();
+ BeanUtils.copyProperties(accountVo, account);
+ return Result.builder().data(accountHandle.login(account, accountVo.getCode(), httpServletRequest.getRemoteAddr())).status(ResultCodeEnum.SUCCESS).build();
+ }
+
+ @PostMapping("/logout")
+ @Operation(summary = "退出登录")
+ @NoAuth
+ public Result logout(){
+ return Result.builder().data(accountHandle.logout()).status(ResultCodeEnum.SUCCESS).build();
+ }
+
+ @GetMapping("/getAccountInfo")
+ @Operation(summary = "获取当前账号信息")
+ @NoAuth
+ public Result getAccountInfo() {
+ SecurityUser securityUser = (SecurityUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+ AccountDto accountDto = new AccountDto();
+ BeanUtils.copyProperties(securityUser.getAccount(), accountDto);
+ return Result.builder().data(accountDto).status(ResultCodeEnum.SUCCESS).build();
+ }
+
+}
diff --git a/api/src/main/java/com/intelligentHealthCare/api/controller/CommonStaticFileControllerTest.java b/api/src/main/java/com/intelligentHealthCare/api/controller/CommonStaticFileControllerTest.java
new file mode 100644
index 0000000..abc612c
--- /dev/null
+++ b/api/src/main/java/com/intelligentHealthCare/api/controller/CommonStaticFileControllerTest.java
@@ -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 save(@RequestBody CommonStaticFile commonStaticFile){
+ return Result.builder().data(commonStaticFileRemoteService.save(commonStaticFile)).build();
+ }
+
+ @DeleteMapping("/{id}")
+ @Operation(summary = "删除实体")
+ public Result delete(@PathVariable("id") String id){
+ return Result.builder().data(commonStaticFileRemoteService.delete(id)).build();
+ }
+
+ @GetMapping("/{id}")
+ @Operation(summary = "查询实体根据id")
+ public Result getById(@PathVariable("id") String id){
+ return Result.builder().data(commonStaticFileRemoteService.getById(id)).build();
+ }
+
+ @GetMapping("/loadStaticFile/**")
+ @Operation(summary = "下载静态资源文件")
+ public ResponseEntity 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 saveStaticFile(@NotNull(message = "文件不能为空")MultipartFile file){
+ return Result.builder().data(commonStaticFileRemoteService.saveStaticFile(file)).build();
+ }
+}
+
diff --git a/api/src/main/java/com/intelligentHealthCare/api/controller/KaptchaController.java b/api/src/main/java/com/intelligentHealthCare/api/controller/KaptchaController.java
new file mode 100644
index 0000000..a023e4d
--- /dev/null
+++ b/api/src/main/java/com/intelligentHealthCare/api/controller/KaptchaController.java
@@ -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();
+ }
+
+}
diff --git a/api/src/main/java/com/intelligentHealthCare/api/controller/client/ArticleController.java b/api/src/main/java/com/intelligentHealthCare/api/controller/client/ArticleController.java
new file mode 100644
index 0000000..584f5ec
--- /dev/null
+++ b/api/src/main/java/com/intelligentHealthCare/api/controller/client/ArticleController.java
@@ -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 save(@RequestBody Article article) {
+ return Result.builder().data(articleServiceRemote.save(article)).build();
+ }
+
+ @DeleteMapping("/{id}")
+ @Operation(summary = "删除实体")
+ public Result delete(@PathVariable("id") String id) {
+ return Result.builder().data(articleServiceRemote.delete(id)).build();
+ }
+
+ @GetMapping("/{id}")
+ @Operation(summary = "查询实体根据id")
+ public Result getById(@PathVariable("id") String id) {
+ return Result.builder().data(articleServiceRemote.getById(id)).build();
+ }
+
+ @GetMapping("/loadStaticFile/**")
+ @Operation(summary = "下载静态资源文件")
+ public ResponseEntity 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 saveStaticFile(@RequestBody @NotNull(message = "文件不能为空") MultipartFile file) {
+ return Result.builder().data(articleServiceRemote.saveStaticFile(file)).build();
+ }
+
+ @PostMapping(path = "/uploadVideo")
+ @Operation(summary = "上传视频")
+ public Result uploadVideo(@RequestBody @NotNull(message = "文件不能为空") MultipartFile file) {
+ return Result.builder().data(articleServiceRemote.saveStaticFile(file)).build();
+ }
+}
diff --git a/api/src/main/java/com/intelligentHealthCare/api/controller/organization/DepartmentController.java b/api/src/main/java/com/intelligentHealthCare/api/controller/organization/DepartmentController.java
new file mode 100644
index 0000000..9e0e812
--- /dev/null
+++ b/api/src/main/java/com/intelligentHealthCare/api/controller/organization/DepartmentController.java
@@ -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 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