From 03d2740ecb063e39e3453402607eecca048d332d Mon Sep 17 00:00:00 2001
From: zhuo <2089219845@qq.com>
Date: 星期六, 22 二月 2025 15:20:19 +0800
Subject: [PATCH] 移植设备停用启用, 设备报废

---
 cnas-device/src/main/resources/mapper/DeviceScrappedMapper.xml                         |   27 
 cnas-device/src/main/java/com/ruoyi/device/excel/DeviceStateExport.java                |   36 +
 cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceImpl.java     |   86 +++
 cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceScrappedMapper.java            |   35 +
 cnas-device/src/main/java/com/ruoyi/device/service/DeviceScrappedService.java          |   43 +
 cnas-device/src/main/java/com/ruoyi/device/dto/DeviceScrappedDto.java                  |   26 
 cnas-device/src/main/java/com/ruoyi/device/service/DeviceMaintenanceService.java       |   24 
 cnas-device/src/main/resources/static/word/incident-report.docx                        |    0 
 cnas-device/src/main/java/com/ruoyi/device/service/DeviceStateService.java             |   31 +
 cnas-device/src/main/resources/static/word/quipment-details.docx                       |    0 
 cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceBorrowServiceImpl.java   |  116 ++++
 cnas-device/src/main/resources/static/word/review-examine-record-contrast.docx         |    0 
 cnas-device/src/main/resources/static/word/traceability-management-details.docx        |    0 
 cnas-device/src/main/java/com/ruoyi/device/controller/DeviceStateController.java       |   87 +++
 cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceLogMapper.java                 |    9 
 cnas-device/src/main/resources/static/word/examine-plan-detail.docx                    |    0 
 cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceScrapped.java                    |  105 +++
 cnas-device/src/main/java/com/ruoyi/device/controller/DeviceScrappedController.java    |   82 ++
 cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceStateServiceImpl.java    |  159 +++++
 cnas-device/src/main/resources/static/word/maintenance-plan.docx                       |    0 
 cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceState.java                       |  107 +++
 cnas-device/src/main/java/com/ruoyi/device/controller/DeviceBorrowController.java      |   73 ++
 cnas-device/src/main/java/com/ruoyi/device/dto/DeviceStateDto.java                     |   32 +
 cnas-device/src/main/resources/static/word/device-accident-report.docx                 |    0 
 cnas-device/src/main/resources/static/word/maintenance-records.docx                    |    0 
 cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceScrappedServiceImpl.java |  179 ++++++
 cnas-device/src/main/resources/static/word/acceptance-certificate.docx                 |    0 
 cnas-device/src/main/java/com/ruoyi/device/controller/DeviceMaintenanceController.java |   98 +++
 cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceBorrowMapper.java              |   25 
 cnas-device/src/main/resources/static/word/device-document.docx                        |    0 
 cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceLog.java                         |   29 +
 cnas-device/src/main/resources/static/word/device-breakdown-maintenance.docx           |    0 
 cnas-device/src/main/resources/static/word/device-scrapped.docx                        |    0 
 cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceStateMapper.java               |   20 
 cnas-device/src/main/resources/static/word/device-calibration-plan.docx                |    0 
 cnas-device/src/main/resources/static/word/use-record.docx                             |    0 
 cnas-device/src/main/java/com/ruoyi/device/service/DeviceBorrowService.java            |   28 +
 cnas-device/src/main/resources/mapper/DeviceBorrowMapper.xml                           |   21 
 cnas-device/src/main/resources/mapper/DeviceStateMapper.xml                            |   19 
 cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceBorrow.java                      |  133 ++++
 cnas-device/src/main/resources/static/word/device-external-apply.docx                  |    0 
 cnas-device/src/main/resources/static/word/device-status.docx                          |    0 
 cnas-device/src/main/resources/static/word/examine-record.docx                         |    0 
 cnas-device/src/main/resources/static/word/device-inspection-record.docx               |    0 
 44 files changed, 1,630 insertions(+), 0 deletions(-)

