feng_ting-ting 4 天之前
父节点
当前提交
1d0b8a86f8
共有 38 个文件被更改,包括 1454 次插入22 次删除
  1. 31 16
      pom.xml
  2. 38 0
      src/main/java/com/zhentao/ai/config/CommonConfiguration.java
  3. 24 0
      src/main/java/com/zhentao/ai/config/LangChain4jConfig.java
  4. 40 0
      src/main/java/com/zhentao/ai/controller/ChatController.java
  5. 26 0
      src/main/java/com/zhentao/common/CorsConfig.java
  6. 28 0
      src/main/java/com/zhentao/drug/controller/DrugCategoryController.java
  7. 79 0
      src/main/java/com/zhentao/drug/controller/DrugInfoController.java
  8. 51 0
      src/main/java/com/zhentao/drug/domain/DrugCategory.java
  9. 98 0
      src/main/java/com/zhentao/drug/domain/DrugInfo.java
  10. 36 0
      src/main/java/com/zhentao/drug/dto/DrugCategoryDto.java
  11. 83 0
      src/main/java/com/zhentao/drug/dto/DrugDto.java
  12. 12 0
      src/main/java/com/zhentao/drug/dto/param/DrugParam.java
  13. 20 0
      src/main/java/com/zhentao/drug/mapper/DrugCategoryMapper.java
  14. 20 0
      src/main/java/com/zhentao/drug/mapper/DrugInfoMapper.java
  15. 18 0
      src/main/java/com/zhentao/drug/service/DrugCategoryService.java
  16. 27 0
      src/main/java/com/zhentao/drug/service/DrugInfoService.java
  17. 76 0
      src/main/java/com/zhentao/drug/service/impl/DrugCategoryServiceImpl.java
  18. 184 0
      src/main/java/com/zhentao/drug/service/impl/DrugInfoServiceImpl.java
  19. 8 0
      src/main/java/com/zhentao/drug/utils/IdUtil.java
  20. 20 0
      src/main/java/com/zhentao/drug/utils/MyBatisPlusConfig.java
  21. 122 0
      src/main/java/com/zhentao/drug/utils/SnowflakeIdGenerator.java
  22. 26 0
      src/main/java/com/zhentao/symptoms/controller/SymptomsController.java
  23. 13 0
      src/main/java/com/zhentao/symptoms/dto/SymptomsDto.java
  24. 20 0
      src/main/java/com/zhentao/symptoms/mapper/SymptomsMapper.java
  25. 42 0
      src/main/java/com/zhentao/symptoms/pojo/Symptoms.java
  26. 18 0
      src/main/java/com/zhentao/symptoms/service/SymptomsService.java
  27. 46 0
      src/main/java/com/zhentao/symptoms/service/impl/SymptomsServiceImpl.java
  28. 32 0
      src/main/java/com/zhentao/user/controller/UserLoginController.java
  29. 1 0
      src/main/java/com/zhentao/user/domain/User.java
  30. 17 0
      src/main/java/com/zhentao/user/dto/UserLoginDto.java
  31. 7 0
      src/main/java/com/zhentao/user/service/UserService.java
  32. 51 3
      src/main/java/com/zhentao/user/service/impl/UserServiceImpl.java
  33. 47 0
      src/main/java/com/zhentao/user/vo/ResultVo.java
  34. 12 2
      src/main/resources/application.yml
  35. 19 0
      src/main/resources/mapper/DrugCategoryMapper.xml
  36. 32 0
      src/main/resources/mapper/DrugInfoMapper.xml
  37. 28 0
      src/main/resources/mapper/SymptomsMapper.xml
  38. 2 1
      src/main/resources/mapper/UserMapper.xml

+ 31 - 16
pom.xml

@@ -8,12 +8,40 @@
     <name>MedSmart</name>
     <description>MedSmart</description>
     <properties>
-        <java.version>1.8</java.version>
+        <java.version>17</java.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <spring-boot.version>2.7.6</spring-boot.version>
     </properties>
     <dependencies>
+        <dependency>
+            <groupId>dev.langchain4j</groupId>
+            <artifactId>langchain4j-open-ai</artifactId>
+            <version>1.0.0-beta3</version>
+        </dependency>
+        <dependency>
+            <groupId>dev.langchain4j</groupId>
+            <artifactId>langchain4j</artifactId>
+            <version>1.0.0-beta3</version>
+        </dependency>
+
+        <!-- Maven 依赖 -->
+        <dependency>
+            <groupId>dev.langchain4j</groupId>
+            <artifactId>langchain4j</artifactId>
+            <version>0.25.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.zaxxer</groupId>
+            <artifactId>HikariCP</artifactId>
+            <version>5.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+
         <!-- Spring Boot 基础依赖 -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
@@ -34,11 +62,6 @@
             <artifactId>mybatis-plus-boot-starter</artifactId>
             <version>3.5.3.1</version>
         </dependency>
-        <dependency>
-            <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-            <scope>runtime</scope>
-        </dependency>
 
         <!-- 工具库 -->
         <dependency>
@@ -56,14 +79,6 @@
             <artifactId>commons-codec</artifactId>
             <version>1.15</version>
         </dependency>
-
-        <!-- HTTP客户端 -->
-<!--        <dependency>-->
-<!--            <groupId>org.springframework.boot</groupId>-->
-<!--            <artifactId>spring-boot-starter-webclient</artifactId>-->
-<!--            <version>2.7.6</version>-->
-<!--        </dependency>-->
-
     </dependencies>
     <dependencyManagement>
         <dependencies>
@@ -84,8 +99,8 @@
                 <artifactId>maven-compiler-plugin</artifactId>
                 <version>3.8.1</version>
                 <configuration>
-                    <source>1.8</source>
-                    <target>1.8</target>
+                    <source>17</source>
+                    <target>17</target>
                     <encoding>UTF-8</encoding>
                 </configuration>
             </plugin>

+ 38 - 0
src/main/java/com/zhentao/ai/config/CommonConfiguration.java

@@ -0,0 +1,38 @@
+package com.zhentao.ai.config;
+
+/**
+ * @date: 2025/5/24 11:06
+ * @author: ftt
+ */
+
+import dev.langchain4j.memory.ChatMemory;
+import dev.langchain4j.memory.chat.MessageWindowChatMemory;
+import dev.langchain4j.store.memory.chat.ChatMemoryStore;
+import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class CommonConfiguration {
+
+    /**
+     * 定义一个基于消息数量限制的 ChatMemory Bean
+     */
+    @Bean
+    public ChatMemory messageWindowChatMemory(ChatMemoryStore chatMemoryStore) {
+        return MessageWindowChatMemory.builder()
+                .id("session-1") // 会话 ID
+                .maxMessages(10) // 最大消息数量
+                .chatMemoryStore(chatMemoryStore) // 持久化存储
+                .build();
+    }
+
+    /**
+     * 定义一个简单的内存存储实现
+     */
+    @Bean
+    public ChatMemoryStore inMemoryChatMemoryStore() {
+        return new InMemoryChatMemoryStore();
+    }
+}
+

