feng_ting-ting 2 days ago
parent
commit
d0ebbb5dfa
21 changed files with 897 additions and 22 deletions
  1. 17 0
      pom.xml
  2. 7 0
      src/main/java/com/zhentao/MedSmartApplication.java
  3. 1 1
      src/main/java/com/zhentao/common/MyBatisPlusConfig.java
  4. 1 21
      src/main/java/com/zhentao/drug/controller/DrugInfoController.java
  5. 14 0
      src/main/java/com/zhentao/prescription/PrescriptionApplication.java
  6. 76 0
      src/main/java/com/zhentao/prescription/controller/PrescriptionController.java
  7. 24 0
      src/main/java/com/zhentao/prescription/dto/PrescriptionDTO.java
  8. 18 0
      src/main/java/com/zhentao/prescription/dto/PrescriptionDetailDTO.java
  9. 15 0
      src/main/java/com/zhentao/prescription/exception/GlobalExceptionHandler.java
  10. 9 0
      src/main/java/com/zhentao/prescription/mapper/PrescriptionDetailMapper.java
  11. 40 0
      src/main/java/com/zhentao/prescription/mapper/PrescriptionMapper.java
  12. 37 0
      src/main/java/com/zhentao/prescription/model/AuditRecord.java
  13. 33 0
      src/main/java/com/zhentao/prescription/model/Doctor.java
  14. 42 0
      src/main/java/com/zhentao/prescription/model/MedicationRecord.java
  15. 51 0
      src/main/java/com/zhentao/prescription/model/Medicine.java
  16. 44 0
      src/main/java/com/zhentao/prescription/model/MedicineInventory.java
  17. 39 0
      src/main/java/com/zhentao/prescription/model/Patient.java
  18. 54 0
      src/main/java/com/zhentao/prescription/model/Prescription.java
  19. 55 0
      src/main/java/com/zhentao/prescription/model/PrescriptionDetail.java
  20. 42 0
      src/main/java/com/zhentao/prescription/service/PrescriptionService.java
  21. 278 0
      src/main/java/com/zhentao/prescription/service/impl/PrescriptionServiceImpl.java

+ 17 - 0
pom.xml

@@ -14,6 +14,23 @@
         <spring-boot.version>2.7.6</spring-boot.version>
     </properties>
     <dependencies>
+
+
+        <dependency>
+            <groupId>org.modelmapper</groupId>
+            <artifactId>modelmapper</artifactId>
+            <version>3.1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>5.2.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>5.2.3</version>
+        </dependency>
         <dependency>
             <groupId>dev.langchain4j</groupId>
             <artifactId>langchain4j-open-ai</artifactId>

+ 7 - 0
src/main/java/com/zhentao/MedSmartApplication.java

@@ -1,7 +1,9 @@
 package com.zhentao;
 
+import org.modelmapper.ModelMapper;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
 
 @SpringBootApplication
 public class MedSmartApplication {
@@ -10,4 +12,9 @@ public class MedSmartApplication {
         SpringApplication.run(MedSmartApplication.class, args);
     }
 
+    @Bean
+    public ModelMapper modelMapper() {
+        return new ModelMapper();
+    }
+
 }

+ 1 - 1
src/main/java/com/zhentao/drug/utils/MyBatisPlusConfig.java → src/main/java/com/zhentao/common/MyBatisPlusConfig.java

@@ -1,4 +1,4 @@
-package com.zhentao.drug.utils;
+package com.zhentao.common;
 
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;

+ 1 - 21
src/main/java/com/zhentao/drug/controller/DrugInfoController.java

@@ -22,11 +22,7 @@ public class DrugInfoController {
     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) {
@@ -55,25 +51,9 @@ public class DrugInfoController {
 
     }
 
-  /*  //修改药品
-    @RequestMapping("updateDrug")
-    public Result updateDrug(@RequestBody DrugParam drugParam){
-        return drugInfoService.updateDrug(drugParam);
-    }*/
-
-
-
-
-
-
-
-
     //删除药品
     @RequestMapping("delDrug")
     public Result delDrug(Integer id){
         return drugInfoService.delDrug(id);
     }
-
-    //
-
 }