diff --git a/cnas-device/src/main/java/com/ruoyi/device/controller/DeviceBorrowController.java b/cnas-device/src/main/java/com/ruoyi/device/controller/DeviceBorrowController.java
new file mode 100644
index 0000000..6ddde96
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/controller/DeviceBorrowController.java
@@ -0,0 +1,73 @@
+package com.ruoyi.device.controller;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.core.domain.Result;
+import com.ruoyi.device.pojo.DeviceBorrow;
+import com.ruoyi.device.service.DeviceBorrowService;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ *  鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author 姹熻嫃榈烽洀缃戠粶绉戞妧鏈夐檺鍏徃
+ * @since 2024-09-21 10:53:51
+ */
+@RestController
+@RequestMapping("/deviceBorrow")
+public class DeviceBorrowController {
+
+    @Resource
+    private DeviceBorrowService deviceBorrowService;
+
+
+    //鍒嗛〉
+    @PostMapping("/deviceBorrowPage")
+    public Result deviceBorrowPage(Page page, DeviceBorrow deviceBorrow) throws Exception {
+        return Result.success(deviceBorrowService.deviceBorrowPage(page, deviceBorrow));
+    }
+
+    //鏌ヨ
+    @GetMapping("/getDeviceBorrow")
+    public Result getDeviceBorrow(Integer id) {
+        return Result.success(deviceBorrowService.getDeviceBorrow(id));
+    }
+
+    //鏂板
+    @PostMapping("/saveDeviceBorrow")
+    public Result saveDeviceBorrow(@RequestBody DeviceBorrow deviceBorrow) {
+        return Result.success(deviceBorrowService.saveDeviceBorrow(deviceBorrow));
+    }
+
+    //鍒犻櫎
+    @PostMapping("/deleteDeviceBorrow")
+    public Result deleteDeviceBorrow(Integer id) {
+        return Result.success(deviceBorrowService.removeById(id));
+    }
+
+    //瀵煎嚭
+    @PostMapping("/deviceBorrowExport")
+    public Result deviceBorrowExport(@RequestParam("deviceId") Integer deviceId, HttpServletResponse response) throws Exception {
+        List<DeviceBorrow> deviceBorrows = deviceBorrowService.getDeviceBorrowBydeviceId(deviceId);
+        response.setHeader("requestType", "excel");
+        response.setHeader("Access-Control-Expose-Headers", "requestType");
+        // 璁剧疆鍗曞厓鏍兼牱寮�
+        // 淇濆瓨鍒扮涓�涓猻heet涓�
+        EasyExcel.write(response.getOutputStream())
+                .head(DeviceBorrow.class)
+                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 鑷�傚簲鍒楀
+                .sheet()
+                .doWrite(deviceBorrows);
+        return Result.success();
+    }
+
+
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/controller/DeviceMaintenanceController.java b/cnas-device/src/main/java/com/ruoyi/device/controller/DeviceMaintenanceController.java
new file mode 100644
index 0000000..9420f41
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/controller/DeviceMaintenanceController.java
@@ -0,0 +1,98 @@
+package com.ruoyi.device.controller;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.write.metadata.style.WriteCellStyle;
+import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.core.domain.Result;
+import com.ruoyi.common.numgen.NumberGenerator;
+import com.ruoyi.device.excel.DeviceMaintenanceExport;
+import com.ruoyi.device.pojo.DeviceMaintenance;
+import com.ruoyi.device.service.DeviceMaintenanceService;
+import io.swagger.annotations.ApiOperation;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * todo: 瀛欐渤婊�
+ */
+@RestController
+@RequestMapping("/device-maintain")
+public class DeviceMaintenanceController {
+
+    @Autowired
+    private DeviceMaintenanceService deviceMaintenanceService;
+
+    @Autowired
+    private NumberGenerator<DeviceMaintenance> numberGenerator;
+    //澧�
+    @PostMapping()
+    public Result create(@RequestBody DeviceMaintenance deviceMaintenance){
+        String year = new SimpleDateFormat("yy", Locale.CHINESE).format(new Date());
+        String month = new SimpleDateFormat("MM", Locale.CHINESE).format(new Date());
+        String processNumber = numberGenerator.generateNumberWithPrefix(3, "DG-TC-23FM " + month + "-" + year + month, DeviceMaintenance::getDeviceNumber);
+        deviceMaintenance.setDeviceNumber(processNumber);
+        return Result.success(deviceMaintenanceService.save(deviceMaintenance));
+    }
+
+    //閫氳繃deviceId鏌ヨ缁存姢鏁版嵁
+    @GetMapping("/getDeviceMaintenancePage")
+    public Result getDeviceMaintenancePage(@RequestParam("deviceId") Integer deviceId, Page page, String deviceNumber){
+        return Result.success(deviceMaintenanceService.getDeviceMaintenancePage(page, deviceId, deviceNumber));
+    }
+
+    //鍒�
+    @DeleteMapping("/delete/{id}")
+    public void deleteDeviceFault(@PathVariable Integer id) {
+        deviceMaintenanceService.removeById(id);
+    }
+
+    @GetMapping("/deviceMaintenanceExport")
+    public Result deviceMaintenanceExport(@RequestParam("deviceId") Integer deviceId, HttpServletResponse response) throws IOException {
+        List<DeviceMaintenanceExport> list = deviceMaintenanceService.deviceMaintenanceExport(deviceId);
+        response.setHeader("requestType","excel");
+        response.setHeader("Access-Control-Expose-Headers", "requestType");
+        // 璁剧疆鍗曞厓鏍兼牱寮�
+        // 淇濆瓨鍒扮涓�涓猻heet涓�
+        EasyExcel.write(response.getOutputStream())
+                .head(DeviceMaintenanceExport.class)
+                .registerWriteHandler(getHorizontalCellStyleStrategy((short) 12))
+                .sheet()
+                .doWrite(list);
+        return Result.success();
+    }
+
+    @ApiOperation(value = "璁惧缁存姢璁板綍瀵煎嚭")
+    @GetMapping("/exportMaintenanceRecord")
+    public void exportMaintenanceRecord(@RequestParam("deviceId") Integer deviceId, HttpServletResponse response) throws Exception {
+        deviceMaintenanceService.exportMaintenanceRecord(deviceId, response);
+    }
+
+    /**
+     * 鍗曞厓鏍兼牱寮忕瓥鐣�
+     */
+    public static HorizontalCellStyleStrategy getHorizontalCellStyleStrategy(Short fontHeightInPoints) {
+        // 鍐呭鐨勭瓥鐣�
+        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
+
+        // 銆愭按骞冲眳涓渶瑕佷娇鐢ㄤ互涓嬩袱琛屻��
+        // 璁剧疆鏂囧瓧宸﹀彸灞呬腑
+        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
+        // 璁剧疆鏂囧瓧涓婁笅灞呬腑
+        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+        // 璁剧疆 鑷姩鎹㈣
+        contentWriteCellStyle.setWrapped(true);
+
+        // 鏍峰紡绛栫暐
+        return new HorizontalCellStyleStrategy(null, contentWriteCellStyle);
+    }
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/controller/DeviceScrappedController.java b/cnas-device/src/main/java/com/ruoyi/device/controller/DeviceScrappedController.java
new file mode 100644
index 0000000..9bada11
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/controller/DeviceScrappedController.java
@@ -0,0 +1,82 @@
+package com.ruoyi.device.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.core.domain.Result;
+import com.ruoyi.device.pojo.DeviceScrapped;
+import com.ruoyi.device.service.DeviceScrappedService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+
+/**
+ * <p>
+ * 璁惧鎶ュ簾鐢宠琛� 鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author 姹熻嫃榈烽洀缃戠粶绉戞妧鏈夐檺鍏徃
+ * @since 2024-12-17 01:53:47
+ */
+@Api(tags = "璁惧鎶ュ簾鐢宠琛�")
+@AllArgsConstructor
+@RestController
+@RequestMapping("/deviceScrapped")
+public class DeviceScrappedController {
+
+    private DeviceScrappedService deviceScrappedService;
+
+
+    /**
+     * 璁惧鎶ュ簾鐢宠鍒楄〃
+     * @return
+     */
+    @ApiOperation(value = "璁惧鎶ュ簾鐢宠鍒楄〃")
+    @PostMapping("/pageDeviceScrapped")
+    public Result<IPage<DeviceScrapped>> pageDeviceScrapped(Page page, DeviceScrapped deviceScrapped) {
+        return Result.success(deviceScrappedService.pageDeviceScrapped(page, deviceScrapped));
+    }
+
+    /**
+     * 鏌ヨ璁惧鎶ュ簾鐢宠
+     * @return
+     */
+    @ApiOperation(value = "鏌ヨ璁惧鎶ュ簾鐢宠")
+    @GetMapping("/getDeviceScrapped")
+    public Result getDeviceScrapped(Integer scrappedId){
+        return Result.success(deviceScrappedService.getById(scrappedId));
+    }
+
+    /**
+     * 鍒犻櫎璁惧鏍告煡璁″垝璇︽儏
+     * @return
+     */
+    @ApiOperation(value = "鍒犻櫎璁惧鎶ュ簾鐢宠")
+    @GetMapping("/delDeviceScrapped")
+    public Result delDeviceScrapped(Integer scrappedId){
+        return Result.success(deviceScrappedService.removeById(scrappedId));
+    }
+
+    /**
+     * 鏂板璁惧鎶ュ簾鐢宠
+     * @return
+     */
+    @ApiOperation(value = "鏂板璁惧鎶ュ簾鐢宠")
+    @PostMapping("/addDeviceScrapped")
+    public Result addDeviceScrapped(@RequestBody DeviceScrapped deviceScrapped){
+        return Result.success(deviceScrappedService.addDeviceScrapped(deviceScrapped));
+    }
+
+    /**
+     * 瀵煎嚭璁惧鎶ュ簾鐢宠
+     */
+    @ApiOperation("瀵煎嚭璁惧鎶ュ簾鐢宠")
+    @GetMapping("/exportDeviceScrapped")
+    public Result exportDeviceScrapped(Integer scrappedId, HttpServletResponse response) {
+        return deviceScrappedService.exportDeviceScrapped(scrappedId, response);
+    }
+
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/controller/DeviceStateController.java b/cnas-device/src/main/java/com/ruoyi/device/controller/DeviceStateController.java
new file mode 100644
index 0000000..4c73996
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/controller/DeviceStateController.java
@@ -0,0 +1,87 @@
+package com.ruoyi.device.controller;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson2.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.core.domain.Result;
+import com.ruoyi.common.numgen.NumberGenerator;
+import com.ruoyi.device.dto.DeviceStateDto;
+import com.ruoyi.device.excel.DeviceStateExport;
+import com.ruoyi.device.pojo.DeviceState;
+import com.ruoyi.device.service.DeviceStateService;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * <p>
+ * 璁惧鍋滅敤/鍚敤 鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2024-09-26 09:51:40
+ */
+@RestController
+@RequestMapping("/deviceState")
+public class DeviceStateController {
+
+    @Autowired
+    private DeviceStateService deviceStateService;
+
+    @Autowired
+    private NumberGenerator<DeviceState> numberGenerator;
+
+    @PostMapping("saveDeviceState")
+    public Result saveIncidentReportData(@RequestBody DeviceState deviceState) {
+        if (ObjectUtils.isEmpty(deviceState.getProcessNumber())) {
+            String year = new SimpleDateFormat("yy", Locale.CHINESE).format(new Date());
+            String month = new SimpleDateFormat("MM", Locale.CHINESE).format(new Date());
+            String processNumber = numberGenerator.generateNumberWithPrefix(3, "DG-TC-23FM " + month + "-" + year + month, DeviceState::getProcessNumber);
+            deviceState.setProcessNumber(processNumber);
+        }
+        deviceStateService.saveOrUpdate(deviceState);
+        return Result.success();
+    }
+
+    @GetMapping("/getDeviceStatePage")
+    public Result getDeviceStatePage(@RequestParam("deviceId") Integer deviceId, Page page, String processNumber){
+        return Result.success(deviceStateService.getDeviceStatePage(deviceId, page, processNumber));
+    }
+
+    @DeleteMapping("/deleteDeviceState")
+    public Result deleteDeviceState(@RequestParam("stateId") Integer stateId){
+        return Result.success(deviceStateService.removeById(stateId));
+    }
+
+    @PostMapping("/deviceStateExport")
+    public Result deviceStateExport(@RequestParam("deviceId") Integer deviceId, String processNumber, HttpServletResponse response) throws Exception {
+        IPage<DeviceStateDto> deviceBorrows = deviceStateService.getDeviceStatePage(deviceId, new Page<>(1, -1), processNumber);
+        List<DeviceStateExport> studentList  = JSONObject.parseArray(JSON.toJSONString(deviceBorrows.getRecords()), DeviceStateExport.class);
+        response.setHeader("requestType", "excel");
+        response.setHeader("Access-Control-Expose-Headers", "requestType");
+        // 璁剧疆鍗曞厓鏍兼牱寮�
+        // 淇濆瓨鍒扮涓�涓猻heet涓�
+        EasyExcel.write(response.getOutputStream())
+                .head(DeviceStateExport.class)
+                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 鑷�傚簲鍒楀
+                .sheet("sheet")
+                .doWrite(studentList);
+        return Result.success();
+    }
+
+    @ApiOperation(value = "璁惧鍚姩/鍋滄瀵煎嚭")
+    @GetMapping("/exportDeviceStatus")
+    public void exportDeviceStatus(@RequestParam("processNumber") String processNumber,@RequestParam("deviceId") Integer deviceId, HttpServletResponse response) throws Exception {
+        deviceStateService.exportDeviceStatus(deviceId, processNumber, response);
+    }
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/dto/DeviceScrappedDto.java b/cnas-device/src/main/java/com/ruoyi/device/dto/DeviceScrappedDto.java
new file mode 100644
index 0000000..4cac0ce
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/dto/DeviceScrappedDto.java
@@ -0,0 +1,26 @@
+package com.ruoyi.device.dto;
+
+import com.ruoyi.device.pojo.DeviceScrapped;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * Author: yuan
+ * Date: 2024-12-17 鏄熸湡浜� 18:34:17
+ * Description:
+ */
+@Data
+public class DeviceScrappedDto extends DeviceScrapped {
+
+    @ApiModelProperty("鐢宠鏃堕棿")
+    private String applicantDateStr;
+
+    @ApiModelProperty("閮ㄩ棬璐熻矗浜哄~鍐欐椂闂�")
+    private String departmentHeadDateStr;
+
+    @ApiModelProperty("璁¢噺瀹や汉濉啓鏃堕棿")
+    private String meteringRoomDateStr;
+
+    @ApiModelProperty("鎵瑰噯浜哄~鍐欐椂闂�")
+    private String approverDateStr;
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/dto/DeviceStateDto.java b/cnas-device/src/main/java/com/ruoyi/device/dto/DeviceStateDto.java
new file mode 100644
index 0000000..6e45eee
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/dto/DeviceStateDto.java
@@ -0,0 +1,32 @@
+package com.ruoyi.device.dto;
+
+import com.ruoyi.device.pojo.DeviceState;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class DeviceStateDto extends DeviceState {
+    @ApiModelProperty(value = "璁惧鍚嶇О")
+    private String deviceName;
+
+    @ApiModelProperty(value = "瑙勬牸鍨嬪彿")
+    private String specificationModel;
+
+    @ApiModelProperty(value = "绠$悊缂栧彿")
+    private String managementNumber;
+
+    @ApiModelProperty(value = "鎿嶄綔鏃ユ湡 yyyy-MM-dd")
+    private String submitDateString;
+
+    @ApiModelProperty("璐熻矗浜哄鎵规棩鏈� yyyy-MM-dd")
+    private String departmentDateString;
+
+    @ApiModelProperty("璁¢噺瀹ゅ鎵规棩鏈� yyyy-MM-dd")
+    private String measuringRoomDateString;
+
+    @ApiModelProperty("鎵瑰噯鏃ユ湡 yyyy-MM-dd")
+    private String approvalDateString;
+
+    @ApiModelProperty(value = "璁惧绫诲瀷")
+    private String largeCategory;
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/excel/DeviceStateExport.java b/cnas-device/src/main/java/com/ruoyi/device/excel/DeviceStateExport.java
new file mode 100644
index 0000000..f4e5592
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/excel/DeviceStateExport.java
@@ -0,0 +1,36 @@
+package com.ruoyi.device.excel;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class DeviceStateExport {
+    @ExcelProperty(value = "璁惧鍚嶇О")
+    private String deviceName;
+
+    @ExcelProperty(value = "瑙勬牸鍨嬪彿")
+    private String specificationModel;
+
+    @ExcelProperty(value = "绠$悊缂栧彿")
+    private String managementNumber;
+
+    @ExcelProperty("璁惧鐘舵��")
+    private String deviceStatus;
+
+    @ExcelProperty("鍋滅敤鍚敤鐞嗙敱")
+    private String reason;
+
+    @ExcelProperty("鎻愪氦浜�")
+    private String createUser;
+
+    @ExcelProperty("鎻愪氦鏃ユ湡")
+    private LocalDateTime createTime;
+
+    @ExcelProperty("褰撳墠鐘舵��")
+    private String currentState;
+
+    @ExcelProperty("褰撳墠璐熻矗浜�")
+    private String currentResponsible;
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceBorrowMapper.java b/cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceBorrowMapper.java
new file mode 100644
index 0000000..498e972
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceBorrowMapper.java
@@ -0,0 +1,25 @@
+package com.ruoyi.device.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.device.pojo.DeviceBorrow;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 姹熻嫃榈烽洀缃戠粶绉戞妧鏈夐檺鍏徃
+ * @since 2024-09-21 10:53:51
+ */
+public interface DeviceBorrowMapper extends BaseMapper<DeviceBorrow> {
+
+    IPage<DeviceBorrow> deviceBorrowPage(Page page, @Param("ew")QueryWrapper<DeviceBorrow> ew);
+
+    List<DeviceBorrow> getDeviceBorrowBydeviceId(Integer deviceId);
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceLogMapper.java b/cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceLogMapper.java
new file mode 100644
index 0000000..193b5b6
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceLogMapper.java
@@ -0,0 +1,9 @@
+package com.ruoyi.device.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.device.pojo.DeviceLog;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface DeviceLogMapper extends BaseMapper<DeviceLog> {
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceScrappedMapper.java b/cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceScrappedMapper.java
new file mode 100644
index 0000000..bf6266f
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceScrappedMapper.java
@@ -0,0 +1,35 @@
+package com.ruoyi.device.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.device.dto.DeviceScrappedDto;
+import com.ruoyi.device.pojo.DeviceScrapped;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * <p>
+ * 璁惧鎶ュ簾鐢宠琛� Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 姹熻嫃榈烽洀缃戠粶绉戞妧鏈夐檺鍏徃
+ * @since 2024-12-17 01:53:47
+ */
+public interface DeviceScrappedMapper extends BaseMapper<DeviceScrapped> {
+
+    /**
+     * 璁惧鎶ュ簾鐢宠鍒楄〃
+     * @param page
+     * @param ew
+     * @return
+     */
+    IPage<DeviceScrapped> pageDeviceScrapped(Page page, @Param("ew") QueryWrapper<DeviceScrapped> ew);
+
+    /**
+     * 鏍规嵁id鏌ヨ璁惧鎶ュ簾鐢宠
+     * @param scrappedId
+     * @return
+     */
+    DeviceScrappedDto selectDeviceScrappedById(@Param("scrappedId") Integer scrappedId);
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceStateMapper.java b/cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceStateMapper.java
new file mode 100644
index 0000000..db96d63
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceStateMapper.java
@@ -0,0 +1,20 @@
+package com.ruoyi.device.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.ruoyi.device.dto.DeviceStateDto;
+import com.ruoyi.device.pojo.DeviceState;
+
+/**
+ * <p>
+ * 璁惧鍋滅敤/鍚敤 Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2024-09-26 09:51:40
+ */
+public interface DeviceStateMapper extends BaseMapper<DeviceState> {
+
+    IPage<DeviceStateDto> getDeviceStatePage(Integer deviceId, Page page, String processNumber);
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceBorrow.java b/cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceBorrow.java
new file mode 100644
index 0000000..da122b6
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceBorrow.java
@@ -0,0 +1,133 @@
+package com.ruoyi.device.pojo;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author 姹熻嫃榈烽洀缃戠粶绉戞妧鏈夐檺鍏徃
+ * @since 2024-09-21 10:53:51
+ */
+@Getter
+@Setter
+@TableName("device_borrow")
+@ApiModel(value = "DeviceBorrow瀵硅薄", description = "璁惧鍊熺敤")
+@ExcelIgnoreUnannotated
+public class DeviceBorrow implements Serializable {
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty("娴佺▼缂栧彿")
+    @ExcelProperty(value = "娴佺▼缂栧彿")
+    private String processNumber;
+
+    @ApiModelProperty("璁惧id")
+    private Integer deviceId;
+
+    @ApiModelProperty("绠$悊缂栧彿")
+    @ExcelProperty(value = "绠$悊缂栧彿")
+    private String unifyNumber;
+
+    @ApiModelProperty("鍊熺敤浜�")
+    @ExcelProperty(value = "鍊熺敤浜�")
+    private String recipientUser;
+
+    @ExcelProperty(value = "鍊熺敤浜鸿仈绯绘柟寮�")
+    @ApiModelProperty("鍊熺敤浜鸿仈绯绘柟寮�")
+    private String borrowerContactInformation;
+
+    @ApiModelProperty("鍊熺敤鏃剁姸鎬�")
+    @ExcelProperty(value = "鍊熺敤鏃剁姸鎬�")
+    //0鍚堟牸;1缁翠慨;2鍋滅敤;3鎶ュ簾
+    private Integer recipientState;
+
+    @ApiModelProperty("鍊熺敤鏃ユ湡")
+    @ExcelProperty(value = "鎻愪氦鏃ユ湡")
+    private Date recipientTime;
+
+    @ApiModelProperty("鍊熷嚭浜�")
+    @ExcelProperty(value = "鍊熷嚭浜�")
+    private String submitUser;
+
+    @ApiModelProperty("鍊熷嚭鏃ユ湡")
+    @ExcelProperty(value = "鍊熷嚭鏃ユ湡")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("褰撳墠鐘舵��")
+    @ExcelProperty(value = "褰撳墠鐘舵��")
+    private String nowState;
+
+    @ApiModelProperty("褰撳墠璐d换浜�")
+    @ExcelProperty(value = "褰撳墠璐d换浜�")
+    private String nowUser;
+
+    @ApiModelProperty("闄勪欢")
+    //璺緞
+    private String url;
+
+    @ApiModelProperty("闄勪欢")
+    @ExcelProperty(value = "闄勪欢")
+    //鏂囦欢鍚�
+    private String fileName;
+
+    @ApiModelProperty("涓嬬幆鑺傝矗浠讳汉")
+    private String nextUser;
+
+    @ApiModelProperty("鎻愪氦鎿嶄綔浜�")
+    private String submitOperationUser;
+
+    @ApiModelProperty("鎻愪氦鎿嶄綔鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime submitOperationTime;
+
+    @ApiModelProperty("褰掕繕浜�")
+    private String rebackUser;
+
+    @ApiModelProperty("褰掕繕鏃ユ湡")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime rebackTime;
+
+    @ApiModelProperty("鎺ュ彈鐘舵��0鍚堟牸;1缁翠慨;2鍋滅敤;3鎶ュ簾")
+    private Integer receiveState;
+
+    @ApiModelProperty("璁惧璐d换浜�")
+    private String deviceUser;
+
+    @ApiModelProperty("澶囨敞")
+    private String note;
+
+    @ApiModelProperty("鎺ユ敹鎿嶄綔浜�")
+    private String receiveOperationUser;
+
+    @ApiModelProperty("鎺ユ敹鎿嶄綔鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime receiveOperationTime;
+
+    @ApiModelProperty("璁惧鍚嶇О")
+    @TableField(select = false, exist = false)
+    @ExcelProperty(value = "璁惧鍚嶇О")
+    private String deviceName;
+
+
+    @ApiModelProperty("娴佺▼璺熻釜")
+    @TableField(select = false, exist = false)
+    private List<DeviceLog> deviceLogs;
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceLog.java b/cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceLog.java
new file mode 100644
index 0000000..5141c82
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceLog.java
@@ -0,0 +1,29 @@
+package com.ruoyi.device.pojo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@Data
+@TableName("device_log") // 璁板綍
+public class DeviceLog implements Serializable {
+
+    @TableId(type= IdType.AUTO)
+    private Integer id;
+    private String operator;
+//    @JsonFormat()
+    private LocalDateTime operationTime;
+    private String operationType;
+    private String operationContent;
+    private Integer deviceId;
+
+    //鍏宠仈鐨勮〃鍚�
+    private String relevanceForm;
+
+    //鍏宠仈鐨刬d
+    private Integer relevanceId;
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceScrapped.java b/cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceScrapped.java
new file mode 100644
index 0000000..f60aefb
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceScrapped.java
@@ -0,0 +1,105 @@
+package com.ruoyi.device.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 璁惧鎶ュ簾鐢宠琛�
+ * </p>
+ *
+ * @author 姹熻嫃榈烽洀缃戠粶绉戞妧鏈夐檺鍏徃
+ * @since 2024-12-17 01:53:47
+ */
+@Getter
+@Setter
+@TableName("device_scrapped")
+@ApiModel(value = "DeviceScrapped瀵硅薄", description = "璁惧鎶ュ簾鐢宠琛�")
+public class DeviceScrapped {
+
+    @TableId(value = "scrapped_id", type = IdType.AUTO)
+    private Integer scrappedId;
+
+    @ApiModelProperty("璁惧id")
+    private Integer deviceId;
+
+    @ApiModelProperty("閰嶄欢")
+    private String parts;
+
+    @ApiModelProperty("鎶ュ簾鐞嗙敱")
+    private String reasonsForScrap;
+
+    @ApiModelProperty("鐢宠浜篿d")
+    private Integer applicantUserId;
+
+    @ApiModelProperty("鐢宠浜�")
+    private String applicantUser;
+
+    @ApiModelProperty("鐢宠鏃堕棿")
+    private LocalDate applicantDate;
+
+    @ApiModelProperty("閮ㄩ棬璐熻矗浜烘剰瑙�")
+    private String departmentHeadOpinion;
+
+    @ApiModelProperty("閮ㄩ棬璐熻矗浜篿d")
+    private Integer departmentHeadUserId;
+
+    @ApiModelProperty("閮ㄩ棬璐熻矗浜�")
+    private String departmentHeadUser;
+
+    @ApiModelProperty("閮ㄩ棬璐熻矗浜哄~鍐欐椂闂�")
+    private LocalDate departmentHeadDate;
+
+    @ApiModelProperty("璁¢噺瀹ゆ剰瑙�")
+    private String meteringRoomOpinion;
+
+    @ApiModelProperty("璁¢噺瀹や汉id")
+    private Integer meteringRoomUserId;
+
+    @ApiModelProperty("璁¢噺瀹や汉")
+    private String meteringRoomUser;
+
+    @ApiModelProperty("璁¢噺瀹や汉濉啓鏃堕棿")
+    private LocalDate meteringRoomDate;
+
+    @ApiModelProperty("鎵瑰噯浜烘剰瑙�")
+    private String approverOpinion;
+
+    @ApiModelProperty("鎵瑰噯浜篿d")
+    private Integer approverUserId;
+
+    @ApiModelProperty("鎵瑰噯浜�")
+    private String approverUser;
+
+    @ApiModelProperty("鎵瑰噯浜哄~鍐欐椂闂�")
+    private LocalDate approverDate;
+
+    @ApiModelProperty("鏄惁缁撴潫,0: 鏈粨鏉�, 1:缁撴潫")
+    private Integer isFinish;
+
+    @ApiModelProperty("鍒涘缓浜�")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("淇敼浜�")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+
+    @ApiModelProperty("淇敼鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    @TableField(exist = false,select = false)
+    @ApiModelProperty("娴佺▼, 0:鎶ュ簾鐢宠, 1鐢宠閮ㄩ棬璐熻矗浜烘剰瑙�, 2:璁¢噺瀹ゆ剰瑙�, 3:鎵瑰噯浜�")
+    private Integer flowType;
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceState.java b/cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceState.java
new file mode 100644
index 0000000..e212f3e
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/pojo/DeviceState.java
@@ -0,0 +1,107 @@
+package com.ruoyi.device.pojo;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 璁惧鍋滅敤/鍚敤
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2024-09-26 09:51:40
+ */
+@Getter
+@Setter
+@TableName("device_state")
+@ApiModel(value = "DeviceState瀵硅薄", description = "璁惧鍋滅敤/鍚敤")
+public class DeviceState implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("璁惧鍋滅敤鍚敤id")
+    @TableId(value = "state_id", type = IdType.AUTO)
+    private Integer stateId;
+
+    @ApiModelProperty("娴佺▼缂栧彿")
+    private String processNumber;
+
+    @ApiModelProperty("0閰嶄欢")
+    private String accessoryPart;
+
+    @ApiModelProperty("0璁惧鐘舵��")
+    private String deviceStatus;
+
+    @ApiModelProperty("0鍋滅敤鍚敤鐞嗙敱")
+    private String reason;
+
+    @ApiModelProperty("0涓嬬幆鑺傝矗浠讳汉")
+    private String submitNextPesponsible;
+
+    @ApiModelProperty("0鎿嶄綔浜�")
+    private String submitOperatingPersonnel;
+
+    @ApiModelProperty("0鏃ユ湡")
+    private LocalDateTime submitDate;
+
+    @ApiModelProperty("1閮ㄩ棬璐熻矗浜烘剰瑙�")
+    private String departmentReviewOpinion;
+
+    @ApiModelProperty("1涓嬬幆鑺傝矗浠讳汉")
+    private String departmentNextPesponsible;
+
+    @ApiModelProperty("1鎿嶄綔浜�")
+    private String departmentOperatingPersonnel;
+
+    @ApiModelProperty("1鏃ユ湡")
+    private LocalDateTime departmentDate;
+
+    @ApiModelProperty("2璁¢噺瀹ゆ剰瑙�")
+    private String measuringRoomReviewOpinion;
+
+    @ApiModelProperty("2涓嬬幆鑺傝矗浠讳汉")
+    private String measuringRoomNextPesponsible;
+
+    @ApiModelProperty("2鎿嶄綔浜�")
+    private String measuringRoomOperatingPersonnel;
+
+    @ApiModelProperty("2鏃ユ湡")
+    private LocalDateTime measuringRoomDate;
+
+    @ApiModelProperty("3鎵瑰噯鎰忚")
+    private String approvalOpinion;
+
+    @ApiModelProperty("3涓嬬幆鑺傝矗浠讳汉")
+    private String approvalNextPesponsible;
+
+    @ApiModelProperty("3鎿嶄綔浜�")
+    private String approvalOperatingPersonnel;
+
+    @ApiModelProperty("3鏃ユ湡")
+    private LocalDateTime approvalDate;
+
+    @ApiModelProperty("褰撳墠鐘舵��")
+    private String currentState;
+
+    @ApiModelProperty("璁惧Id")
+    private Integer deviceId;
+
+    @ApiModelProperty("褰撳墠鐜妭璐熻矗浜�")
+    private String currentResponsible;
+
+    @ApiModelProperty("鎻愪氦浜�")
+    @ExcelProperty(value = "鎻愪氦浜�")
+    private String createUser;
+
+    @ApiModelProperty("鎻愪氦鏃ユ湡")
+    @ExcelProperty(value = "鎻愪氦鏃ユ湡")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/service/DeviceBorrowService.java b/cnas-device/src/main/java/com/ruoyi/device/service/DeviceBorrowService.java
new file mode 100644
index 0000000..298b03e
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/service/DeviceBorrowService.java
@@ -0,0 +1,28 @@
+package com.ruoyi.device.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.device.pojo.DeviceBorrow;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ *  鏈嶅姟绫�
+ * </p>
+ *
+ * @author 姹熻嫃榈烽洀缃戠粶绉戞妧鏈夐檺鍏徃
+ * @since 2024-09-21 10:53:51
+ */
+public interface DeviceBorrowService extends IService<DeviceBorrow> {
+
+    IPage<DeviceBorrow> deviceBorrowPage(Page page, DeviceBorrow deviceBorrow);
+
+    int saveDeviceBorrow(DeviceBorrow deviceBorrow);
+
+    DeviceBorrow getDeviceBorrow(Integer id);
+
+    List<DeviceBorrow> getDeviceBorrowBydeviceId(Integer deviceId);
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/service/DeviceMaintenanceService.java b/cnas-device/src/main/java/com/ruoyi/device/service/DeviceMaintenanceService.java
new file mode 100644
index 0000000..4883178
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/service/DeviceMaintenanceService.java
@@ -0,0 +1,24 @@
+package com.ruoyi.device.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.device.excel.DeviceMaintenanceExport;
+import com.ruoyi.device.pojo.DeviceMaintenance;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+public interface DeviceMaintenanceService extends IService<DeviceMaintenance> {
+    IPage<DeviceMaintenance> getDeviceMaintenancePage(Page page, Integer deviceId, String deviceNumber);
+
+    List<DeviceMaintenanceExport> deviceMaintenanceExport(Integer deviceId);
+
+    /**
+     * 瀵煎嚭Word璁惧缁存姢璁板綍
+     *
+     * @param deviceId
+     * @param response
+     */
+    void exportMaintenanceRecord(Integer deviceId, HttpServletResponse response);
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/service/DeviceScrappedService.java b/cnas-device/src/main/java/com/ruoyi/device/service/DeviceScrappedService.java
new file mode 100644
index 0000000..71cf704
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/service/DeviceScrappedService.java
@@ -0,0 +1,43 @@
+package com.ruoyi.device.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.common.core.domain.Result;
+import com.ruoyi.device.pojo.DeviceScrapped;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * <p>
+ * 璁惧鎶ュ簾鐢宠琛� 鏈嶅姟绫�
+ * </p>
+ *
+ * @author 姹熻嫃榈烽洀缃戠粶绉戞妧鏈夐檺鍏徃
+ * @since 2024-12-17 01:53:47
+ */
+public interface DeviceScrappedService extends IService<DeviceScrapped> {
+
+    /**
+     * 璁惧鎶ュ簾鐢宠鍒楄〃
+     * @param page
+     * @param deviceScrapped
+     * @return
+     */
+    IPage<DeviceScrapped> pageDeviceScrapped(Page page, DeviceScrapped deviceScrapped);
+
+    /**
+     * 鏂板璁惧鎶ュ簾鐢宠
+     * @param deviceScrapped
+     * @return
+     */
+    boolean addDeviceScrapped(DeviceScrapped deviceScrapped);
+
+    /**
+     * 淇敼璁惧鎶ュ簾鐢宠
+     * @param scrappedId 璁惧鎶ュ簾鐢宠id
+     * @return
+     */
+    Result exportDeviceScrapped(Integer scrappedId, HttpServletResponse response);
+
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/service/DeviceStateService.java b/cnas-device/src/main/java/com/ruoyi/device/service/DeviceStateService.java
new file mode 100644
index 0000000..9a2b789
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/service/DeviceStateService.java
@@ -0,0 +1,31 @@
+package com.ruoyi.device.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.device.dto.DeviceStateDto;
+import com.ruoyi.device.pojo.DeviceState;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * <p>
+ * 璁惧鍋滅敤/鍚敤 鏈嶅姟绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2024-09-26 09:51:40
+ */
+public interface DeviceStateService extends IService<DeviceState> {
+
+    IPage<DeviceStateDto> getDeviceStatePage(Integer deviceId, Page page, String processNumber);
+
+    /**
+     * 瀵煎嚭璁惧鐘舵��
+     *
+     * @param deviceId
+     * @param processNumber
+     * @param response
+     */
+    void exportDeviceStatus(Integer deviceId, String processNumber, HttpServletResponse response);
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceBorrowServiceImpl.java b/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceBorrowServiceImpl.java
new file mode 100644
index 0000000..72023fc
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceBorrowServiceImpl.java
@@ -0,0 +1,116 @@
+package com.ruoyi.device.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.core.domain.entity.User;
+import com.ruoyi.common.numgen.NumberGenerator;
+import com.ruoyi.common.utils.QueryWrappers;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.device.mapper.DeviceBorrowMapper;
+import com.ruoyi.device.mapper.DeviceLogMapper;
+import com.ruoyi.device.pojo.DeviceBorrow;
+import com.ruoyi.device.pojo.DeviceLog;
+import com.ruoyi.device.service.DeviceBorrowService;
+import com.ruoyi.system.mapper.UserMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.util.*;
+
+/**
+ * <p>
+ * 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author 姹熻嫃榈烽洀缃戠粶绉戞妧鏈夐檺鍏徃
+ * @since 2024-09-21 10:53:51
+ */
+@Service
+@Transactional(rollbackFor = Exception.class)
+public class DeviceBorrowServiceImpl extends ServiceImpl<DeviceBorrowMapper, DeviceBorrow> implements DeviceBorrowService {
+
+    @Resource
+    private DeviceBorrowMapper deviceBorrowMapper;
+
+    @Resource
+    private DeviceLogMapper deviceLogMapper;
+
+    @Resource
+    private UserMapper userMapper;
+
+    @Autowired
+    private NumberGenerator<DeviceBorrow> numberGenerator;
+
+    @Override
+    public IPage<DeviceBorrow> deviceBorrowPage(Page page, DeviceBorrow deviceBorrow) {
+        return deviceBorrowMapper.deviceBorrowPage(page, QueryWrappers.queryWrappers(deviceBorrow));
+    }
+
+    @Override
+    public int saveDeviceBorrow(DeviceBorrow deviceBorrow) {
+        Integer userId = SecurityUtils.getUserId().intValue();
+        User user = userMapper.selectById(userId);
+        //鏂板鐨勬椂鍊欐坊鍔犳柊寤烘祦绋�
+        if (ObjectUtils.isEmpty(deviceBorrow.getId())) {
+            deviceBorrow.setSubmitUser(user.getName());
+            String year = new SimpleDateFormat("yy", Locale.CHINESE).format(new Date());
+            String month = new SimpleDateFormat("MM", Locale.CHINESE).format(new Date());
+            String processNumber = numberGenerator.generateNumberWithPrefix(3, "DG-TC-23FM " + month + "-" + year + month, DeviceBorrow::getProcessNumber);
+            deviceBorrow.setProcessNumber(processNumber);
+            deviceBorrowMapper.insert(deviceBorrow);
+            DeviceLog deviceLog = new DeviceLog();
+            deviceLog.setOperator(user.getName());
+            deviceLog.setOperationTime(LocalDateTime.now());
+            deviceLog.setOperationType("鏂板缓");
+            deviceLog.setOperationContent("鏂板缓娴佺▼");
+            deviceLog.setRelevanceForm("device_borrow");
+            deviceLog.setRelevanceId(deviceBorrow.getId());
+            deviceLogMapper.insert(deviceLog);
+        } else {
+            DeviceBorrow borrow = deviceBorrowMapper.selectById(deviceBorrow.getId());
+            deviceBorrowMapper.updateById(deviceBorrow);
+            //閫氳繃鎴栬�呴┏鍥炲鍔犳祦绋嬭窡韪�
+            if (deviceBorrow.getNowState().equals("鍏抽棴")) {
+                DeviceLog deviceLog = new DeviceLog();
+                deviceLog.setOperator(user.getName());
+                deviceLog.setOperationTime(LocalDateTime.now());
+                deviceLog.setOperationType("鎺ユ敹閫氳繃");
+                deviceLog.setRelevanceForm("device_borrow");
+                deviceLog.setRelevanceId(deviceBorrow.getId());
+                deviceLogMapper.insert(deviceLog);
+            }
+            else if (deviceBorrow.getNowState().equals("鎻愪氦") && borrow.getNowState().equals("鎺ユ敹")) {
+                DeviceLog deviceLog = new DeviceLog();
+                deviceLog.setOperator(user.getName());
+                deviceLog.setOperationTime(LocalDateTime.now());
+                deviceLog.setOperationType("鎺ユ敹椹冲洖");
+                deviceLog.setRelevanceForm("device_borrow");
+                deviceLog.setRelevanceId(deviceBorrow.getId());
+                deviceLogMapper.insert(deviceLog);
+            }
+        }
+        return 0;
+    }
+
+    @Override
+    public DeviceBorrow getDeviceBorrow(Integer id) {
+        List<DeviceLog> deviceLogs = deviceLogMapper.selectList(Wrappers.<DeviceLog>lambdaQuery()
+                .eq(DeviceLog::getRelevanceForm, "device_borrow")
+                .eq(DeviceLog::getRelevanceId, id));
+        DeviceBorrow deviceBorrow = deviceBorrowMapper.selectById(id);
+        deviceBorrow.setDeviceLogs(deviceLogs);
+        return deviceBorrow;
+    }
+
+    @Override
+    public List<DeviceBorrow> getDeviceBorrowBydeviceId(Integer deviceId) {
+        return deviceBorrowMapper.getDeviceBorrowBydeviceId(deviceId);
+    }
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceImpl.java b/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceImpl.java
new file mode 100644
index 0000000..3487fc2
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceImpl.java
@@ -0,0 +1,86 @@
+package com.ruoyi.device.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.deepoove.poi.XWPFTemplate;
+import com.deepoove.poi.config.Configure;
+import com.ruoyi.device.excel.DeviceMaintenanceExport;
+import com.ruoyi.device.mapper.DeviceMaintenanceMapper;
+import com.ruoyi.device.mapper.DeviceMapper;
+import com.ruoyi.device.pojo.DeviceMaintenance;
+import com.ruoyi.device.service.DeviceMaintenanceService;
+import com.ruoyi.inspect.util.HackLoopTableRenderPolicy;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.List;
+
+@Service
+public class DeviceMaintenanceImpl extends ServiceImpl<DeviceMaintenanceMapper, DeviceMaintenance> implements DeviceMaintenanceService {
+
+    @Override
+    public IPage<DeviceMaintenance> getDeviceMaintenancePage(Page page, Integer deviceId, String deviceNumber) {
+        return baseMapper.selectPage(page, Wrappers.<DeviceMaintenance>lambdaQuery()
+                .eq(DeviceMaintenance::getDeviceId, deviceId)
+                .like(DeviceMaintenance::getDeviceNumber, deviceNumber));
+    }
+
+    @Override
+    public List<DeviceMaintenanceExport> deviceMaintenanceExport(Integer deviceId) {
+        return baseMapper.deviceMaintenanceExport(deviceId);
+    }
+
+    @Override
+    public void exportMaintenanceRecord(Integer deviceId, HttpServletResponse response) {
+        // 鏌ヨcnas璁惧缁翠慨璁板綍
+        List<DeviceMaintenance> deviceMaintenanceList = baseMapper.selectList(Wrappers.<DeviceMaintenance>lambdaQuery()
+                .eq(DeviceMaintenance::getDeviceId, deviceId)
+                .select(DeviceMaintenance::getDate,
+                        DeviceMaintenance::getDeviceNumber,
+                        DeviceMaintenance::getDeviceName,
+                        DeviceMaintenance::getManagementNumber,
+                        DeviceMaintenance::getContent,
+                        DeviceMaintenance::getName,
+                        DeviceMaintenance::getComments));
+
+
+        // 鑾峰彇璺緞
+        InputStream inputStream = this.getClass().getResourceAsStream("/static/word/maintenance-records.docx");
+        Configure configure = Configure.builder()
+                .bind("deviceMaintenanceList", new HackLoopTableRenderPolicy())
+                .build();
+        // 鑾峰彇璁惧 鍚嶇О 鍜� 缂栧彿
+        DeviceMaintenance deviceMaintenance = deviceMaintenanceList.get(0);
+        String deviceName = deviceMaintenance.getDeviceName();
+        String managementNumber = deviceMaintenance.getManagementNumber();
+        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
+                new HashMap<String, Object>() {{
+                    put("deviceMaintenanceList", deviceMaintenanceList);
+                    put("deviceName", deviceName);
+                    put("managementNumber", managementNumber);
+                }});
+
+        try {
+            response.setContentType("application/msword");
+            String fileName = URLEncoder.encode(
+                    "璁惧缁存姢淇濆吇璁板綍", "UTF-8");
+            response.setHeader("Content-disposition",
+                    "attachment;filename=" + fileName + ".docx");
+            OutputStream os = response.getOutputStream();
+            template.write(os);
+            os.flush();
+            os.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("瀵煎嚭澶辫触");
+        }
+    }
+
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceScrappedServiceImpl.java b/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceScrappedServiceImpl.java
new file mode 100644
index 0000000..910617a
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceScrappedServiceImpl.java
@@ -0,0 +1,179 @@
+package com.ruoyi.device.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.deepoove.poi.XWPFTemplate;
+import com.deepoove.poi.config.Configure;
+import com.ruoyi.common.core.domain.Result;
+import com.ruoyi.common.core.domain.entity.User;
+import com.ruoyi.common.utils.QueryWrappers;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.device.dto.DeviceScrappedDto;
+import com.ruoyi.device.mapper.DeviceMapper;
+import com.ruoyi.device.mapper.DeviceScrappedMapper;
+import com.ruoyi.device.pojo.Device;
+import com.ruoyi.device.pojo.DeviceScrapped;
+import com.ruoyi.device.service.DeviceScrappedService;
+import com.ruoyi.inspect.util.UserUtils;
+import com.ruoyi.system.mapper.UserMapper;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.time.LocalDate;
+import java.util.HashMap;
+
+/**
+ * <p>
+ * 璁惧鎶ュ簾鐢宠琛� 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author 姹熻嫃榈烽洀缃戠粶绉戞妧鏈夐檺鍏徃
+ * @since 2024-12-17 01:53:47
+ */
+@Service
+public class DeviceScrappedServiceImpl extends ServiceImpl<DeviceScrappedMapper, DeviceScrapped> implements DeviceScrappedService {
+
+    @Resource
+    private DeviceMapper deivceMapper;
+    @Resource
+    private UserMapper userMapper;
+
+
+    /**
+     * 璁惧鎶ュ簾鐢宠鍒楄〃
+     *
+     * @param deviceScrapped
+     * @return
+     */
+    @Override
+    public IPage<DeviceScrapped> pageDeviceScrapped(Page page, DeviceScrapped deviceScrapped) {
+        return baseMapper.pageDeviceScrapped(page, QueryWrappers.queryWrappers(deviceScrapped));
+    }
+
+    /**
+     * 鏂板璁惧鎶ュ簾鐢宠
+     *
+     * @return
+     */
+    @Override
+    public boolean addDeviceScrapped(DeviceScrapped deviceScrapped) {
+        DeviceScrapped scrapped = new DeviceScrapped();
+        // 褰撳墠鐧诲綍鐢ㄦ埛淇℃伅鍜岄儴闂�
+        User user = userMapper.selectById(SecurityUtils.getUserId().intValue());
+        switch (deviceScrapped.getFlowType()) {
+            case 0:
+                BeanUtils.copyProperties(deviceScrapped, scrapped);
+                // 鐢宠
+                scrapped.setReasonsForScrap(deviceScrapped.getReasonsForScrap());
+                scrapped.setApplicantUserId(user.getId());
+                scrapped.setApplicantUser(user.getName());
+                scrapped.setApplicantDate(LocalDate.now());
+
+                // 澶勭悊浜轰俊鎭�
+                User departmentHeadUser = userMapper.selectById(deviceScrapped.getDepartmentHeadUserId());
+                scrapped.setApplicantUserId(departmentHeadUser.getId());
+                scrapped.setApplicantUser(departmentHeadUser.getName());
+
+                baseMapper.insert(scrapped);
+                break;
+            case 1:
+                scrapped.setScrappedId(deviceScrapped.getScrappedId());
+                // 鐢宠閮ㄩ棬璐熻矗浜烘剰瑙�
+                scrapped.setDepartmentHeadOpinion(deviceScrapped.getDepartmentHeadOpinion());
+                scrapped.setDepartmentHeadDate(LocalDate.now());
+
+                // 璁¢噺瀹や俊鎭�
+                User meteringRoomUser = userMapper.selectById(deviceScrapped.getMeteringRoomUserId());
+                scrapped.setMeteringRoomUserId(meteringRoomUser.getId());
+                scrapped.setMeteringRoomUser(meteringRoomUser.getName());
+
+                baseMapper.updateById(scrapped);
+                break;
+            case 2:
+                scrapped.setScrappedId(deviceScrapped.getScrappedId());
+                // 璁¢噺瀹ゆ剰瑙�
+                scrapped.setMeteringRoomOpinion(deviceScrapped.getMeteringRoomOpinion());
+                scrapped.setMeteringRoomDate(LocalDate.now());
+
+                // 鎵瑰噯浜轰俊鎭�
+                User approverUser = userMapper.selectById(deviceScrapped.getApproverUserId());
+                scrapped.setApproverUserId(approverUser.getId());
+                scrapped.setApproverUser(approverUser.getName());
+
+                baseMapper.updateById(scrapped);
+                break;
+            case 3:
+                scrapped.setScrappedId(deviceScrapped.getScrappedId());
+                //鎵瑰噯浜�
+                scrapped.setApproverOpinion(deviceScrapped.getApproverOpinion());
+                scrapped.setApproverDate(LocalDate.now());
+                scrapped.setIsFinish(1);
+                baseMapper.updateById(scrapped);
+                break;
+        }
+
+        return true;
+    }
+
+    /**
+     * 瀵煎嚭璁惧鎶ュ簾鐢宠
+     *
+     * @param scrappedId 璁惧鎶ュ簾鐢宠id
+     * @param response   鍝嶅簲
+     * @return 缁撴灉
+     */
+    @Override
+    public Result<?> exportDeviceScrapped(Integer scrappedId, HttpServletResponse response) {
+        // 鏌ヨ鎶ュ簾鏁版嵁
+        DeviceScrappedDto deviceScrapped = baseMapper.selectDeviceScrappedById(scrappedId);
+        if (deviceScrapped == null) {
+            return Result.fail("璁惧鎶ュ簾鐢宠涓嶅瓨鍦�");
+        }
+        Device device = null;
+        if (deviceScrapped.getDeviceId() != null) {
+            device = deivceMapper.selectById(deviceScrapped.getDeviceId());
+            device = device == null ? new Device() : device;
+        }
+        // 鑾峰彇璺緞
+        InputStream inputStream = this.getClass().getResourceAsStream("/static/word/device-scrapped.docx");
+        Configure configure = Configure.builder()
+                .build();
+        Device finalDevice = device;
+        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
+                new HashMap<String, Object>() {{
+                    put("deviceScrapped", deviceScrapped);
+                    put("device", finalDevice);
+                    // 鐢宠浜虹鍚�
+                    put("applicantUrl", UserUtils.getFinalUserSignatureUrl(deviceScrapped.getApplicantUserId()));
+                    // 閮ㄩ棬璐熻矗浜虹鍚�
+                    put("headUrl", UserUtils.getFinalUserSignatureUrl(deviceScrapped.getDepartmentHeadUserId()));
+                    // 璁¢噺瀹ょ鍚�
+                    put("metrologyRoomUrl", UserUtils.getFinalUserSignatureUrl(deviceScrapped.getMeteringRoomUserId()));
+                    // 鎵瑰噯浜虹鍚�
+                    put("approverUrl", UserUtils.getFinalUserSignatureUrl(deviceScrapped.getApproverUserId()));
+                }});
+
+        try {
+            response.setContentType("application/msword");
+            String deviceName = device.getDeviceName() == null ? "" : device.getDeviceName();
+            String fileName = URLEncoder.encode(
+                    deviceName + "璁惧鎶ュ簾鐢宠", "UTF-8");
+            response.setHeader("Content-disposition",
+                    "attachment;filename=" + fileName + ".docx");
+            OutputStream os = response.getOutputStream();
+            template.write(os);
+            os.flush();
+            os.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("瀵煎嚭澶辫触");
+        }
+        return Result.success();
+    }
+}
diff --git a/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceStateServiceImpl.java b/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceStateServiceImpl.java
new file mode 100644
index 0000000..f4f7c5a
--- /dev/null
+++ b/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceStateServiceImpl.java
@@ -0,0 +1,159 @@
+package com.ruoyi.device.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.deepoove.poi.XWPFTemplate;
+import com.deepoove.poi.config.Configure;
+import com.deepoove.poi.data.Pictures;
+import com.ruoyi.basic.mapper.LaboratoryMapper;
+import com.ruoyi.basic.pojo.Laboratory;
+import com.ruoyi.common.core.domain.entity.User;
+import com.ruoyi.device.dto.DeviceStateDto;
+import com.ruoyi.device.mapper.DeviceStateMapper;
+import com.ruoyi.device.pojo.DeviceState;
+import com.ruoyi.device.service.DeviceStateService;
+import com.ruoyi.framework.exception.ErrorException;
+import com.ruoyi.system.mapper.UserMapper;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+
+/**
+ * <p>
+ * 璁惧鍋滅敤/鍚敤 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2024-09-26 09:51:40
+ */
+@Service
+public class DeviceStateServiceImpl extends ServiceImpl<DeviceStateMapper, DeviceState> implements DeviceStateService {
+
+    @Resource
+    private LaboratoryMapper laboratoryMapper;
+
+    @Resource
+    private UserMapper userMapper;
+
+    @Value("${file.path}")
+    private String imgUrl;
+
+    @Override
+    public IPage<DeviceStateDto> getDeviceStatePage(Integer deviceId, Page page, String processNumber) {
+        return baseMapper.getDeviceStatePage(deviceId, page, processNumber);
+    }
+
+    @Override
+    public void exportDeviceStatus(Integer deviceId, String processNumber, HttpServletResponse response) {
+        // 鏍规嵁娴佺▼缂栧彿 鏌ヨcnas璁惧鐘舵��
+        DeviceStateDto deviceStateDto = baseMapper.getDeviceStatePage(deviceId,new Page<DeviceStateDto>(1,1), processNumber).getRecords().get(0);
+
+        // 瀵规椂闂磋繘琛屼慨鏀�
+        DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy骞碝M鏈坉d鏃�");
+        deviceStateDto.setSubmitDateString(deviceStateDto.getSubmitDate() != null ? deviceStateDto.getSubmitDate().format(format) : "  骞� 鏈� 鏃�");
+        deviceStateDto.setDepartmentDateString(deviceStateDto.getDepartmentDate() != null? deviceStateDto.getDepartmentDate().format(format) : "  骞� 鏈� 鏃�");
+        deviceStateDto.setMeasuringRoomDateString(deviceStateDto.getMeasuringRoomDate() != null? deviceStateDto.getMeasuringRoomDate().format(format) : "  骞� 鏈� 鏃�");
+        deviceStateDto.setApprovalDateString(deviceStateDto.getApprovalDate() != null? deviceStateDto.getApprovalDate().format(format) : "  骞� 鏈� 鏃�");
+
+        // 鏌ヨ璁惧灞炰簬鍝釜瀹為獙瀹�
+        String laboratoryName;
+        String largeCategory = deviceStateDto.getLargeCategory();
+        if (StringUtils.isNotBlank(largeCategory)) {
+            largeCategory = largeCategory.substring(0, 1);
+            Laboratory laboratory = laboratoryMapper.selectOne(Wrappers.<Laboratory>lambdaQuery()
+                    .eq(Laboratory::getLaboratoryNumber, largeCategory)
+                    .select(Laboratory::getLaboratoryName));
+            laboratoryName = laboratory.getLaboratoryName();
+        } else {
+            laboratoryName = "";
+        }
+
+        //todo: 璁惧鐘舵�佹煡璇㈢鍚嶅湴鍧� 鏆傛椂浜哄悕鏌ヨ
+        //鑾峰彇鐢宠浜虹殑绛惧悕鍦板潃
+        String applicantUrl = null;
+        if (deviceStateDto.getSubmitOperatingPersonnel() != null) {
+            applicantUrl = userMapper.selectOne(Wrappers.<User>lambdaQuery()
+                            .eq(User::getName, deviceStateDto.getSubmitOperatingPersonnel()))
+                    .getSignatureUrl();
+            if (StringUtils.isBlank(applicantUrl)) {
+                throw new ErrorException("鎵句笉鍒扮敵璇蜂汉鐨勭鍚�");
+            }
+        }
+
+        //鑾峰彇閮ㄩ棬璐熻矗浜虹殑绛惧悕鍦板潃
+        String headOfDepartmentUrl = null;
+        if (deviceStateDto.getDepartmentNextPesponsible() != null) {
+            headOfDepartmentUrl = userMapper.selectOne(Wrappers.<User>lambdaQuery()
+                    .eq(User::getName, deviceStateDto.getDepartmentNextPesponsible()))
+                    .getSignatureUrl();
+            if (StringUtils.isBlank(headOfDepartmentUrl)) {
+                throw new ErrorException("鎵句笉鍒伴儴闂ㄨ礋璐d汉鐨勭鍚�");
+            }
+        }
+
+        //鑾峰彇璁¢噺瀹ゅ娴嬩汉鐨勭鍚嶅湴鍧�
+        String measurementRoomUrl = null;
+        if (deviceStateDto.getMeasuringRoomNextPesponsible() != null) {
+            measurementRoomUrl = userMapper.selectOne(Wrappers.<User>lambdaQuery()
+                            .eq(User::getName, deviceStateDto.getMeasuringRoomNextPesponsible()))
+                    .getSignatureUrl();
+            if (StringUtils.isBlank(measurementRoomUrl)) {
+                throw new ErrorException("鎵句笉鍒拌閲忓澶嶆祴浜虹殑绛惧悕");
+            }
+        }
+
+        //鑾峰彇鎵瑰噯浜虹殑绛惧悕鍦板潃
+        String approvedUrl = null;
+        if (deviceStateDto.getApprovalNextPesponsible() != null) {
+            approvedUrl = userMapper.selectOne(Wrappers.<User>lambdaQuery()
+                            .eq(User::getName, deviceStateDto.getApprovalNextPesponsible()))
+                    .getSignatureUrl();
+            if (StringUtils.isBlank(approvedUrl)) {
+                throw new ErrorException("鎵句笉鍒版壒鍑嗕汉鐨勭鍚�");
+            }
+        }
+
+        // 鑾峰彇璺緞
+        InputStream inputStream = this.getClass().getResourceAsStream("/static/word/device-status.docx");
+        Configure configure = Configure.builder()
+                .build();
+        String finalApplicantUrl = applicantUrl; // 鐢宠浜虹殑绛惧悕鍦板潃
+        String finalHeadOfDepartmentUrl = headOfDepartmentUrl; // 閮ㄩ棬璐熻矗浜虹殑绛惧悕鍦板潃
+        String finalMeasurementRoomUrl = measurementRoomUrl; // 璁¢噺瀹ゅ娴嬩汉鐨勭鍚嶅湴鍧�
+        String finalApprovedUrl = approvedUrl; // 鎵瑰噯浜虹殑绛惧悕鍦板潃
+        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
+                new HashMap<String, Object>() {{
+                    put("deviceStateDto", deviceStateDto);
+                    put("submitOperatingPersonnelUrl", StringUtils.isNotBlank(finalApplicantUrl) ? Pictures.ofLocal(imgUrl + "/" + finalApplicantUrl).create() : null);
+                    put("departmentNextPesponsibleUrl", StringUtils.isNotBlank(finalHeadOfDepartmentUrl) ? Pictures.ofLocal(imgUrl + "/" + finalHeadOfDepartmentUrl).create() : null);
+                    put("measuringRoomNextPesponsibleUrl", StringUtils.isNotBlank(finalMeasurementRoomUrl) ? Pictures.ofLocal(imgUrl + "/" + finalMeasurementRoomUrl).create() : null);
+                    put("approvalNextPesponsibleUrl", StringUtils.isNotBlank(finalApprovedUrl) ? Pictures.ofLocal(imgUrl + "/" + finalApprovedUrl).create() : null);
+                    put("laboratory", laboratoryName);
+                }});
+
+        try {
+            response.setContentType("application/msword");
+            String fileName = URLEncoder.encode(
+                    "璁惧缁存姢淇濆吇璁板綍", "UTF-8");
+            response.setHeader("Content-disposition",
+                    "attachment;filename=" + fileName + ".docx");
+            OutputStream os = response.getOutputStream();
+            template.write(os);
+            os.flush();
+            os.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("瀵煎嚭澶辫触");
+        }
+    }
+}
diff --git a/cnas-device/src/main/resources/mapper/DeviceBorrowMapper.xml b/cnas-device/src/main/resources/mapper/DeviceBorrowMapper.xml
new file mode 100644
index 0000000..bb2454d
--- /dev/null
+++ b/cnas-device/src/main/resources/mapper/DeviceBorrowMapper.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.device.mapper.DeviceBorrowMapper">
+
+    <select id="deviceBorrowPage" resultType="com.ruoyi.device.pojo.DeviceBorrow">
+        select * from (
+        select db.*,device_name
+        from device_borrow db
+        left join `center-lims`.device on db.device_id=device.id
+        )a
+        <if test="ew.customSqlSegment != null and ew.customSqlSegment != ''">
+            ${ew.customSqlSegment}
+        </if>
+    </select>
+    <select id="getDeviceBorrowBydeviceId" resultType="com.ruoyi.device.pojo.DeviceBorrow">
+        select db.*,device_name
+        from device_borrow db
+                 left join `center-lims`.device on db.device_id=device.id
+        where device_id=#{deviceId}
+    </select>
+</mapper>
diff --git a/cnas-device/src/main/resources/mapper/DeviceScrappedMapper.xml b/cnas-device/src/main/resources/mapper/DeviceScrappedMapper.xml
new file mode 100644
index 0000000..9bc7595
--- /dev/null
+++ b/cnas-device/src/main/resources/mapper/DeviceScrappedMapper.xml
@@ -0,0 +1,27 @@
+<?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.ruoyi.device.mapper.DeviceScrappedMapper">
+
+    <!-- 璁惧鎶ュ簾鐢宠鍒楄〃 -->
+    <select id="pageDeviceScrapped" resultType="com.ruoyi.device.pojo.DeviceScrapped">
+        select * from (
+        select *
+        from device_scrapped
+        order by create_time desc
+        ) a
+        <if test="ew.customSqlSegment != null and ew.customSqlSegment != ''">
+            ${ew.customSqlSegment}
+        </if>
+    </select>
+    <select id="selectDeviceScrappedById" resultType="com.ruoyi.device.dto.DeviceScrappedDto">
+        select
+            *,
+            date_format(applicant_date,'%Y骞�%m鏈�%d鏃�') as applicantDateStr,
+            date_format(department_head_date,'%Y骞�%m鏈�%d鏃�') as departmentHeadDateStr,
+            date_format(metering_room_date,'%Y骞�%m鏈�%d鏃�') as meteringRoomDateStr,
+            date_format(approver_date,'%Y骞�%m鏈�%d鏃�') as approverDateStr
+        from device_scrapped
+        where scrapped_id = #{scrappedId}
+    </select>
+
+</mapper>
diff --git a/cnas-device/src/main/resources/mapper/DeviceStateMapper.xml b/cnas-device/src/main/resources/mapper/DeviceStateMapper.xml
new file mode 100644
index 0000000..3423111
--- /dev/null
+++ b/cnas-device/src/main/resources/mapper/DeviceStateMapper.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.ruoyi.device.mapper.DeviceStateMapper">
+
+
+    <select id="getDeviceStatePage" resultType="com.ruoyi.device.dto.DeviceStateDto">
+        select ds.*,
+               d.device_name,
+               d.management_number,
+               d.specification_model,
+               d.large_category
+        from device_state ds
+                 left join device d on d.id = ds.device_id
+        where ds.device_id = #{deviceId}
+        <if test="processNumber != '' and processNumber != null">
+            and ds.process_number like concat('%', #{processNumber}, '%')
+        </if>
+    </select>
+</mapper>
diff --git a/cnas-device/src/main/resources/static/word/acceptance-certificate.docx b/cnas-device/src/main/resources/static/word/acceptance-certificate.docx
new file mode 100644
index 0000000..c4412dd
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/acceptance-certificate.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/device-accident-report.docx b/cnas-device/src/main/resources/static/word/device-accident-report.docx
new file mode 100644
index 0000000..6263ba9
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/device-accident-report.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/device-breakdown-maintenance.docx b/cnas-device/src/main/resources/static/word/device-breakdown-maintenance.docx
new file mode 100644
index 0000000..595edc5
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/device-breakdown-maintenance.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/device-calibration-plan.docx b/cnas-device/src/main/resources/static/word/device-calibration-plan.docx
new file mode 100644
index 0000000..4f4e6ff
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/device-calibration-plan.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/device-document.docx b/cnas-device/src/main/resources/static/word/device-document.docx
new file mode 100644
index 0000000..d9e1d51
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/device-document.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/device-external-apply.docx b/cnas-device/src/main/resources/static/word/device-external-apply.docx
new file mode 100644
index 0000000..8df765b
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/device-external-apply.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/device-inspection-record.docx b/cnas-device/src/main/resources/static/word/device-inspection-record.docx
new file mode 100644
index 0000000..2c7a4f4
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/device-inspection-record.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/device-scrapped.docx b/cnas-device/src/main/resources/static/word/device-scrapped.docx
new file mode 100644
index 0000000..96dfdd8
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/device-scrapped.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/device-status.docx b/cnas-device/src/main/resources/static/word/device-status.docx
new file mode 100644
index 0000000..5753f22
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/device-status.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/examine-plan-detail.docx b/cnas-device/src/main/resources/static/word/examine-plan-detail.docx
new file mode 100644
index 0000000..118c324
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/examine-plan-detail.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/examine-record.docx b/cnas-device/src/main/resources/static/word/examine-record.docx
new file mode 100644
index 0000000..2462971
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/examine-record.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/incident-report.docx b/cnas-device/src/main/resources/static/word/incident-report.docx
new file mode 100644
index 0000000..c190287
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/incident-report.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/maintenance-plan.docx b/cnas-device/src/main/resources/static/word/maintenance-plan.docx
new file mode 100644
index 0000000..d4e69a0
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/maintenance-plan.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/maintenance-records.docx b/cnas-device/src/main/resources/static/word/maintenance-records.docx
new file mode 100644
index 0000000..ba8c9f8
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/maintenance-records.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/quipment-details.docx b/cnas-device/src/main/resources/static/word/quipment-details.docx
new file mode 100644
index 0000000..d244180
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/quipment-details.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/review-examine-record-contrast.docx b/cnas-device/src/main/resources/static/word/review-examine-record-contrast.docx
new file mode 100644
index 0000000..dd48c97
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/review-examine-record-contrast.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/traceability-management-details.docx b/cnas-device/src/main/resources/static/word/traceability-management-details.docx
new file mode 100644
index 0000000..cb6d3b9
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/traceability-management-details.docx
Binary files differ
diff --git a/cnas-device/src/main/resources/static/word/use-record.docx b/cnas-device/src/main/resources/static/word/use-record.docx
new file mode 100644
index 0000000..236e645
--- /dev/null
+++ b/cnas-device/src/main/resources/static/word/use-record.docx
Binary files differ

--
Gitblit v1.9.3