+ 24 - 0
src/main/java/com/zhentao/ai/config/LangChain4jConfig.java

@@ -0,0 +1,24 @@
+package com.zhentao.ai.config;
+
+import dev.langchain4j.model.chat.ChatLanguageModel;
+import dev.langchain4j.model.openai.OpenAiChatModel;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @date: 2025/5/24 11:03
+ * @author: ftt
+ */
+
+@Configuration
+public class LangChain4jConfig {
+    @Bean
+    public ChatLanguageModel chatLanguageModel() {
+        return OpenAiChatModel.builder()
+                .baseUrl("http://langchain4j.dev/demo/openai/v1")
+                .apiKey("demo") // 替换为真实KEY时移除baseUrl
+                .modelName("gpt-4o-mini") // 最新轻量级模型
+                .build();
+    }
+}
+

+ 40 - 0
src/main/java/com/zhentao/ai/controller/ChatController.java

@@ -0,0 +1,40 @@
+package com.zhentao.ai.controller;
+
+import dev.langchain4j.data.message.AiMessage;
+import dev.langchain4j.data.message.UserMessage;
+import dev.langchain4j.memory.ChatMemory;
+import dev.langchain4j.model.chat.ChatLanguageModel;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Mono;
+
+/**
+ * @date: 2025/5/24 11:05
+ * @author: ftt
+ */
+
+@RestController
+@RequestMapping("/ai")
+public class ChatController {
+    private final ChatLanguageModel model;
+    private final ChatMemory chatMemory; // 自动记忆上下文
+
+    public ChatController(ChatLanguageModel model, ChatMemory chatMemory) {
+        this.model = model;
+        this.chatMemory = chatMemory;
+    }
+
+    @GetMapping(value = "/chat", produces = "text/plain;charset=utf-8")
+    public Mono<String> chat(@RequestParam String message) {
+        UserMessage userMsg = UserMessage.from("你叫小智,是一个人工智能\n" + message);
+        chatMemory.add(userMsg);
+
+        AiMessage aiMsg = model.chat(chatMemory.messages()).aiMessage();
+        chatMemory.add(aiMsg);
+
+        return Mono.just(aiMsg.text());
+    }
+}
+

+ 26 - 0
src/main/java/com/zhentao/common/CorsConfig.java

@@ -0,0 +1,26 @@
+package com.zhentao.common;
+
+/**
+ * @date: 2025/5/26 14:15
+ * @author: ftt
+ */
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+
+@Configuration
+public class CorsConfig {
+    @Bean
+    public CorsFilter corsFilter() {
+        CorsConfiguration config = new CorsConfiguration();
+        config.addAllowedOrigin("http://localhost:8080"); // 允许的前端域名
+        config.addAllowedMethod("*"); // 允许的HTTP方法(GET/POST等)
+        config.addAllowedHeader("*"); // 允许的请求头
+        config.setAllowCredentials(true); // 允许携带Cookie
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        source.registerCorsConfiguration("/**", config);
+        return new CorsFilter(source);
+    }
+}

+ 28 - 0
src/main/java/com/zhentao/drug/controller/DrugCategoryController.java

@@ -0,0 +1,28 @@
+package com.zhentao.drug.controller;
+
+import com.zhentao.common.Result;
+import com.zhentao.drug.dto.DrugCategoryDto;
+import com.zhentao.drug.service.DrugCategoryService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("drugCategory")
+//药物分类表
+public class DrugCategoryController {
+    @Autowired
+    DrugCategoryService drugCategoryService;
+    //查询两级分类药品
+    @RequestMapping("drugCategoryAll")
+    public Result drugCategoryAll(@RequestBody(required = false) DrugCategoryDto drugCategoryDto){
+        return drugCategoryService.drugCategoryAll(drugCategoryDto);
+    }
+    //逻辑删除
+    @RequestMapping("oneDelOrTwoDel")
+    public Result oneDelOrTwoDel(Integer categoryId){
+
+        return drugCategoryService.oneDelOrTwoDel(categoryId);
+    }
+}

+ 79 - 0
src/main/java/com/zhentao/drug/controller/DrugInfoController.java

@@ -0,0 +1,79 @@
+package com.zhentao.drug.controller;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.zhentao.common.Result;
+import com.zhentao.drug.domain.DrugInfo;
+import com.zhentao.drug.dto.param.DrugParam;
+import com.zhentao.drug.service.DrugInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+
+@RestController
+@RequestMapping("drug")
+public class DrugInfoController {
+    @Autowired
+    DrugInfoService drugInfoService;
+    //查询药品所有
+    @RequestMapping("drugAll")
+    public Result drugAll(@RequestBody DrugParam drugParam){
+        return drugInfoService.drugAll(drugParam);
+    }
+    //添加药品
+  /*  @RequestMapping("addDrug")
+    public Result addDrug(@RequestBody DrugParam drugParam){
+        return drugInfoService.addDrug(drugParam);
+    }*/
+    @PostMapping("/addDrug")
+    public Result addDrug(@RequestParam("imageFile") MultipartFile imageFile,
+                          @RequestParam("drugInfo") String drugInfoJson) {
+        try {
+            // 将JSON字符串转换为DrugInfo对象
+            DrugInfo drugInfo = new ObjectMapper().readValue(drugInfoJson, DrugInfo.class);
+            drugInfo.setImageFile(imageFile);
+
+            return drugInfoService.addDrug(drugInfo);
+        } catch (IOException e) {
+            e.printStackTrace();
+            return Result.FAIL("参数解析失败");
+        }
+    }
+
+    //修改药品的图片
+    @RequestMapping("updateDrug")
+    public Result updateDrug(@RequestParam("imageFile") MultipartFile imageFile,
+                             @RequestParam("id") Integer id) {
+        try {
+
+            return drugInfoService.updateDrug(imageFile,id);
+        } catch (Exception e) {
+            return Result.FAIL("参数解析失败");
+        }
+
+    }
+
+  /*  //修改药品
+    @RequestMapping("updateDrug")
+    public Result updateDrug(@RequestBody DrugParam drugParam){
+        return drugInfoService.updateDrug(drugParam);
+    }*/
+
+
+
+
+
+
+
+
+    //删除药品
+    @RequestMapping("delDrug")
+    public Result delDrug(Integer id){
+        return drugInfoService.delDrug(id);
+    }
+
+    //
+
+}