+ 14 - 0
src/main/java/com/zhentao/prescription/PrescriptionApplication.java

@@ -0,0 +1,14 @@
+package com.prescription;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@MapperScan("com.prescription.mapper")
+public class PrescriptionApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(PrescriptionApplication.class, args);
+    }
+}

+ 76 - 0
src/main/java/com/zhentao/prescription/controller/PrescriptionController.java

@@ -0,0 +1,76 @@
+package com.zhentao.prescription.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhentao.prescription.dto.PrescriptionDTO;
+import com.zhentao.prescription.service.PrescriptionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/prescriptions")
+public class PrescriptionController {
+
+    @Autowired
+    private PrescriptionService prescriptionService;
+
+    @GetMapping
+    public ResponseEntity<List<PrescriptionDTO>> getAllPrescriptions() {
+        List<PrescriptionDTO> prescriptions = prescriptionService.findAll().stream()
+                .map(prescriptionService::convertToDTO)
+                .collect(java.util.stream.Collectors.toList());
+        return new ResponseEntity<>(prescriptions, HttpStatus.OK);
+    }
+
+    @GetMapping("/{id}")
+    public ResponseEntity<PrescriptionDTO> getPrescriptionById(@PathVariable Long id) {
+        PrescriptionDTO prescription = prescriptionService.getPrescriptionDetails(id);
+        if (prescription != null) {
+            return new ResponseEntity<>(prescription, HttpStatus.OK);
+        } else {
+            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+        }
+    }
+
+    @GetMapping("/search")
+    public ResponseEntity<Page<PrescriptionDTO>> searchPrescriptions(
+            @RequestParam(required = false) String patientName,
+            @RequestParam(required = false) String prescriptionNo,
+            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
+            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate,
+            @RequestParam(required = false) String status,
+            @RequestParam(defaultValue = "1") Long page,
+            @RequestParam(defaultValue = "10") Long size) {
+
+        Page<PrescriptionDTO> resultPage = prescriptionService.searchPrescriptions(
+                new Page<>(page, size), patientName, prescriptionNo, startDate, endDate, status);
+        return new ResponseEntity<>(resultPage, HttpStatus.OK);
+    }
+
+    @GetMapping("/export")
+    public ResponseEntity<byte[]> exportToExcel(
+            @RequestParam(required = false) String patientName,
+            @RequestParam(required = false) String prescriptionNo,
+            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
+            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate,
+            @RequestParam(required = false) String status) {
+
+        List<PrescriptionDTO> prescriptions = prescriptionService.searchPrescriptions(
+                new Page<>(1, 1000), patientName, prescriptionNo, startDate, endDate, status).getRecords();
+
+        byte[] excelBytes = prescriptionService.exportToExcel(prescriptions);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
+        headers.setContentDispositionFormData("attachment", "prescriptions_" + LocalDate.now() + ".xlsx");
+
+        return new ResponseEntity<>(excelBytes, headers, HttpStatus.OK);
+    }
+}

+ 24 - 0
src/main/java/com/zhentao/prescription/dto/PrescriptionDTO.java

@@ -0,0 +1,24 @@
+package com.zhentao.prescription.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Data
+public class PrescriptionDTO {
+    private Long prescriptionId;
+    private String prescriptionNo;
+    private String patientName;
+    private String patientGender;
+    private Integer patientAge;
+    private String doctorName;
+    private String department;
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private LocalDate visitDate;
+    private String diagnosis;
+    private Double totalAmount;
+    private String status;
+    private List<PrescriptionDetailDTO> details;
+}

+ 18 - 0
src/main/java/com/zhentao/prescription/dto/PrescriptionDetailDTO.java

@@ -0,0 +1,18 @@
+package com.zhentao.prescription.dto;
+
+import lombok.Data;
+
+@Data
+public class PrescriptionDetailDTO {
+    private Long detailId;
+    private String medicineName;
+    private String specification;
+    private Integer quantity;
+    private String usageMethod;
+    private String dosage;
+    private String frequency;
+    private String duration;
+    private String notes;
+    private Double price;
+    private Double amount;
+}

+ 15 - 0
src/main/java/com/zhentao/prescription/exception/GlobalExceptionHandler.java