+ 51 - 0
src/main/java/com/zhentao/drug/domain/DrugCategory.java

@@ -0,0 +1,51 @@
+package com.zhentao.drug.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 药品分类表
+ * @TableName drug_category
+ */
+@TableName(value ="drug_category")
+@Data
+public class DrugCategory implements Serializable {
+    /**
+     * 分类唯一ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer categoryId;
+
+    /**
+     * 分类名称,如抗生素类、感冒用药类等
+     */
+    private String categoryName;
+
+
+
+    /**
+     * 父分类ID,若为顶级分类则为NULL,用于构建层级结构
+     */
+    private Integer parentCategoryId;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+    // 非数据库字段,用于存储子分类
+    @TableField(exist = false)
+    private List<DrugCategory> childCategories;
+    /**
+     * 假删
+     */
+    @TableLogic(value = "1",delval = "0")
+    private Integer del;
+
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 98 - 0
src/main/java/com/zhentao/drug/domain/DrugInfo.java

@@ -0,0 +1,98 @@
+package com.zhentao.drug.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * 药品基础信息表
+ * @TableName drug_info
+ */
+@TableName(value ="drug_info")
+@Data
+public class DrugInfo implements Serializable {
+    /**
+     * 药品唯一编码
+     */
+    @TableId(type = IdType.INPUT)// 指定ID由应用层手动输入
+    private String drugId;
+
+    /**
+     * 药品通用名
+     */
+    private String drugName;
+
+    /**
+     * 商品名
+     */
+    private String tradeName;
+
+    /**
+     * 生产厂家
+     */
+    private String manufacturer;
+
+    /**
+     * 规格
+     */
+    private String specification;
+
+    /**
+     * 适应症
+     */
+    private String indication;
+
+    /**
+     * 禁忌症
+     */
+    private String contraindication;
+
+    /**
+     * 副作用
+     */
+    private String sideEffect;
+
+    /**
+     * 单价
+     */
+    private BigDecimal price;
+
+    /**
+     * 库存数量
+     */
+    private Integer stockQuantity;
+
+    /**
+     * 库存预警阈值
+     */
+    private Integer warningThreshold;
+    /**
+     * 药品分类
+     */
+    private Integer categoryId;
+    /**
+     * 药品图片
+     */
+
+    private String image;
+    /**
+     * 录入时间
+     */
+    private Date createTime;
+
+    /**
+     * 0假删 1不删
+     */
+    @TableLogic(value = "1",delval = "0")
+    private Integer del;
+
+
+    // 用于接收上传的图片文件
+    @TableField(exist = false)
+    private MultipartFile imageFile;
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 36 - 0
src/main/java/com/zhentao/drug/dto/DrugCategoryDto.java

@@ -0,0 +1,36 @@
+package com.zhentao.drug.dto;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class DrugCategoryDto {
+
+    /**
+     * 分类唯一ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer categoryId;
+
+    /**
+     * 分类名称,如抗生素类、感冒用药类等
+     */
+    private String categoryName;
+
+    /**
+     * 父分类ID,若为顶级分类则为NULL,用于构建层级结构
+     */
+    private Integer parentCategoryId;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 83 - 0
src/main/java/com/zhentao/drug/dto/DrugDto.java

@@ -0,0 +1,83 @@
+package com.zhentao.drug.dto;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+public class DrugDto {
+    /**
+     * 药品唯一编码
+     */
+    @TableId(type = IdType.INPUT)// 指定ID由应用层手动输入
+    private String drugId;
+
+    /**
+     * 药品通用名
+     */
+    private String drugName;
+
+    /**
+     * 商品名
+     */
+    private String tradeName;
+
+    /**
+     * 生产厂家
+     */
+    private String manufacturer;
+
+    /**
+     * 规格
+     */
+    private String specification;
+
+    /**
+     * 适应症
+     */
+    private String indication;
+
+    /**
+     * 禁忌症
+     */
+    private String contraindication;
+
+    /**
+     * 副作用
+     */
+    private String sideEffect;
+
+    /**
+     * 单价
+     */
+    private BigDecimal price;
+
+    /**
+     * 库存数量
+     */
+    private Integer stockQuantity;
+
+    /**
+     * 库存预警阈值
+     */
+    private Integer warningThreshold;
+
+    /**
+     * 录入时间
+     */
+    private Date createTime;
+
+    /**
+     * 0假删 1不删
+     */
+    @TableLogic(value = "1",delval = "0")
+    private Integer del;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 12 - 0
src/main/java/com/zhentao/drug/dto/param/DrugParam.java

@@ -0,0 +1,12 @@
+package com.zhentao.drug.dto.param;
+
+import com.zhentao.drug.domain.DrugInfo;
+import lombok.Data;
+
+@Data
+public class DrugParam extends DrugInfo {
+    // 页码
+    private Integer pageNum = 1;
+    // 每页页数
+    private Integer pageSize = 2;
+}

+ 20 - 0
src/main/java/com/zhentao/drug/mapper/DrugCategoryMapper.java

@@ -0,0 +1,20 @@
+package com.zhentao.drug.mapper;
+
+import com.zhentao.drug.domain.DrugCategory;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author Administrator
+* @description 针对表【drug_category(药品分类表)】的数据库操作Mapper
+* @createDate 2025-05-23 18:49:31
+* @Entity com.zhentao.drug.pojo.DrugCategory
+*/
+@Mapper
+public interface DrugCategoryMapper extends BaseMapper<DrugCategory> {
+
+}
+
+
+
+

+ 20 - 0
src/main/java/com/zhentao/drug/mapper/DrugInfoMapper.java

@@ -0,0 +1,20 @@
+package com.zhentao.drug.mapper;
+
+import com.zhentao.drug.domain.DrugInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author Administrator
+* @description 针对表【drug_info(药品基础信息表)】的数据库操作Mapper
+* @createDate 2025-05-20 16:04:39
+* @Entity com.zhentao.drug.pojo.DrugInfo
+*/
+@Mapper
+public interface DrugInfoMapper extends BaseMapper<DrugInfo> {
+
+}
+
+
+
+

+ 18 - 0
src/main/java/com/zhentao/drug/service/DrugCategoryService.java

@@ -0,0 +1,18 @@
+package com.zhentao.drug.service;
+
+import com.zhentao.common.Result;
+import com.zhentao.drug.domain.DrugCategory;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhentao.drug.dto.DrugCategoryDto;
+
+/**
+* @author Administrator
+* @description 针对表【drug_category(药品分类表)】的数据库操作Service
+* @createDate 2025-05-23 18:49:31
+*/
+public interface DrugCategoryService extends IService<DrugCategory> {
+
+    Result drugCategoryAll(DrugCategoryDto drugCategoryDto);
+
+    Result oneDelOrTwoDel(Integer categoryId);
+}

+ 27 - 0
src/main/java/com/zhentao/drug/service/DrugInfoService.java

@@ -0,0 +1,27 @@
+package com.zhentao.drug.service;
+
+import com.zhentao.common.Result;
+import com.zhentao.drug.dto.param.DrugParam;
+import com.zhentao.drug.domain.DrugInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+* @author Administrator
+* @description 针对表【drug_info(药品基础信息表)】的数据库操作Service
+* @createDate 2025-05-20 16:04:39
+*/
+public interface DrugInfoService extends IService<DrugInfo> {
+
+    Result drugAll(DrugParam drugParam);
+
+//    Result addDrug(DrugParam drugParam);
+
+    Result addDrug(DrugInfo drugInfo);
+
+    Result updateDrug(MultipartFile imageFile, Integer id);
+//    Result updateDrug(DrugParam drugParam);
+
+    Result delDrug(Integer id);
+}

+ 76 - 0
src/main/java/com/zhentao/drug/service/impl/DrugCategoryServiceImpl.java

@@ -0,0 +1,76 @@
+package com.zhentao.drug.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+import com.zhentao.common.Result;
+import com.zhentao.drug.domain.DrugCategory;
+import com.zhentao.drug.dto.DrugCategoryDto;
+import com.zhentao.drug.service.DrugCategoryService;
+import com.zhentao.drug.mapper.DrugCategoryMapper;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+* @author Administrator
+* @description 针对表【drug_category(药品分类表)】的数据库操作Service实现
+* @createDate 2025-05-23 18:49:31
+*/
+@Service
+public class DrugCategoryServiceImpl extends ServiceImpl<DrugCategoryMapper, DrugCategory>
+    implements DrugCategoryService{
+
+    @Override
+    public Result drugCategoryAll(DrugCategoryDto drugCategoryDto) {
+        // 查询所有一级分类
+        QueryWrapper<DrugCategory> parentQuery = new QueryWrapper<>();
+        parentQuery.isNull("parent_category_id");
+        List<DrugCategory> parentCategories = this.list(parentQuery);
+
+        // 遍历一级分类,查询每个分类的子分类
+        for (DrugCategory parent : parentCategories) {
+            QueryWrapper<DrugCategory> childQuery = new QueryWrapper<>();
+            childQuery.eq("parent_category_id", parent.getCategoryId());
+            List<DrugCategory> childCategories = this.list(childQuery);
+            parent.setChildCategories(childCategories); // 自动关联子分类
+        }
+
+        return Result.SUCCESS(parentCategories);
+    }
+
+    @Override
+    public Result oneDelOrTwoDel(Integer categoryId) {
+        //查询该分类是否存在
+        DrugCategory byId = this.getById(categoryId);
+        if (byId==null){
+            return Result.FAIL("分类不存在");
+        }
+        System.err.println(byId.getParentCategoryId()+"是否有子类");
+        //2判断是否为一级分类
+        if (byId.getParentCategoryId()!=null){
+            this.removeById(byId);
+        }else{
+            //查询两级
+            QueryWrapper<DrugCategory> queryWrapper=new QueryWrapper<>();
+            queryWrapper.eq("parent_category_id",categoryId);
+            //获取所有2级
+            List<DrugCategory> list = this.list(queryWrapper);
+            for (DrugCategory d:list) {
+                System.err.println(d);
+                DrugCategory byId1 = this.getById(d.getCategoryId());
+                this.removeById(byId1);
+
+            }
+            //删除一级
+            this.removeById(byId);
+        }
+
+
+        return Result.SUCCESS(byId);
+    }
+}
+
+
+
+

+ 184 - 0
src/main/java/com/zhentao/drug/service/impl/DrugInfoServiceImpl.java

@@ -0,0 +1,184 @@
+package com.zhentao.drug.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhentao.common.Result;
+import com.zhentao.drug.dto.param.DrugParam;
+import com.zhentao.drug.domain.DrugInfo;
+import com.zhentao.drug.service.DrugInfoService;
+import com.zhentao.drug.mapper.DrugInfoMapper;
+import com.zhentao.drug.utils.IdUtil;
+import org.springframework.web.multipart.MultipartFile;
+
+import org.springframework.stereotype.Service;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.UUID;
+
+/**
+* @author Administrator
+* @description 针对表【drug_info(药品基础信息表)】的数据库操作Service实现
+* @createDate 2025-05-20 16:04:39
+*/
+@Service
+public class DrugInfoServiceImpl extends ServiceImpl<DrugInfoMapper, DrugInfo>
+    implements DrugInfoService{
+
+    @Override
+    public Result drugAll(DrugParam drugParam) {
+        //设置分页查询
+        Page<DrugInfo> page=new Page<>(drugParam.getPageNum(),drugParam.getPageSize());
+
+
+        //设置查询条件
+        QueryWrapper<DrugInfo> queryWrapper=new QueryWrapper<>();
+        if (StringUtils.isNotBlank(drugParam.getDrugName())){
+            //根据药名称模糊查询
+            queryWrapper.like("drug_name",drugParam.getDrugName());
+        }
+//        indication
+        if (StringUtils.isNotBlank(drugParam.getIndication())){
+            //根据适应症状模糊查询
+            queryWrapper.like("indication",drugParam.getIndication());
+        }
+
+        // 处理库存数量查询(只查询库存大于等于0的药品)
+        queryWrapper.gt("stock_quantity",1);
+
+        Page<DrugInfo> page1 = this.page(page, queryWrapper);
+
+        return Result.SUCCESS(page1);
+    }
+
+    @Override
+    public Result addDrug(DrugInfo drugInfo) {
+        MultipartFile imageFile = drugInfo.getImageFile();
+        if (imageFile != null &&!imageFile.isEmpty()) {
+            // 生成唯一文件名
+            String originalFilename = imageFile.getOriginalFilename();
+            System.err.println(originalFilename+"输出这是什么玩意");
+            String fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.'));
+            System.err.println(fileExtension+"输出这是什么玩意");
+            String uniqueFileName = UUID.randomUUID().toString().replace("-","") + fileExtension;
+            System.err.println(uniqueFileName+"输出这是什么玩意");
+            // 保存图片到指定目录(这里简单示例,实际可调整为文件存储服务)
+//            String filePath = "D:/images/医疗项目/" + uniqueFileName;
+            String filePath = "C:/Users/Administrator/Desktop/医疗项目/MedSmart/src/main/resources/statis/" + uniqueFileName;
+            try {
+                imageFile.transferTo(new File(filePath));
+                drugInfo.setImage(uniqueFileName);
+            } catch (IOException e) {
+                e.printStackTrace();
+                return Result.FAIL("图片保存失败");
+            }
+        }
+
+        // 这里假设你有其他业务逻辑,比如生成drugId等,先简单处理
+        // 保存药品信息到数据库
+        drugInfo.setDrugId(IdUtil.nextId());
+        boolean saveResult = this.save(drugInfo);
+        if (saveResult) {
+            return Result.SUCCESS("药品添加成功");
+        } else {
+            return Result.FAIL("药品添加失败");
+        }
+
+    }
+
+    //雪花算法
+   /* @Override
+    public Result addDrug(DrugParam drugParam) {
+        DrugInfo drugInfo = new DrugInfo();
+
+        drugInfo.setDrugId(IdUtil.nextId());
+        drugInfo.setDrugName(drugParam.getDrugName());
+        drugInfo.setTradeName(drugParam.getTradeName());
+        drugInfo.setManufacturer(drugParam.getManufacturer());
+        drugInfo.setSpecification(drugParam.getSpecification());
+        drugInfo.setIndication(drugParam.getIndication());
+        drugInfo.setContraindication(drugParam.getContraindication());
+        drugInfo.setSideEffect(drugParam.getSideEffect());
+        drugInfo.setPrice(drugParam.getPrice());
+        drugInfo.setCategoryId(drugParam.getCategoryId());
+        drugInfo.setStockQuantity(drugParam.getStockQuantity());
+        drugInfo.setWarningThreshold(drugParam.getWarningThreshold());
+        boolean save = this.save(drugInfo);
+
+        return Result.SUCCESS(save+"添加成功");
+    }
+*/
+    @Override
+    public Result updateDrug(MultipartFile imageFile, Integer id) {
+        DrugInfo byId = this.getById(id);
+
+        if (imageFile != null &&!imageFile.isEmpty()) {
+            // 生成唯一文件名
+            String originalFilename = imageFile.getOriginalFilename();
+            System.err.println(originalFilename+"输出这是什么玩意");
+            String fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.'));
+            System.err.println(fileExtension+"输出这是什么玩意");
+            String uniqueFileName = UUID.randomUUID().toString().replace("-","") + fileExtension;
+            System.err.println(uniqueFileName+"输出这是什么玩意");
+            // 保存图片到指定目录(这里简单示例,实际可调整为文件存储服务)
+//            String filePath = "D:/images/医疗项目/" + uniqueFileName;
+            String filePath = "C:/Users/Administrator/Desktop/医疗项目/MedSmart/src/main/resources/statis/" + uniqueFileName;
+
+
+            try {
+                imageFile.transferTo(new File(filePath));
+                byId.setImage(uniqueFileName);
+                System.err.println("image+"+byId);
+            } catch (IOException e) {
+                e.printStackTrace();
+                return Result.FAIL("图片保存失败");
+            }
+        }
+
+        // 这里假设你有其他业务逻辑,比如生成drugId等,先简单处理
+        // 保存药品信息到数据库
+        System.err.println(byId);
+        boolean b = this.updateById(byId);
+        if (b) {
+            return Result.SUCCESS("药品修改成功");
+        } else {
+            return Result.FAIL("药品修改失败");
+        }
+
+    }
+/*
+  @Override
+    public Result updateDrug(DrugParam drugParam) {
+        //根据参数id,查找修改数据
+        QueryWrapper<DrugInfo> queryWrapper=new QueryWrapper<>();
+        queryWrapper.eq("drug_id",drugParam.getDrugId());
+        DrugInfo byId = this.getOne(queryWrapper);
+        //要修改的数据
+        byId.setDrugName(drugParam.getDrugName());
+        byId.setTradeName(drugParam.getTradeName());
+        byId.setManufacturer(drugParam.getManufacturer());
+        byId.setSpecification(drugParam.getSpecification());
+        byId.setIndication(drugParam.getIndication());
+        byId.setContraindication(drugParam.getContraindication());
+        byId.setSideEffect(drugParam.getSideEffect());
+        byId.setPrice(drugParam.getPrice());
+        byId.setStockQuantity(drugParam.getStockQuantity());
+        byId.setCategoryId(drugParam.getCategoryId());
+        byId.setWarningThreshold(drugParam.getWarningThreshold());
+        boolean b = this.updateById(byId);
+        return Result.SUCCESS(b+"修改成功");
+    }
+*/
+
+    @Override
+    public Result delDrug(Integer id) {
+        boolean b = this.removeById(id);
+        return Result.SUCCESS(b+"==true?'删除成功':'删除失败'");
+    }
+}
+
+
+
+

+ 8 - 0
src/main/java/com/zhentao/drug/utils/IdUtil.java

@@ -0,0 +1,8 @@
+package com.zhentao.drug.utils;
+public class IdUtil {
+    private static final SnowflakeIdGenerator ID_GENERATOR = new SnowflakeIdGenerator();
+
+    public static String nextId() {
+        return String.valueOf(ID_GENERATOR.nextId());
+    }
+}

+ 20 - 0
src/main/java/com/zhentao/drug/utils/MyBatisPlusConfig.java

@@ -0,0 +1,20 @@
+package com.zhentao.drug.utils;
+
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class MyBatisPlusConfig {
+
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor() {
+        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+        // 配置分页拦截器
+        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
+        return interceptor;
+    }
+}
+
+

+ 122 - 0
src/main/java/com/zhentao/drug/utils/SnowflakeIdGenerator.java

@@ -0,0 +1,122 @@
+package com.zhentao.drug.utils;
+
+public class SnowflakeIdGenerator {
+    /*// 起始时间戳 (2020-01-01)
+    private final long startTimeStamp = 1577836800000L;
+
+    // 各部分占用位数
+    private final long dataCenterIdBits = 5L;
+    private final long machineIdBits = 5L;
+    private final long sequenceBits = 12L;
+
+    // 最大值
+    private final long maxDataCenterId = -1L ^ (-1L << dataCenterIdBits); // 31
+    private final long maxMachineId = -1L ^ (-1L << machineIdBits); // 31
+    private final long maxSequence = -1L ^ (-1L << sequenceBits); // 4095
+
+    // 位移量
+    private final long machineIdShift = sequenceBits;
+    private final long dataCenterIdShift = sequenceBits + machineIdBits;
+    private final long timestampShift = sequenceBits + machineIdBits + dataCenterIdBits;
+
+    // 数据中心ID和机器ID
+    private final long dataCenterId;
+    private final long machineId;
+
+    // 序列号和上一次时间戳
+    private long sequence = 0L;
+    private long lastTimestamp = -1L;
+
+    // 构造函数
+    public SnowflakeIdGenerator(long dataCenterId, long machineId) {
+        if (dataCenterId > maxDataCenterId || dataCenterId < 0) {
+            throw new IllegalArgumentException("DataCenter ID must be between 0 and " + maxDataCenterId);
+        }
+        if (machineId > maxMachineId || machineId < 0) {
+            throw new IllegalArgumentException("Machine ID must be between 0 and " + maxMachineId);
+        }
+
+        this.dataCenterId = dataCenterId;
+        this.machineId = machineId;
+    }
+
+    // 生成下一个ID
+    public synchronized long nextId() {
+        long currentTimestamp = System.currentTimeMillis();
+
+        // 处理时钟回拨
+        if (currentTimestamp < lastTimestamp) {
+            throw new RuntimeException("Clock moved backwards. Refusing to generate id for "
+                    + (lastTimestamp - currentTimestamp) + " milliseconds");
+        }
+
+        if (currentTimestamp == lastTimestamp) {
+            sequence = (sequence + 1) & maxSequence;
+            if (sequence == 0) {
+                // 当前毫秒内序列号用完,等待下一毫秒
+                currentTimestamp = waitNextMillis(lastTimestamp);
+            }
+        } else {
+            // 不同毫秒,重置序列号
+            sequence = 0L;
+        }
+
+        lastTimestamp = currentTimestamp;
+
+        // 按规则组合生成ID
+        return ((currentTimestamp - startTimeStamp) << timestampShift) |
+                (dataCenterId << dataCenterIdShift) |
+                (machineId << machineIdShift) |
+                sequence;
+    }
+
+    // 等待下一毫秒
+    private long waitNextMillis(long lastTimestamp) {
+        long timestamp = System.currentTimeMillis();
+        while (timestamp <= lastTimestamp) {
+            timestamp = System.currentTimeMillis();
+        }
+        return timestamp;
+    }*/
+    private final long startTimeStamp = 1609459200000L; // 2021-01-01
+    private final long sequenceBits = 10L; // 序列号占10位,范围0-1023
+    private final long maxSequence = -1L ^ (-1L << sequenceBits);
+
+    private long sequence = 0L;
+    private long lastTimestamp = -1L;
+
+    // 生成10位数字ID(格式:时间戳后7位 + 3位序列号)
+    public synchronized String nextId() {
+        long currentTimestamp = System.currentTimeMillis() - startTimeStamp;
+
+        if (currentTimestamp < lastTimestamp) {
+            throw new RuntimeException("Clock moved backwards.");
+        }
+
+        if (currentTimestamp == lastTimestamp) {
+            sequence = (sequence + 1) & maxSequence;
+            if (sequence == 0) {
+                currentTimestamp = waitNextMillis(lastTimestamp);
+            }
+        } else {
+            sequence = 0L;
+        }
+
+        lastTimestamp = currentTimestamp;
+
+        // 组合时间戳和序列号,生成10位数字
+        // 时间戳取后7位(支持约10年),序列号取3位(每毫秒支持1000个ID)
+        long timestampPart = currentTimestamp % 10000000;
+        long id = timestampPart * 1000 + sequence;
+
+        return String.format("%010d", id); // 不足10位时前补0
+    }
+
+    private long waitNextMillis(long lastTimestamp) {
+        long timestamp = System.currentTimeMillis();
+        while (timestamp <= lastTimestamp) {
+            timestamp = System.currentTimeMillis();
+        }
+        return timestamp;
+    }
+}

+ 26 - 0
src/main/java/com/zhentao/symptoms/controller/SymptomsController.java

@@ -0,0 +1,26 @@
+package com.zhentao.symptoms.controller;
+
+import com.zhentao.symptoms.dto.SymptomsDto;
+import com.zhentao.symptoms.service.SymptomsService;
+import com.zhentao.user.vo.ResultVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author: wzy
+ * @date: 2025/5/25 20:46
+ */
+@RestController
+@RequestMapping("/symptoms")
+public class SymptomsController {
+    @Autowired
+    private SymptomsService symptomsService;
+    @PostMapping("/findAll")
+    public ResultVo findAll(@RequestBody SymptomsDto dto){
+        return symptomsService.findAll(dto);
+    }
+    @GetMapping("/selectById/{id}")
+    public ResultVo selectById(@PathVariable Integer id){
+        return symptomsService.selectById(id);
+    }
+}

+ 13 - 0
src/main/java/com/zhentao/symptoms/dto/SymptomsDto.java

@@ -0,0 +1,13 @@
+package com.zhentao.symptoms.dto;
+
+import lombok.Data;
+
+/**
+ * @author: wzy
+ * @date: 2025/5/25 20:54
+ */
+@Data
+public class SymptomsDto {
+    private String category;
+    private String keyword;
+}

+ 20 - 0
src/main/java/com/zhentao/symptoms/mapper/SymptomsMapper.java

@@ -0,0 +1,20 @@
+package com.zhentao.symptoms.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhentao.symptoms.pojo.Symptoms;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author 王阳阳
+* @description 针对表【symptoms(症状信息表)】的数据库操作Mapper
+* @createDate 2025-05-25 20:49:10
+* @Entity com.zhentao.common.symptoms.pojo.Symptoms
+*/
+@Mapper
+public interface SymptomsMapper extends BaseMapper<Symptoms> {
+
+}
+
+
+
+

+ 42 - 0
src/main/java/com/zhentao/symptoms/pojo/Symptoms.java

@@ -0,0 +1,42 @@
+package com.zhentao.symptoms.pojo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * @TableName symptoms
+ */
+@TableName(value ="symptoms")
+@Data
+public class Symptoms implements Serializable {
+    private Integer id;
+
+    private String name;
+
+    private String description;
+
+    private String category;
+
+    private String bodyPart;
+
+    private Integer severity;
+
+    private String commonCauses;
+
+    private String suggestedActions;
+
+    private String relatedDiseases;
+
+    private Date createdAt;
+
+    private Date updatedAt;
+
+    private Integer isActive;
+
+    private static final long serialVersionUID = 1L;
+}

+ 18 - 0
src/main/java/com/zhentao/symptoms/service/SymptomsService.java

@@ -0,0 +1,18 @@
+package com.zhentao.symptoms.service;
+
+import com.zhentao.symptoms.dto.SymptomsDto;
+import com.zhentao.symptoms.pojo.Symptoms;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhentao.user.vo.ResultVo;
+
+/**
+* @author 王阳阳
+* @description 针对表【symptoms(症状信息表)】的数据库操作Service
+* @createDate 2025-05-25 20:49:10
+*/
+public interface SymptomsService extends IService<Symptoms> {
+
+    ResultVo findAll(SymptomsDto dto);
+
+    ResultVo selectById(Integer id);
+}

+ 46 - 0
src/main/java/com/zhentao/symptoms/service/impl/SymptomsServiceImpl.java

@@ -0,0 +1,46 @@
+package com.zhentao.symptoms.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhentao.symptoms.dto.SymptomsDto;
+import com.zhentao.symptoms.pojo.Symptoms;
+import com.zhentao.symptoms.service.SymptomsService;
+import com.zhentao.symptoms.mapper.SymptomsMapper;
+import com.zhentao.user.vo.ResultVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+* @author 王阳阳
+* @description 针对表【symptoms(症状信息表)】的数据库操作Service实现
+* @createDate 2025-05-25 20:49:10
+*/
+@Service
+public class SymptomsServiceImpl extends ServiceImpl<SymptomsMapper, Symptoms>
+    implements SymptomsService{
+    @Autowired
+    private SymptomsMapper symptomsMapper;
+    @Override
+    public ResultVo findAll(SymptomsDto dto) {
+//        QueryWrapper<Symptoms> queryWrapper = new QueryWrapper<>();
+//        queryWrapper.eq(true,"category",dto.getCategory())
+//                .or().eq(true,"name",dto.getKeyword())
+//                .or().eq(true,"description",dto.getKeyword());
+        List<Symptoms> symptoms = symptomsMapper.selectList(null);
+        return ResultVo.success(symptoms);
+    }
+
+    @Override
+    public ResultVo selectById(Integer id) {
+        QueryWrapper<Symptoms> queryWrapper = new QueryWrapper<>();
+        QueryWrapper<Symptoms> wrapper = queryWrapper.eq("id", id);
+        Symptoms symptoms = symptomsMapper.selectOne(wrapper);
+        return ResultVo.success(symptoms);
+    }
+}
+
+
+
+

+ 32 - 0
src/main/java/com/zhentao/user/controller/UserLoginController.java

@@ -0,0 +1,32 @@
+package com.zhentao.user.controller;
+
+import com.zhentao.user.dto.UserLoginDto;
+import com.zhentao.user.service.UserService;
+import com.zhentao.user.vo.ResultVo;
+import org.springframework.beans.factory.annotation.Autowired;
+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;
+
+/**
+ * @date: 2025/5/20 15:30
+ * @author: ftt
+ */
+
+@RestController
+@RequestMapping("/user")
+public class UserLoginController {
+    @Autowired
+    private UserService userService;
+
+    @PostMapping("/register")
+    public ResultVo register(@RequestBody UserLoginDto dto) {
+        return userService.register(dto);
+    }
+
+    @PostMapping("/login")
+    public ResultVo login(@RequestBody UserLoginDto dto) {
+        return userService.login(dto);
+    }
+}

+ 1 - 0
src/main/java/com/zhentao/user/domain/User.java

@@ -20,6 +20,7 @@ public class User implements Serializable {
     private String username;
 
     private String password;
+    private String salt;
 
     private String realName;
 

+ 17 - 0
src/main/java/com/zhentao/user/dto/UserLoginDto.java

@@ -0,0 +1,17 @@
+package com.zhentao.user.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author: wzy
+ * @date: 2025/5/20 16:32
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class UserLoginDto {
+    private String username;
+    private String password;
+}

+ 7 - 0
src/main/java/com/zhentao/user/service/UserService.java

@@ -1,9 +1,12 @@
 package com.zhentao.user.service;
 
+import com.zhentao.common.Result;
 import com.zhentao.user.domain.User;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.zhentao.user.dto.LoginResponseDTO;
+import com.zhentao.user.dto.UserLoginDto;
 import com.zhentao.user.dto.WechatLoginDTO;
+import com.zhentao.user.vo.ResultVo;
 
 /**
 * @author ASUS
@@ -12,4 +15,8 @@ import com.zhentao.user.dto.WechatLoginDTO;
 */
 public interface UserService extends IService<User> {
     LoginResponseDTO wechatLogin(WechatLoginDTO dto);
+
+    ResultVo register(UserLoginDto dto);
+
+    ResultVo login(UserLoginDto dto);
 }

+ 51 - 3
src/main/java/com/zhentao/user/service/impl/UserServiceImpl.java

@@ -1,9 +1,13 @@
 package com.zhentao.user.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhentao.common.Result;
 import com.zhentao.user.domain.User;
+import com.zhentao.user.dto.UserLoginDto;
 import com.zhentao.user.service.UserService;
 import com.zhentao.user.mapper.UserMapper;
+import com.zhentao.user.vo.ResultVo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -13,11 +17,12 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.util.DigestUtils;
 import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
 import org.springframework.web.client.RestTemplate;
 
-import javax.annotation.Resource;
+import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
@@ -47,6 +52,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
     @Autowired
     private RestTemplate restTemplate;
 
+    @Autowired
+    private UserMapper userMapper;
+
     @Override
     public LoginResponseDTO wechatLogin(WechatLoginDTO dto) {
         try {
@@ -93,6 +101,46 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
         }
     }
 
+    @Override
+    public ResultVo register(UserLoginDto dto) {
+        if (dto == null){
+            return ResultVo.error(400,"参数无效");
+        }
+        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(User::getUsername,dto.getUsername());
+        User user = userMapper.selectOne(queryWrapper);
+        if (user != null){
+            return ResultVo.error(401,"用户信息已存在");
+        }
+        User user1 = new User();
+        user1.setUsername(dto.getUsername());
+        String salt = UUID.randomUUID().toString().replace("-", "");
+        String digest = DigestUtils.md5DigestAsHex((dto.getPassword() + salt).getBytes(StandardCharsets.UTF_8));
+        user1.setPassword(digest);
+        user1.setSalt(salt);
+        userMapper.insert(user1);
+        return ResultVo.success("注册成功");
+    }
+
+    @Override
+    public ResultVo login(UserLoginDto dto) {
+        if (dto == null){
+            return ResultVo.error(400,"参数无效");
+        }
+        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(User::getUsername,dto.getUsername());
+        User user = userMapper.selectOne(queryWrapper);
+        if (user == null){
+            return ResultVo.error(401,"用户不存在");
+        }
+        String salt = user.getSalt();
+        String s = DigestUtils.md5DigestAsHex((dto.getPassword() + salt).getBytes(StandardCharsets.UTF_8));
+        if (!s.equals(user.getPassword())){
+            return ResultVo.error(401,"用户名或密码错误");
+        }
+        return ResultVo.success(user);
+    }
+
     private Map<String, String> getWxSession(String code) {
         MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
         params.add("appid", appId);
@@ -133,7 +181,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
         user.setWxOpenid(openid);
         user.setWxSessionKey(sessionKey);
         user.setLoginType(1); // 1=微信登录
-    
+
         // 如果有用户信息,填充到实体
         if (dto.getRawData() != null) {
             try {
@@ -155,7 +203,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
     private void updateUserInfo(User user, String sessionKey, WechatLoginDTO dto) {
         user.setWxSessionKey(sessionKey);
         user.setWxLastLoginTime(new java.util.Date());
-    
+
         // 如果有新的用户信息,更新
         if (dto.getRawData() != null) {
             try {

+ 47 - 0
src/main/java/com/zhentao/user/vo/ResultVo.java

@@ -0,0 +1,47 @@
+package com.zhentao.user.vo;
+
+public class ResultVo<T> {
+    private int code;
+    private String msg;
+    private T data;
+
+    public static <T> ResultVo<T> success(T data) {
+        ResultVo<T> result = new ResultVo<>();
+        result.setCode(200);
+        result.setMsg("成功");
+        result.setData(data);
+        return result;
+    }
+
+    public static <T> ResultVo<T> error(int code, String msg) {
+        ResultVo<T> result = new ResultVo<>();
+        result.setCode(code);
+        result.setMsg(msg);
+        return result;
+    }
+
+    // getters and setters
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+}

+ 12 - 2
src/main/resources/application.yml

@@ -2,9 +2,9 @@ server:
   port: 8080
 spring:
   datasource:
-    url: jdbc:mysql://localhost:3306/medical_inquiry_system?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
+    url: jdbc:mysql://39.105.174.251:3306/medical_inquiry_system?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
     username: root
-    password: root
+    password: Tingting520
     driver-class-name: com.mysql.cj.jdbc.Driver
 
   redis:
@@ -12,6 +12,16 @@ spring:
     port: 6379
     password:
 
+  ai:
+    openai:
+      api-key: "demo"
+      base-url: "http://langchain4j.dev/demo/openai/v1"
+
+  servlet:
+    multipart:
+      max-file-size: 10MB
+      max-request-size: 100MB
+
 mybatis-plus:
   mapper-locations: classpath:mapper/*.xml
   type-aliases-package: com.zhentao.*.domain

+ 19 - 0
src/main/resources/mapper/DrugCategoryMapper.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zhentao.drug.mapper.DrugCategoryMapper">
+
+    <resultMap id="BaseResultMap" type="com.zhentao.drug.domain.DrugCategory">
+            <id property="categoryId" column="category_id" jdbcType="INTEGER"/>
+            <result property="categoryName" column="category_name" jdbcType="VARCHAR"/>
+            <result property="parentCategoryId" column="parent_category_id" jdbcType="INTEGER"/>
+            <result property="del" column="del" jdbcType="INTEGER"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        category_id,category_name,parent_category_id,
+        create_time,del
+    </sql>
+</mapper>

+ 32 - 0
src/main/resources/mapper/DrugInfoMapper.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zhentao.drug.mapper.DrugInfoMapper">
+
+    <resultMap id="BaseResultMap" type="com.zhentao.drug.domain.DrugInfo">
+            <id property="drugId" column="drug_id" jdbcType="CHAR"/>
+            <result property="drugName" column="drug_name" jdbcType="VARCHAR"/>
+            <result property="tradeName" column="trade_name" jdbcType="VARCHAR"/>
+            <result property="manufacturer" column="manufacturer" jdbcType="VARCHAR"/>
+            <result property="specification" column="specification" jdbcType="VARCHAR"/>
+            <result property="indication" column="indication" jdbcType="VARCHAR"/>
+            <result property="contraindication" column="contraindication" jdbcType="VARCHAR"/>
+            <result property="sideEffect" column="side_effect" jdbcType="VARCHAR"/>
+            <result property="image" column="image" jdbcType="VARCHAR"/>
+            <result property="price" column="price" jdbcType="DECIMAL"/>
+            <result property="stockQuantity" column="stock_quantity" jdbcType="INTEGER"/>
+            <result property="warningThreshold" column="warning_threshold" jdbcType="INTEGER"/>
+            <result property="categoryId" column="category_id" jdbcType="INTEGER"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+            <result property="del" column="del" jdbcType="INTEGER"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        drug_id,drug_name,trade_name,
+        manufacturer,specification,indication,
+        contraindication,side_effect,price,
+        stock_quantity,category_id,warning_threshold,create_time,image,
+        del
+    </sql>
+</mapper>

+ 28 - 0
src/main/resources/mapper/SymptomsMapper.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zhentao.symptoms.mapper.SymptomsMapper">
+
+    <resultMap id="BaseResultMap" type="com.zhentao.symptoms.pojo.Symptoms">
+            <id property="id" column="id" jdbcType="INTEGER"/>
+            <result property="name" column="name" jdbcType="VARCHAR"/>
+            <result property="description" column="description" jdbcType="VARCHAR"/>
+            <result property="category" column="category" jdbcType="VARCHAR"/>
+            <result property="bodyPart" column="body_part" jdbcType="VARCHAR"/>
+            <result property="severity" column="severity" jdbcType="INTEGER"/>
+            <result property="commonCauses" column="common_causes" jdbcType="VARCHAR"/>
+            <result property="suggestedActions" column="suggested_actions" jdbcType="VARCHAR"/>
+            <result property="relatedDiseases" column="related_diseases" jdbcType="VARCHAR"/>
+            <result property="createdAt" column="created_at" jdbcType="TIMESTAMP"/>
+            <result property="updatedAt" column="updated_at" jdbcType="TIMESTAMP"/>
+            <result property="isActive" column="is_active" jdbcType="TINYINT"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,name,description,
+        category,body_part,severity,
+        common_causes,suggested_actions,related_diseases,
+        created_at,updated_at,is_active
+    </sql>
+</mapper>

+ 2 - 1
src/main/resources/mapper/UserMapper.xml

@@ -8,6 +8,7 @@
             <id property="userId" column="user_id" jdbcType="INTEGER"/>
             <result property="username" column="username" jdbcType="VARCHAR"/>
             <result property="password" column="password" jdbcType="VARCHAR"/>
+            <result property="salt" column="salt" jdbcType="VARCHAR"/>
             <result property="realName" column="real_name" jdbcType="VARCHAR"/>
             <result property="gender" column="gender" jdbcType="TINYINT"/>
             <result property="birthday" column="birthday" jdbcType="DATE"/>
@@ -25,7 +26,7 @@
     </resultMap>
 
     <sql id="Base_Column_List">
-        user_id,username,password,
+        user_id,username,password,salt,
         real_name,gender,birthday,
         mobile,role,create_time,
         last_login_time,wx_openid,wx_unionid,