@@ -0,0 +1,15 @@
+package com.prescription.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+    @ExceptionHandler(Exception.class)
+    public ResponseEntity<String> handleGlobalException(Exception ex) {
+        return new ResponseEntity<>("系统错误: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+    }
+}

+ 9 - 0
src/main/java/com/zhentao/prescription/mapper/PrescriptionDetailMapper.java

@@ -0,0 +1,9 @@
+package com.zhentao.prescription.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhentao.prescription.model.PrescriptionDetail;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface PrescriptionDetailMapper extends BaseMapper<PrescriptionDetail> {
+}

+ 40 - 0
src/main/java/com/zhentao/prescription/mapper/PrescriptionMapper.java

@@ -0,0 +1,40 @@
+package com.zhentao.prescription.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhentao.prescription.model.Prescription;
+import com.zhentao.prescription.model.PrescriptionDetail;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.time.LocalDate;
+import java.util.List;
+@Mapper
+public interface PrescriptionMapper extends BaseMapper<Prescription> {
+
+    /**
+     * 根据处方编号查询处方详情(关联患者和医生信息)
+     */
+    Prescription selectFullDetailByNo(@Param("prescriptionNo") String prescriptionNo);
+
+    /**
+     * 根据患者姓名查询处方列表
+     */
+    List<Prescription> selectByPatientName(@Param("name") String name);
+
+    /**
+     * 分页查询处方列表
+     */
+    IPage<Prescription> selectPageWithCondition(Page<Prescription> page,
+                                              @Param("patientName") String patientName,
+                                              @Param("prescriptionNo") String prescriptionNo,
+                                              @Param("startDate") LocalDate startDate,
+                                              @Param("endDate") LocalDate endDate,
+                                              @Param("status") String status);
+
+    /**
+     * 查询处方明细列表
+     */
+    List<PrescriptionDetail> selectDetailsByPrescriptionId(@Param("prescriptionId") Long prescriptionId);
+}

+ 37 - 0
src/main/java/com/zhentao/prescription/model/AuditRecord.java

@@ -0,0 +1,37 @@
+package com.zhentao.prescription.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("audit_record")
+public class AuditRecord {
+
+    @TableId(value = "audit_id", type = IdType.AUTO)
+    private Long auditId;
+
+    @TableField("prescription_id")
+    private Long prescriptionId;
+
+    @TableField("auditor_id")
+    private Long auditorId;
+
+    @TableField("audit_time")
+    private LocalDateTime auditTime;
+
+    @TableField("audit_result")
+    private String auditResult;
+
+    @TableField("audit_comment")
+    private String auditComment;
+
+    @TableField(value = "create_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime createTime;
+
+    // 关联查询字段
+    @TableField(exist = false)
+    private Prescription prescription;
+}

+ 33 - 0
src/main/java/com/zhentao/prescription/model/Doctor.java

@@ -0,0 +1,33 @@
+package com.zhentao.prescription.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("doctor")
+public class Doctor {
+
+    @TableId(value = "doctor_id", type = IdType.AUTO)
+    private Long doctorId;
+
+    @TableField("name")
+    private String name;
+
+    @TableField("department")
+    private String department;
+
+    @TableField("title")
+    private String title;
+
+    @TableField("phone")
+    private String phone;
+
+    @TableField(value = "create_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime createTime;
+
+    @TableField(value = "update_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime updateTime;
+}

+ 42 - 0
src/main/java/com/zhentao/prescription/model/MedicationRecord.java

@@ -0,0 +1,42 @@
+package com.zhentao.prescription.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("medication_record")
+public class MedicationRecord {
+
+    @TableId(value = "record_id", type = IdType.AUTO)
+    private Long recordId;
+
+    @TableField("prescription_id")
+    private Long prescriptionId;
+
+    @TableField("detail_id")
+    private Long detailId;
+
+    @TableField("patient_id")
+    private Long patientId;
+
+    @TableField("medicine_id")
+    private Long medicineId;
+
+    @TableField("actual_time")
+    private LocalDateTime actualTime;
+
+    @TableField("dosage")
+    private String dosage;
+
+    @TableField("operator_id")
+    private Long operatorId;
+
+    @TableField("remarks")
+    private String remarks;
+
+    @TableField(value = "create_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime createTime;
+}

+ 51 - 0
src/main/java/com/zhentao/prescription/model/Medicine.java

@@ -0,0 +1,51 @@
+package com.zhentao.prescription.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("medicine")
+public class Medicine {
+
+    @TableId(value = "medicine_id", type = IdType.AUTO)
+    private Long medicineId;
+
+    @TableField("name")
+    private String name;
+
+    @TableField("scientific_name")
+    private String scientificName;
+
+    @TableField("specification")
+    private String specification;
+
+    @TableField("unit")
+    private String unit;
+
+    @TableField("manufacturer")
+    private String manufacturer;
+
+    @TableField("approval_number")
+    private String approvalNumber;
+
+    @TableField("category")
+    private String category;
+
+    @TableField("contraindication")
+    private String contraindication;
+
+    @TableField("adverse_reaction")
+    private String adverseReaction;
+
+    @TableField("price")
+    private Double price;
+
+    @TableField(value = "create_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime createTime;
+
+    @TableField(value = "update_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime updateTime;
+}

+ 44 - 0
src/main/java/com/zhentao/prescription/model/MedicineInventory.java

@@ -0,0 +1,44 @@
+package com.zhentao.prescription.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+@Data
+@TableName("medicine_inventory")
+public class MedicineInventory {
+
+    @TableId(value = "inventory_id", type = IdType.AUTO)
+    private Long inventoryId;
+
+    @TableField("medicine_id")
+    private Long medicineId;
+
+    @TableField("batch_number")
+    private String batchNumber;
+
+    @TableField("production_date")
+    private LocalDate productionDate;
+
+    @TableField("expiry_date")
+    private LocalDate expiryDate;
+
+    @TableField("quantity")
+    private Integer quantity;
+
+    @TableField("location")
+    private String location;
+
+    @TableField(value = "create_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime createTime;
+
+    @TableField(value = "update_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime updateTime;
+
+    // 关联查询字段
+    @TableField(exist = false)
+    private Medicine medicine;
+}

+ 39 - 0
src/main/java/com/zhentao/prescription/model/Patient.java

@@ -0,0 +1,39 @@
+package com.zhentao.prescription.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("patient")
+public class Patient {
+
+    @TableId(value = "patient_id", type = IdType.AUTO)
+    private Long patientId;
+
+    @TableField("name")
+    private String name;
+
+    @TableField("gender")
+    private String gender;
+
+    @TableField("age")
+    private Integer age;
+
+    @TableField("phone")
+    private String phone;
+
+    @TableField("id_card")
+    private String idCard;
+
+    @TableField("address")
+    private String address;
+
+    @TableField(value = "create_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime createTime;
+
+    @TableField(value = "update_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime updateTime;
+}

+ 54 - 0
src/main/java/com/zhentao/prescription/model/Prescription.java

@@ -0,0 +1,54 @@
+package com.zhentao.prescription.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Data
+@TableName("prescription")
+public class Prescription {
+
+    @TableId(value = "prescription_id", type = IdType.AUTO)
+    private Long prescriptionId;
+
+    @TableField("prescription_no")
+    private String prescriptionNo;
+
+    @TableField("patient_id")
+    private Long patientId;
+
+    @TableField("doctor_id")
+    private Long doctorId;
+
+    @TableField("visit_date")
+    private LocalDate visitDate;
+
+    @TableField("diagnosis")
+    private String diagnosis;
+
+    @TableField("total_amount")
+    private Double totalAmount;
+
+    @TableField("status")
+    private String status;
+
+    @TableField(value = "create_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime createTime;
+
+    @TableField(value = "update_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime updateTime;
+
+    // 关联查询字段
+    @TableField(exist = false)
+    private Patient patient;
+
+    @TableField(exist = false)
+    private Doctor doctor;
+
+    @TableField(exist = false)
+    private List<PrescriptionDetail> details;
+}

+ 55 - 0
src/main/java/com/zhentao/prescription/model/PrescriptionDetail.java

@@ -0,0 +1,55 @@
+package com.zhentao.prescription.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("prescription_detail")
+public class PrescriptionDetail {
+
+    @TableId(value = "detail_id", type = IdType.AUTO)
+    private Long detailId;
+
+    @TableField("prescription_id")
+    private Long prescriptionId;
+
+    @TableField("medicine_id")
+    private Long medicineId;
+
+    @TableField("quantity")
+    private Integer quantity;
+
+    @TableField("usage_method")
+    private String usageMethod;
+
+    @TableField("dosage")
+    private String dosage;
+
+    @TableField("frequency")
+    private String frequency;
+
+    @TableField("duration")
+    private String duration;
+
+    @TableField("notes")
+    private String notes;
+
+    @TableField("price")
+    private Double price;
+
+    @TableField("amount")
+    private Double amount;
+
+    @TableField(value = "create_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime createTime;
+
+    @TableField(value = "update_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime updateTime;
+
+    // 关联查询字段
+    @TableField(exist = false)
+    private Medicine medicine;
+}

+ 42 - 0
src/main/java/com/zhentao/prescription/service/PrescriptionService.java

@@ -0,0 +1,42 @@
+package com.zhentao.prescription.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhentao.prescription.dto.PrescriptionDTO;
+import com.zhentao.prescription.model.Prescription;
+
+import java.time.LocalDate;
+import java.util.List;
+
+public interface PrescriptionService {
+
+    List<Prescription> findAll();
+
+    Page<Prescription> findAll(Page<Prescription> page);
+
+    Prescription findById(Long id);
+
+    Prescription findByPrescriptionNo(String prescriptionNo);
+
+    List<Prescription> findByPatientId(Long patientId);
+
+    List<Prescription> findByDoctorId(Long doctorId);
+
+    List<Prescription> findByStatus(String status);
+
+    List<Prescription> findByVisitDate(LocalDate visitDate);
+
+    List<Prescription> findByPatientNameContaining(String name);
+
+    PrescriptionDTO getPrescriptionDetails(Long id);
+
+    Page<PrescriptionDTO> searchPrescriptions(Page<PrescriptionDTO> page,
+                                             String patientName,
+                                             String prescriptionNo,
+                                             LocalDate startDate,
+                                             LocalDate endDate,
+                                             String status);
+
+    byte[] exportToExcel(List<PrescriptionDTO> prescriptions);
+
+    PrescriptionDTO convertToDTO(Prescription prescription);
+}

+ 278 - 0
src/main/java/com/zhentao/prescription/service/impl/PrescriptionServiceImpl.java

@@ -0,0 +1,278 @@
+package com.zhentao.prescription.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhentao.prescription.dto.PrescriptionDTO;
+import com.zhentao.prescription.dto.PrescriptionDetailDTO;
+import com.zhentao.prescription.mapper.PrescriptionDetailMapper;
+import com.zhentao.prescription.mapper.PrescriptionMapper;
+import com.zhentao.prescription.model.*;
+import com.zhentao.prescription.service.PrescriptionService;
+
+import org.modelmapper.ModelMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+@Service
+@Transactional
+public class PrescriptionServiceImpl implements PrescriptionService {
+
+    @Autowired
+    private PrescriptionMapper prescriptionMapper;
+
+    @Autowired
+    private PrescriptionDetailMapper prescriptionDetailMapper;
+
+    @Autowired
+    private ModelMapper modelMapper;
+
+    @Override
+    public List<Prescription> findAll() {
+        return prescriptionMapper.selectList(null);
+    }
+
+    @Override
+    public Page<Prescription> findAll(Page<Prescription> page) {
+        return prescriptionMapper.selectPage(page, null);
+    }
+
+    @Override
+    public Prescription findById(Long id) {
+        return prescriptionMapper.selectById(id);
+    }
+
+    @Override
+    public Prescription findByPrescriptionNo(String prescriptionNo) {
+        return prescriptionMapper.selectFullDetailByNo(prescriptionNo);
+    }
+
+    @Override
+    public List<Prescription> findByPatientId(Long patientId) {
+        QueryWrapper<Prescription> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("patient_id", patientId);
+        return prescriptionMapper.selectList(queryWrapper);
+    }
+
+    @Override
+    public List<Prescription> findByDoctorId(Long doctorId) {
+        QueryWrapper<Prescription> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("doctor_id", doctorId);
+        return prescriptionMapper.selectList(queryWrapper);
+    }
+
+    @Override
+    public List<Prescription> findByStatus(String status) {
+        QueryWrapper<Prescription> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("status", status);
+        return prescriptionMapper.selectList(queryWrapper);
+    }
+
+    @Override
+    public List<Prescription> findByVisitDate(LocalDate visitDate) {
+        QueryWrapper<Prescription> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("visit_date", visitDate);
+        return prescriptionMapper.selectList(queryWrapper);
+    }
+
+    @Override
+    public List<Prescription> findByPatientNameContaining(String name) {
+        return prescriptionMapper.selectByPatientName(name);
+    }
+
+    @Override
+    public PrescriptionDTO getPrescriptionDetails(Long id) {
+        Prescription prescription = prescriptionMapper.selectById(id);
+        if (prescription == null) {
+            return null;
+        }
+
+        PrescriptionDTO dto = modelMapper.map(prescription, PrescriptionDTO.class);
+
+        // 设置处方明细
+        List<PrescriptionDetail> details = prescriptionDetailMapper.selectList(
+                new QueryWrapper<PrescriptionDetail>().eq("prescription_id", id));
+
+        List<PrescriptionDetailDTO> detailDTOs = details.stream()
+                .map(detail -> {
+                    PrescriptionDetailDTO detailDTO = modelMapper.map(detail, PrescriptionDetailDTO.class);
+                    // 实际项目中应该查询Medicine表获取药品名称和规格
+                    detailDTO.setMedicineName("药品名称" + detail.getMedicineId());
+                    detailDTO.setSpecification("规格" + detail.getMedicineId());
+                    return detailDTO;
+                })
+                .collect(Collectors.toList());
+        dto.setDetails(detailDTOs);
+
+        return dto;
+    }
+
+    @Override
+    public Page<PrescriptionDTO> searchPrescriptions(Page<PrescriptionDTO> page,
+                                                    String patientName,
+                                                    String prescriptionNo,
+                                                    LocalDate startDate,
+                                                    LocalDate endDate,
+                                                    String status) {
+        // 先查询Prescription列表
+        Page<Prescription> prescriptionPage = new Page<>(page.getCurrent(), page.getSize());
+        prescriptionMapper.selectPageWithCondition(
+                prescriptionPage, patientName, prescriptionNo, startDate, endDate, status);
+
+        // 转换为DTO
+        List<PrescriptionDTO> dtoList = prescriptionPage.getRecords().stream()
+                .map(this::convertToDTO)
+                .collect(Collectors.toList());
+
+        // 构建结果
+        Page<PrescriptionDTO> resultPage = new Page<>(
+                prescriptionPage.getCurrent(),
+                prescriptionPage.getSize(),
+                prescriptionPage.getTotal());
+        resultPage.setRecords(dtoList);
+
+        return resultPage;
+    }
+
+    public PrescriptionDTO convertToDTO(Prescription prescription) {
+        PrescriptionDTO dto = modelMapper.map(prescription, PrescriptionDTO.class);
+
+        // 设置处方明细
+        List<PrescriptionDetail> details = prescriptionDetailMapper.selectList(
+                new QueryWrapper<PrescriptionDetail>().eq("prescription_id", prescription.getPrescriptionId()));
+
+        List<PrescriptionDetailDTO> detailDTOs = details.stream()
+                .map(detail -> {
+                    PrescriptionDetailDTO detailDTO = modelMapper.map(detail, PrescriptionDetailDTO.class);
+                    // 实际项目中应该查询Medicine表获取药品名称和规格
+                    detailDTO.setMedicineName("药品名称" + detail.getMedicineId());
+                    detailDTO.setSpecification("规格" + detail.getMedicineId());
+                    return detailDTO;
+                })
+                .collect(Collectors.toList());
+        dto.setDetails(detailDTOs);
+
+        return dto;
+    }
+
+    @Override
+    public byte[] exportToExcel(List<PrescriptionDTO> prescriptions) {
+        Workbook workbook = new XSSFWorkbook();
+        Sheet sheet = workbook.createSheet("处方信息");
+
+        // 创建标题行
+        Row headerRow = sheet.createRow(0);
+        String[] headers = {
+            "处方编号", "患者姓名", "性别", "年龄", "医生", "科室",
+            "就诊日期", "诊断结果", "总金额", "状态",
+            "药品名称", "规格", "数量", "用法", "剂量",
+            "频次", "疗程", "注意事项", "单价", "金额"
+        };
+
+        for (int i = 0; i < headers.length; i++) {
+            Cell cell = headerRow.createCell(i);
+            cell.setCellValue(headers[i]);
+
+            // 设置标题样式
+            CellStyle style = workbook.createCellStyle();
+            Font font = workbook.createFont();
+            font.setBold(true);
+            style.setFont(font);
+            style.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
+            style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+            style.setBorderTop(BorderStyle.THIN);
+            style.setBorderBottom(BorderStyle.THIN);
+            style.setBorderLeft(BorderStyle.THIN);
+            style.setBorderRight(BorderStyle.THIN);
+            cell.setCellStyle(style);
+        }
+
+        // 填充数据
+        int rowNum = 1;
+        for (PrescriptionDTO prescription : prescriptions) {
+            // 为每个处方的每个明细创建一行
+            for (PrescriptionDetailDTO detail : prescription.getDetails()) {
+                Row row = sheet.createRow(rowNum++);
+
+                // 处方信息
+                row.createCell(0).setCellValue(prescription.getPrescriptionNo());
+                row.createCell(1).setCellValue(prescription.getPatientName());
+                row.createCell(2).setCellValue(prescription.getPatientGender());
+
+                if (prescription.getPatientAge() != null) {
+                    row.createCell(3).setCellValue(prescription.getPatientAge());
+                }
+
+                row.createCell(4).setCellValue(prescription.getDoctorName());
+                row.createCell(5).setCellValue(prescription.getDepartment());
+                row.createCell(6).setCellValue(prescription.getVisitDate().toString());
+                row.createCell(7).setCellValue(prescription.getDiagnosis());
+
+                if (prescription.getTotalAmount() != null) {
+                    row.createCell(8).setCellValue(prescription.getTotalAmount());
+                }
+
+                row.createCell(9).setCellValue(prescription.getStatus());
+
+                // 药品明细信息
+                row.createCell(10).setCellValue(detail.getMedicineName());
+                row.createCell(11).setCellValue(detail.getSpecification());
+                row.createCell(12).setCellValue(detail.getQuantity());
+                row.createCell(13).setCellValue(detail.getUsageMethod());
+                row.createCell(14).setCellValue(detail.getDosage());
+                row.createCell(15).setCellValue(detail.getFrequency());
+                row.createCell(16).setCellValue(detail.getDuration());
+                row.createCell(17).setCellValue(detail.getNotes());
+
+                if (detail.getPrice() != null) {
+                    row.createCell(18).setCellValue(detail.getPrice());
+                }
+
+                if (detail.getAmount() != null) {
+                    row.createCell(19).setCellValue(detail.getAmount());
+                }
+
+                // 设置单元格样式
+                for (int i = 0; i < headers.length; i++) {
+                    CellStyle style = workbook.createCellStyle();
+                    style.setBorderTop(BorderStyle.THIN);
+                    style.setBorderBottom(BorderStyle.THIN);
+                    style.setBorderLeft(BorderStyle.THIN);
+                    style.setBorderRight(BorderStyle.THIN);
+                    row.getCell(i).setCellStyle(style);
+                }
+            }
+        }
+
+        // 自动调整列宽
+        for (int i = 0; i < headers.length; i++) {
+            sheet.autoSizeColumn(i);
+        }
+
+        // 将工作簿写入字节数组
+        try {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            workbook.write(outputStream);
+            byte[] bytes = outputStream.toByteArray();
+            workbook.close();
+            return bytes;
+        } catch (Exception e) {
+            throw new RuntimeException("导出Excel失败", e);
+        }
+    }
+
+    // 内部类用于处理字节数组输出流
+    private static class ByteArrayOutputStream extends java.io.ByteArrayOutputStream {
+        public byte[] toByteArray() {
+            return this.buf;
+        }
+    }
+}