Ver código fonte

ly eoeg员工 可靠性测厚和优化

ly 2 dias atrás
pai
commit
29ad3a4b0e
30 arquivos alterados com 1835 adições e 165 exclusões
  1. 0 69
      master/src/main/java/com/ruoyi/project/eoeg/controller/TEoegStaffmgrController.java
  2. 0 9
      master/src/main/java/com/ruoyi/project/eoeg/mapper/TEoegStaffmgrMapper.java
  3. 119 0
      master/src/main/java/com/ruoyi/project/production/controller/ApiTester.java
  4. 201 0
      master/src/main/java/com/ruoyi/project/production/domain/TLimsData.java
  5. 1 1
      master/src/main/java/com/ruoyi/project/reliability/controller/TRelCompoController.java
  6. 3 3
      master/src/main/java/com/ruoyi/project/reliability/controller/TRelDeviceController.java
  7. 1 1
      master/src/main/java/com/ruoyi/project/reliability/controller/TRelMaintPlanController.java
  8. 110 8
      master/src/main/java/com/ruoyi/project/reliability/controller/TRelMaintRecordController.java
  9. 81 0
      master/src/main/java/com/ruoyi/project/reliability/controller/TRelThicknessController.java
  10. 13 0
      master/src/main/java/com/ruoyi/project/reliability/domain/TRelCompo.java
  11. 14 0
      master/src/main/java/com/ruoyi/project/reliability/domain/TRelMaintRecord.java
  12. 230 0
      master/src/main/java/com/ruoyi/project/reliability/domain/TRelThickness.java
  13. 28 0
      master/src/main/java/com/ruoyi/project/reliability/mapper/TRelThicknessMapper.java
  14. 1 2
      master/src/main/java/com/ruoyi/project/reliability/service/ITRelMaintPlanService.java
  15. 28 0
      master/src/main/java/com/ruoyi/project/reliability/service/ITRelThicknessService.java
  16. 54 3
      master/src/main/java/com/ruoyi/project/reliability/service/impl/TRelCompoServiceImpl.java
  17. 13 1
      master/src/main/java/com/ruoyi/project/reliability/service/impl/TRelDeviceServiceImpl.java
  18. 45 4
      master/src/main/java/com/ruoyi/project/reliability/service/impl/TRelMaintPlanServiceImpl.java
  19. 47 1
      master/src/main/java/com/ruoyi/project/reliability/service/impl/TRelMaintRecordServiceImpl.java
  20. 77 0
      master/src/main/java/com/ruoyi/project/reliability/service/impl/TRelThicknessServiceImpl.java
  21. 8 1
      master/src/main/resources/mybatis/reliability/TRelMaintRecordMapper.xml
  22. 167 0
      master/src/main/resources/mybatis/reliability/TRelThicknessMapper.xml
  23. 8 0
      ui/src/api/reliability/rel_maint_record.js
  24. 2 2
      ui/src/views/login.vue
  25. 69 31
      ui/src/views/reliability/rel_compo/index.vue
  26. 51 1
      ui/src/views/reliability/rel_device/detail.vue
  27. 6 1
      ui/src/views/reliability/rel_maint_plan/form.vue
  28. 12 4
      ui/src/views/reliability/rel_maint_plan/index.vue
  29. 291 21
      ui/src/views/reliability/rel_maint_record/index.vue
  30. 155 2
      ui/src/views/reliability/rel_maint_record/myRecord.vue

+ 0 - 69
master/src/main/java/com/ruoyi/project/eoeg/controller/TEoegStaffmgrController.java

@@ -903,47 +903,6 @@ public class TEoegStaffmgrController extends BaseController {
         if (old.getDeptId() != 103) { //非bcc
             return toAjax(tStaffmgrService.updateTStaffmgr(tStaffmgr));
         }
-        //
-        TTrainingbccRegular regular = new TTrainingbccRegular();
-        regular.setActualpostId(tStaffmgr.getActualpost());
-        regular.setYear(String.valueOf(LocalDate.now().getYear()));
-        List<TTrainingbccRegular> regularList = tTrainingbccRegularService.selectTTrainingbccRegularList(regular);
-        for (TTrainingbccRegular r: regularList
-             ) {
-            TTrainingbccDevice bccDevice = new TTrainingbccDevice();
-            bccDevice.setStaffId(String.valueOf(tStaffmgr.getId()));
-            bccDevice.setRegularId(r.getId());
-            List<TTrainingbccDevice> deviceList = tTrainingbccDeviceMapper.selectTTrainingbccDeviceByReguar(bccDevice);
-            if (deviceList.size() == 0) { //新岗位需要培训
-                TTrainingbcc tTrainingbcc = new TTrainingbcc();
-                tTrainingbcc.setRegularId(r.getId());
-                List<TTrainingbcc> tTrainingbccList = trainingbccService.selectTTrainingbccList(tTrainingbcc);
-                if (tTrainingbccList.size() > 0) {
-                    TTrainingbcc t = tTrainingbccList.get(0);
-                    // 获取课程结束时间
-                    Date endDate = t.getCourseEnddate();
-                    // 获取当前时间
-                    Date now = new Date();
-                    if (endDate == null || endDate.after(now)) {
-                        System.out.println("课程未结束");
-                        TTrainingbccDevice tTrainingDevice = new TTrainingbccDevice();
-                        tTrainingDevice.setStaffId(old.getStaffid());
-                        tTrainingDevice.setRegularId(t.getId());
-                        tTrainingDevice.setStartDate(t.getCourseStartdate());
-                        tTrainingDevice.setSupplementary("0");
-                        trainingbccDeviceService.insertTTrainingbccDevice(tTrainingDevice);
-                    } else {
-                        System.out.println("课程已结束");
-                        TTrainingbccDevice tTrainingDevice = new TTrainingbccDevice();
-                        tTrainingDevice.setStaffId(old.getStaffid());
-                        tTrainingDevice.setRegularId(t.getId());
-                        tTrainingDevice.setStartDate(t.getCourseStartdate());
-                        tTrainingDevice.setSupplementary("1");
-                        trainingbccDeviceService.insertTTrainingbccDevice(tTrainingDevice);
-                    }
-                }
-            }
-        }
 
         return toAjax(tStaffmgrService.updateTStaffmgr(tStaffmgr));
     }
@@ -955,34 +914,6 @@ public class TEoegStaffmgrController extends BaseController {
     @Log(title = "人员管理", businessType = BusinessType.DELETE)
     @DeleteMapping("/{ids}")
     public AjaxResult remove(@PathVariable Long[] ids) {
-        for (int i = 0; i < ids.length; i++) {
-            TTrainingrecords tTrainingrecords = tTrainingrecordsService.selectTTrainingrecordsBystaffId(ids[i]);
-            if (tTrainingrecords != null) {
-                tTrainingrecords.setDelFlag(2l);
-                tTrainingrecordsService.updateTTrainingrecords(tTrainingrecords);
-            }
-            TEoegStaffmgr staffmgr = tStaffmgrService.selectTStaffmgrById(ids[i]);
-            TTrainingDevice device = new TTrainingDevice();
-            device.setStaffId(staffmgr.getStaffid());
-            List<TTrainingDevice> devices = tTrainingDeviceService.selectTTrainingDeviceList(device);
-            if (devices.size() != 0) {
-                Long[] devicesIds = new Long[devices.size()];
-                for (int m = 0; m < devices.size(); m++) {
-                    devicesIds[m] = devices.get(m).getId();
-                }
-                tTrainingDeviceService.deleteTTrainingDeviceByIds(devicesIds);
-            }
-            TTrainingNon non = new TTrainingNon();
-            non.setStaffId(staffmgr.getStaffid());
-            List<TTrainingNon> nons = tTrainingNonService.selectTTrainingNonList(non);
-            if (nons.size() != 0) {
-                Long[] nonIds = new Long[nons.size()];
-                for (int n = 0; n < nons.size(); n++) {
-                    nonIds[n] = nons.get(n).getId();
-                }
-                tTrainingNonService.deleteTTrainingNonByIds(nonIds);
-            }
-        }
         return toAjax(tStaffmgrService.deleteTStaffmgrByIds(ids));
     }
 

+ 0 - 9
master/src/main/java/com/ruoyi/project/eoeg/mapper/TEoegStaffmgrMapper.java

@@ -97,7 +97,6 @@ public interface TEoegStaffmgrMapper
      */
     public List<TEoegStaffmgr> selectTStaffmgrListByDeptId(TEoegStaffmgr tStaffmgr);
 
-    @DataScope(deptAlias = "d")
     public List<TEoegStaffmgr> selectAllTStaffmgrList(TEoegStaffmgr tStaffmgr);
 
     /**
@@ -124,7 +123,6 @@ public interface TEoegStaffmgrMapper
      * @param tStaffmgr 人员管理
      * @return 人员管理集合
      */
-    @DataScope(deptAlias = "d")
     public List<TEoegStaffmgr> selectList(TEoegStaffmgr tStaffmgr);
 
     List<TEoegStaffmgr> selectTaskList(TEoegStaffmgr tStaffmgr);
@@ -134,7 +132,6 @@ public interface TEoegStaffmgrMapper
      * @param tStaffmgr 人员管理
      * @return 人员管理集合
      */
-    @DataScope(deptAlias = "d")
     public List<TEoegStaffmgr> selectRecordList(TEoegStaffmgr tStaffmgr);
 
     /**
@@ -169,19 +166,14 @@ public interface TEoegStaffmgrMapper
      */
     public int deleteTStaffmgrByIds(Long[] ids);
 
-    @DataScope(deptAlias = "d")
     List<DataEntity> selectEduData(TEoegStaffmgr param);
 
-    @DataScope(deptAlias = "d")
     List<DataEntity> selectEngData(TEoegStaffmgr param);
 
-    @DataScope(deptAlias = "d")
     List<DataEntity> selectTeamData(TEoegStaffmgr param);
 
-    @DataScope(deptAlias = "d")
     List<DataEntity> selectAgeData(TEoegStaffmgr param);
 
-    @DataScope(deptAlias = "d")
     List<TEoegStaffmgr> selectLeftTStaffmgrList(TEoegStaffmgr tStaffmgr);
 
 
@@ -191,7 +183,6 @@ public interface TEoegStaffmgrMapper
     List<TEoegStaffmgr> selectTStaffmgrByPost(SysUser sysUser);
 
     List<TEoegStaffmgr> selectTMentorStaffmgrByPost(SysUser sysUser);
-    @DataScope(deptAlias = "d")
     List<TEoegStaffmgr> selectUserInfoByStaffmgr(TEoegStaffmgr tStaffmgr);
 
     int deleteRetireTStaffmgrByIds(Long id);

+ 119 - 0
master/src/main/java/com/ruoyi/project/production/controller/ApiTester.java

@@ -0,0 +1,119 @@
+package com.ruoyi.project.production.controller;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.apache.http.util.EntityUtils;
+
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+
+/**
+ * 简化的API测试工具类
+ * 用于测试GET接口
+ */
+public class ApiTester {
+
+    private static final String API_URL = "https://reportserver.basf-ypc.net.cn:3061/api/query";
+    private static final String USERNAME = "LIMSData_CPMS";
+    private static final String PASSWORD = "G6j!8Op$7s#Y2aB";
+
+    /**
+     * 创建忽略SSL证书验证的HTTP客户端
+     * @return HttpClient
+     */
+    private static HttpClient createHttpClient() {
+        try {
+            // 创建信任所有证书的SSL上下文
+            SSLContext sslContext = SSLContextBuilder.create()
+                    .loadTrustMaterial(null, (chain, authType) -> true)
+                    .build();
+
+            // 创建SSL连接工厂,忽略主机名验证
+            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
+                    sslContext,
+                    NoopHostnameVerifier.INSTANCE
+            );
+
+            // 创建HTTP客户端
+            return HttpClients.custom()
+                    .setSSLSocketFactory(sslConnectionSocketFactory)
+                    .build();
+
+        } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
+            System.err.println("创建HTTP客户端失败: " + e.getMessage());
+            e.printStackTrace();
+            // 如果创建失败,返回默认的HTTP客户端
+            return HttpClients.createDefault();
+        }
+    }
+
+    /**
+     * 测试API接口 - 简单的GET请求
+     */
+    public static void testApi() {
+        System.out.println("=== API接口测试 ===");
+        System.out.println("接口地址: " + API_URL);
+        System.out.println("请求方法: GET");
+        System.out.println("==========================================");
+
+        try {
+            // 创建忽略SSL证书的HTTP客户端
+            HttpClient httpClient = createHttpClient();
+
+            // 创建GET请求
+            HttpGet httpGet = new HttpGet(API_URL);
+
+            // 设置请求头
+            httpGet.setHeader("Accept", "application/json");
+
+            // 创建Basic认证头
+            String auth = USERNAME + ":" + PASSWORD;
+            String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
+            httpGet.setHeader("Authorization", "Basic " + encodedAuth);
+
+            System.out.println("正在发送GET请求...");
+
+            // 发送请求
+            HttpResponse response = httpClient.execute(httpGet);
+
+            // 获取响应状态码
+            int statusCode = response.getStatusLine().getStatusCode();
+            System.out.println("响应状态码: " + statusCode);
+
+            // 获取响应内容
+            HttpEntity responseEntity = response.getEntity();
+            String responseBody = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
+
+            System.out.println("响应内容:");
+            System.out.println(responseBody);
+
+            // 检查响应状态
+            if (statusCode == 200) {
+                System.out.println("✅ API请求成功!");
+            } else {
+                System.out.println("❌ API请求失败,状态码: " + statusCode);
+            }
+
+        } catch (IOException e) {
+            System.err.println("❌ API请求出现异常: " + e.getMessage());
+            e.printStackTrace();
+        } catch (Exception e) {
+            System.err.println("❌ 发生未知错误: " + e.getMessage());
+            e.printStackTrace();
+        }
+
+        System.out.println("==========================================");
+        System.out.println("API测试完成");
+    }
+}

+ 201 - 0
master/src/main/java/com/ruoyi/project/production/domain/TLimsData.java

@@ -2,6 +2,10 @@ package com.ruoyi.project.production.domain;
 
 import java.util.Date;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.framework.aspectj.lang.annotation.Excel;
 import com.ruoyi.framework.web.domain.BaseEntity;
 import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -13,6 +17,7 @@ import org.apache.commons.lang3.builder.ToStringStyle;
  * @author ssy
  * @date 2025-09-12
  */
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class TLimsData extends BaseEntity
 {
     private static final long serialVersionUID = 1L;
@@ -87,6 +92,12 @@ public class TLimsData extends BaseEntity
     @Excel(name = "备注")
     private String remarks;
 
+    private transient int sampledDateSourceLevel;
+    private transient int plantSourceLevel;
+    private transient int samplingPointSourceLevel;
+    private transient int authorisedSourceLevel;
+    private transient int resultSourceLevel;
+
     public void setId(Long id)
     {
         this.id = id;
@@ -241,6 +252,196 @@ public class TLimsData extends BaseEntity
         return remarks;
     }
 
+    @JsonProperty("SAMPLE_ID")
+    public void setSampleIdFromLims(String sampleId)
+    {
+        this.sampId = StringUtils.trim(sampleId);
+    }
+
+    @JsonProperty("R_NAME")
+    public void setRNameFromLims(String rName)
+    {
+        this.rName = StringUtils.trim(rName);
+    }
+
+    @JsonProperty("R_UNITS")
+    public void setUnitsFromLims(String units)
+    {
+        this.units = StringUtils.trim(units);
+    }
+
+    @JsonProperty("MV_RANGE")
+    public void setMvRangeFromLims(String mvRange)
+    {
+        this.mvRange = StringUtils.trim(mvRange);
+    }
+
+    @JsonProperty("R_TEXT")
+    public void setRTextFromLims(String rText)
+    {
+        this.rText = StringUtils.trim(rText);
+    }
+
+    @JsonProperty("SAMPLED_DATE_C")
+    public void setSampledDateCFromLims(String sampledDateC)
+    {
+        setSampledDateIfBetter(parseLimsDate(sampledDateC), 2);
+    }
+
+    @JsonProperty("S_SAMPLED_DATE")
+    public void setSSampledDateFromLims(String sSampledDate)
+    {
+        setSampledDateIfBetter(parseLimsDate(sSampledDate), 1);
+    }
+
+    @JsonProperty("T_DATE_AUTHORISED")
+    public void setTDateAuthorisedFromLims(String tDateAuthorised)
+    {
+        setAuthorisedIfBetter(parseLimsDate(tDateAuthorised), 2);
+    }
+
+    @JsonProperty("S_DATE_AUTHORISED")
+    public void setSDateAuthorisedFromLims(String sDateAuthorised)
+    {
+        setAuthorisedIfBetter(parseLimsDate(sDateAuthorised), 1);
+    }
+
+    @JsonProperty("L_LOCATION")
+    public void setLLocationFromLims(String lLocation)
+    {
+        setPlantIfBetter(lLocation, 2);
+    }
+
+    @JsonProperty("LOCATION_ID")
+    public void setLocationIdFromLims(String locationId)
+    {
+        setPlantIfBetter(locationId, 1);
+    }
+
+    @JsonProperty("SP_SAMPLING_POINT")
+    public void setSpSamplingPointFromLims(String spSamplingPoint)
+    {
+        setSamplingPointIfBetter(spSamplingPoint, 2);
+    }
+
+    @JsonProperty("S_SAMPLING_POINT_ID")
+    public void setSSamplingPointIdFromLims(String sSamplingPointId)
+    {
+        setSamplingPointIfBetter(sSamplingPointId, 1);
+    }
+
+    @JsonProperty("SAMPLE_GRADE")
+    public void setSampleGradeFromLims(String sampleGrade)
+    {
+        setResultIfBetter(sampleGrade, 5);
+    }
+
+    @JsonProperty("S_COMP_PROD_GRADE")
+    public void setSCompProdGradeFromLims(String sCompProdGrade)
+    {
+        setResultIfBetter(sCompProdGrade, 4);
+    }
+
+    @JsonProperty("R_OUT_OF_RANGE")
+    public void setROutOfRangeFromLims(String rOutOfRange)
+    {
+        setResultIfBetter(rOutOfRange, 3);
+    }
+
+    @JsonProperty("T_ON_SPEC")
+    public void setTOnSpecFromLims(String tOnSpec)
+    {
+        setResultIfBetter(tOnSpec, 2);
+    }
+
+    @JsonProperty("S_ON_SPEC")
+    public void setSOnSpecFromLims(String sOnSpec)
+    {
+        setResultIfBetter(sOnSpec, 1);
+    }
+
+    private void setSampledDateIfBetter(Date value, int level)
+    {
+        if (value == null)
+        {
+            return;
+        }
+        if (this.sampledDate == null || level >= this.sampledDateSourceLevel)
+        {
+            this.sampledDate = value;
+            this.sampledDateSourceLevel = level;
+        }
+    }
+
+    private void setAuthorisedIfBetter(Date value, int level)
+    {
+        if (value == null)
+        {
+            return;
+        }
+        if (this.authorised == null || level >= this.authorisedSourceLevel)
+        {
+            this.authorised = value;
+            this.authorisedSourceLevel = level;
+        }
+    }
+
+    private void setPlantIfBetter(String value, int level)
+    {
+        String v = StringUtils.trim(value);
+        if (StringUtils.isEmpty(v))
+        {
+            return;
+        }
+        if (StringUtils.isEmpty(this.plant) || level >= this.plantSourceLevel)
+        {
+            this.plant = v;
+            this.plantSourceLevel = level;
+        }
+    }
+
+    private void setSamplingPointIfBetter(String value, int level)
+    {
+        String v = StringUtils.trim(value);
+        if (StringUtils.isEmpty(v))
+        {
+            return;
+        }
+        if (StringUtils.isEmpty(this.samplingPoint) || level >= this.samplingPointSourceLevel)
+        {
+            this.samplingPoint = v;
+            this.samplingPointSourceLevel = level;
+        }
+    }
+
+    private void setResultIfBetter(String value, int level)
+    {
+        String v = StringUtils.trim(value);
+        if (StringUtils.isEmpty(v))
+        {
+            return;
+        }
+        if (StringUtils.isEmpty(this.result) || level >= this.resultSourceLevel)
+        {
+            this.result = v;
+            this.resultSourceLevel = level;
+        }
+    }
+
+    private Date parseLimsDate(String value)
+    {
+        if (StringUtils.isEmpty(value))
+        {
+            return null;
+        }
+        String v = StringUtils.trim(value);
+        if (v.length() >= 10)
+        {
+            return DateUtils.parseDate(v.substring(0, 10));
+        }
+        return DateUtils.parseDate(v);
+    }
+
     @Override
     public String toString() {
         return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

+ 1 - 1
master/src/main/java/com/ruoyi/project/reliability/controller/TRelCompoController.java

@@ -137,7 +137,7 @@ public class TRelCompoController extends BaseController
         int failNumber = 0;
         int successNumber = 0;
 
-        for (int i = 1; i < rowNum; i++) {
+        for (int i = 1; i <= rowNum; i++) {
             try {
                 logger.info("读取行数:" + i);
                 Row row = sheet.getRow(i);

+ 3 - 3
master/src/main/java/com/ruoyi/project/reliability/controller/TRelDeviceController.java

@@ -138,14 +138,14 @@ public class TRelDeviceController extends BaseController
         int failNumber = 0;
         int successNumber = 0;
 
-        for (int i = 1; i < rowNum; i++) {
+        for (int i = 1; i <= rowNum; i++) {
             try {
                 logger.info("读取行数:" + i);
                 Row row = sheet.getRow(i);
                 if (row == null) continue;
 
                 TRelDevice entity = new TRelDevice();
-                
+
                 int cellNum = row.getPhysicalNumberOfCells();
                 for (int j = 0; j < cellNum; j++) {
                     Cell cell = row.getCell(j);
@@ -183,7 +183,7 @@ public class TRelDeviceController extends BaseController
                 } else {
                     entity.setDeptId(userService.selectUserById(userId).getDeptId());
                 }
-                
+
                 entity.setCreaterCode(userId.toString());
                 entity.setCreatedate(new Date());
                 entity.setDelFlag(0L);

+ 1 - 1
master/src/main/java/com/ruoyi/project/reliability/controller/TRelMaintPlanController.java

@@ -348,7 +348,7 @@ public class TRelMaintPlanController extends BaseController
                 return AjaxResult.error("维修部件列表不能为空");
             }
 
-            tRelMaintPlanService.syncMaintRecordsOnly(tRelMaintPlan.getPlanId(), tRelMaintPlan.getMaintComponents(), getUserId());
+            tRelMaintPlanService.syncMaintRecordsOnly(tRelMaintPlan, getUserId());
             return AjaxResult.success("保存成功");
         } catch (Exception e) {
             logger.error("仅保存失败", e);

+ 110 - 8
master/src/main/java/com/ruoyi/project/reliability/controller/TRelMaintRecordController.java

@@ -2,6 +2,7 @@ package com.ruoyi.project.reliability.controller;
 
 import java.util.Date;
 import java.util.List;
+import java.util.Objects;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -18,10 +19,12 @@ import com.ruoyi.project.reliability.domain.TRelMaintRecord;
 import com.ruoyi.project.reliability.domain.TRelMaintPlan;
 import com.ruoyi.project.reliability.domain.TRelMaintMemo;
 import com.ruoyi.project.reliability.domain.TRelCompo;
+import com.ruoyi.project.reliability.domain.TRelThickness;
 import com.ruoyi.project.reliability.service.ITRelMaintRecordService;
 import com.ruoyi.project.reliability.service.ITRelMaintPlanService;
 import com.ruoyi.project.reliability.service.ITRelMaintMemoService;
 import com.ruoyi.project.reliability.service.ITRelCompoService;
+import com.ruoyi.project.reliability.service.ITRelThicknessService;
 import com.ruoyi.framework.web.controller.BaseController;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -53,6 +56,9 @@ public class TRelMaintRecordController extends BaseController
     @Autowired
     private ITRelCompoService tRelCompoService;
 
+    @Autowired
+    private ITRelThicknessService tRelThicknessService;
+
     /**
      * 查询部件维修记录列表
      */
@@ -108,6 +114,12 @@ public class TRelMaintRecordController extends BaseController
         if (record != null) {
             // 预填充部件的对应内容
             fillRecordContentFromCompo(record);
+
+            try {
+                record.setThicknessList(tRelThicknessService.selectTRelThicknessByRecordId(recordId));
+            } catch (Exception e) {
+                logger.error("查询测厚记录失败,recordId: " + recordId, e);
+            }
         }
         return AjaxResult.success(record);
     }
@@ -146,16 +158,21 @@ public class TRelMaintRecordController extends BaseController
     @PutMapping
     public AjaxResult edit(@RequestBody TRelMaintRecord tRelMaintRecord)
     {
-        // 保存是否需要创建新记录的信息(在更新前保存,因为更新后这些字段可能被清空)
+        // 保存“派生动作”相关的入参(必须在 update 前保存)。
+        // 说明:前端提交的 payload 里会带一些辅助字段(例如 needMaintOrReplace/newMaintType/newResponsible),
+        // update 之后这些字段在对象上可能被覆盖/清空(或前端未再次回传),所以这里先缓存,后续用于业务分支判断。
         Boolean needMaintOrReplace = tRelMaintRecord.getNeedMaintOrReplace();
         String newMaintType = tRelMaintRecord.getNewMaintType();
         String newResponsible = tRelMaintRecord.getNewResponsible();
         String maintType = tRelMaintRecord.getMaintType();
         Boolean cannotMaintOrReplace = tRelMaintRecord.getCannotMaintOrReplace();
         
-        // 如果传入了recordId,说明是处理维修任务
+        // 如果传入了 recordId,说明是“处理任务/完工提交”(而不是新增记录)。
+        // 处理逻辑:
+        // - cannotMaintOrReplace=true 视为延期(recordStatus=3)
+        // - 否则视为已完成(recordStatus=2)
         if (tRelMaintRecord.getRecordId() != null) {
-            // 如果选择了延期维护,设置状态为3(已延期),否则设置为2(已完成)
+            // 如果选择了延期维护,设置状态为 3(已延期),否则设置为 2(已完成)
             if (cannotMaintOrReplace != null && cannotMaintOrReplace) {
                 tRelMaintRecord.setRecordStatus(3); // 已延期
             } else {
@@ -166,6 +183,9 @@ public class TRelMaintRecordController extends BaseController
         Date memoTime = tRelMaintRecord.getMemoTime();
         String remarks = tRelMaintRecord.getRemarks();
 
+        // 当选择“无法维修/更换(延期)”并填写了备忘原因时:
+        // - 将备忘原因同步写入 remarks,便于在记录列表中快速查看延期原因。
+        // - 注意:此处不会创建 memo,创建 memo 的条件在后面单独判断(需要 memoTime 等信息)。
         if (cannotMaintOrReplace != null && cannotMaintOrReplace
             && memoReason != null && !memoReason.isEmpty()) {
             if (remarks == null || remarks.isEmpty()) {
@@ -175,16 +195,20 @@ public class TRelMaintRecordController extends BaseController
             }
         }
 
+        // 先更新维修记录本身(状态、内容、时间、费用等)。
+        // 下面的派生动作(创建新任务、创建/删除备忘录、保存测厚、更新部件上次日期)均依赖该更新成功。
         int result = tRelMaintRecordService.updateTRelMaintRecord(tRelMaintRecord);
         
-        // 如果是检查任务(maintType = "1")且选择了需要维修/更换,创建新的维修或更换记录
+        // 检查任务(maintType=1):
+        // 若选择“需要维修/更换”,则自动派生一条新的维修/更换记录,形成从检查 -> 维修/更换的闭环。
         if (result > 0 && "1".equals(maintType) && needMaintOrReplace != null && needMaintOrReplace 
             && newMaintType != null && !newMaintType.isEmpty() 
             && newResponsible != null && !newResponsible.isEmpty()) {
             createNewMaintRecordFromInspect(tRelMaintRecord, newMaintType, newResponsible);
         }
         
-        // 如果是维修/更换任务(maintType = "2" 或 "3")且选择了无法维修/更换,创建备忘录记录
+        // 维修/更换任务(maintType=2/3):
+        // 若选择“无法维修/更换(延期)”且填写了原因与时间,则生成一条备忘录,作为后续跟踪提醒。
         if (result > 0 && ("2".equals(maintType) || "3".equals(maintType)) 
             && cannotMaintOrReplace != null && cannotMaintOrReplace
             && memoReason != null && !memoReason.isEmpty()
@@ -192,21 +216,99 @@ public class TRelMaintRecordController extends BaseController
             createMaintMemoFromRecord(tRelMaintRecord, memoReason, memoTime);
         }
         
-        // 如果没有创建备忘录,则更新部件的上次日期
-        // 检查是否创建了备忘录(如果创建了备忘录则不更新上次日期)
+        // 如果没有创建备忘录,则更新部件的上次检查/维修/更换日期”。
+        // 说明:当选择延期并生成备忘录时,本次不应更新上次日期(因为并未真正完成维护动作)。
         boolean createdMemo = result > 0 && ("2".equals(maintType) || "3".equals(maintType)) 
             && cannotMaintOrReplace != null && cannotMaintOrReplace
             && memoReason != null && !memoReason.isEmpty()
             && memoTime != null;
         
         if (result > 0 && !createdMemo && tRelMaintRecord.getCompoId() != null) {
+            // 根据 maintType 更新部件的 lastInspDate / lastFixDate / lastReplaceDate
             updateCompoLastDate(tRelMaintRecord, maintType);
         }
         
-        // 更新记录后,检查该记录所属的计划是否所有记录都已完成
+        // 更新记录后,检查该记录所属的计划是否所有记录都已完成:
+        // 若计划下全部记录都处于“已完成/已延期”,则计划标记为完成。
         if (result > 0 && tRelMaintRecord.getPlanId() != null) {
             checkAndUpdatePlanCompletionStatus(tRelMaintRecord.getPlanId());
         }
+
+        // 维修/更换任务在“正常完成(recordStatus=2)”后:
+        // 若该部件存在未删除的备忘录,则自动删除(逻辑删除)备忘录。
+        // 目的:备忘录通常用于“延期/无法处理”的临时提醒;当部件已被处理完成,备忘录应随之清理。
+        if (result > 0
+            && ("2".equals(maintType) || "3".equals(maintType))
+            && tRelMaintRecord.getRecordId() != null
+            && "2".equals(String.valueOf(tRelMaintRecord.getRecordStatus()))) {
+            try {
+                TRelMaintMemo queryMemo = new TRelMaintMemo();
+                // 优先通过 compoId 精确定位备忘录;若历史数据缺少 compoId,则使用 devTag+compoName 兜底查询。
+                if (tRelMaintRecord.getCompoId() != null && !tRelMaintRecord.getCompoId().isEmpty()) {
+                    queryMemo.setCompoId(tRelMaintRecord.getCompoId());
+                } else {
+                    queryMemo.setDevTag(tRelMaintRecord.getDevTag());
+                    queryMemo.setCompoName(tRelMaintRecord.getCompoName());
+                }
+                List<TRelMaintMemo> memoList = tRelMaintMemoService.selectTRelMaintMemoList(queryMemo);
+                if (memoList != null && !memoList.isEmpty()) {
+                    // 统一批量逻辑删除(del_flag=2),兼容一个部件可能存在多条备忘录的情况。
+                    Long[] memoIds = memoList.stream()
+                        .map(TRelMaintMemo::getMemoId)
+                        .filter(Objects::nonNull)
+                        .toArray(Long[]::new);
+                    if (memoIds.length > 0) {
+                        tRelMaintMemoService.deleteTRelMaintMemoByIds(memoIds);
+                    }
+                }
+            } catch (Exception e) {
+                logger.error("删除备忘录失败,recordId: " + tRelMaintRecord.getRecordId() + ", compoId: " + tRelMaintRecord.getCompoId(), e);
+            }
+        }
+        
+        // 保存测厚数据(与 recordId 关联):
+        // - 若本次提交携带 thicknessList,则先删除该 recordId 原有测厚记录,再插入新列表,实现“全量覆盖式保存”。
+        // - 插入前补齐外键/冗余字段(装置、位号、部件等)以及审计字段(创建人、创建时间、部门、删除标志)。
+        if (result > 0 && tRelMaintRecord.getRecordId() != null) {
+            try {
+                if (tRelMaintRecord.getThicknessList() != null) {
+                    tRelThicknessService.deleteTRelThicknessByRecordId(tRelMaintRecord.getRecordId());
+
+                    if (!tRelMaintRecord.getThicknessList().isEmpty()) {
+                        String staffId = getBaseStaffId();
+                        Date now = new Date();
+
+                        for (TRelThickness row : tRelMaintRecord.getThicknessList()) {
+                            if (row == null) {
+                                continue;
+                            }
+                            row.setThicknessId(null);
+                            row.setRecordId(tRelMaintRecord.getRecordId());
+                            row.setPlant(tRelMaintRecord.getPlant());
+                            row.setDevName(tRelMaintRecord.getDevName());
+                            row.setDevTag(tRelMaintRecord.getDevTag());
+                            row.setCompoId(tRelMaintRecord.getCompoId());
+                            row.setCompoName(tRelMaintRecord.getCompoName());
+                            if (tRelMaintRecord.getCompo() != null) {
+                                row.setCompoModel(tRelMaintRecord.getCompo().getCompoModel());
+                            }
+                            row.setDelFlag(0L);
+                            if (row.getCreaterCode() == null || row.getCreaterCode().isEmpty()) {
+                                row.setCreaterCode(staffId);
+                            }
+                            if (row.getCreatedate() == null) {
+                                row.setCreatedate(now);
+                            }
+                            row.setDeptId(tRelMaintRecord.getDeptId());
+
+                            tRelThicknessService.insertTRelThickness(row);
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                logger.error("保存测厚记录失败,recordId: " + tRelMaintRecord.getRecordId(), e);
+            }
+        }
         
         return toAjax(result);
     }

+ 81 - 0
master/src/main/java/com/ruoyi/project/reliability/controller/TRelThicknessController.java

@@ -0,0 +1,81 @@
+package com.ruoyi.project.reliability.controller;
+
+import java.util.Date;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.ruoyi.framework.web.controller.BaseController;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.framework.web.page.TableDataInfo;
+import com.ruoyi.project.reliability.domain.TRelThickness;
+import com.ruoyi.project.reliability.service.ITRelThicknessService;
+
+@RestController
+@RequestMapping("/reliability/rel_thickness")
+public class TRelThicknessController extends BaseController
+{
+    @Autowired
+    private ITRelThicknessService tRelThicknessService;
+
+    @GetMapping("/list")
+    public TableDataInfo list(TRelThickness tRelThickness)
+    {
+        startPage();
+        List<TRelThickness> list = tRelThicknessService.selectTRelThicknessList(tRelThickness);
+        return getDataTable(list);
+    }
+
+    @GetMapping(value = "/{thicknessId}")
+    public AjaxResult getInfo(@PathVariable("thicknessId") Long thicknessId)
+    {
+        return AjaxResult.success(tRelThicknessService.selectTRelThicknessById(thicknessId));
+    }
+
+    @PostMapping
+    public AjaxResult add(@RequestBody TRelThickness tRelThickness)
+    {
+        if (tRelThickness.getDelFlag() == null) {
+            tRelThickness.setDelFlag(0L);
+        }
+        if (tRelThickness.getCreatedate() == null) {
+            tRelThickness.setCreatedate(new Date());
+        }
+        if (tRelThickness.getCreaterCode() == null || tRelThickness.getCreaterCode().isEmpty()) {
+            String staffId = getBaseStaffId();
+            if (staffId != null && !staffId.isEmpty()) {
+                tRelThickness.setCreaterCode(staffId);
+            }
+        }
+        return toAjax(tRelThicknessService.insertTRelThickness(tRelThickness));
+    }
+
+    @PutMapping
+    public AjaxResult edit(@RequestBody TRelThickness tRelThickness)
+    {
+        if (tRelThickness.getUpdatedate() == null) {
+            tRelThickness.setUpdatedate(new Date());
+        }
+        if (tRelThickness.getUpdaterCode() == null || tRelThickness.getUpdaterCode().isEmpty()) {
+            String staffId = getBaseStaffId();
+            if (staffId != null && !staffId.isEmpty()) {
+                tRelThickness.setUpdaterCode(staffId);
+            }
+        }
+        return toAjax(tRelThicknessService.updateTRelThickness(tRelThickness));
+    }
+
+    @DeleteMapping("/{thicknessIds}")
+    public AjaxResult remove(@PathVariable Long[] thicknessIds)
+    {
+        return toAjax(tRelThicknessService.deleteTRelThicknessByIds(thicknessIds));
+    }
+}

+ 13 - 0
master/src/main/java/com/ruoyi/project/reliability/domain/TRelCompo.java

@@ -1,6 +1,7 @@
 package com.ruoyi.project.reliability.domain;
 
 import java.util.Date;
+import java.util.List;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.framework.aspectj.lang.annotation.Excel;
 import com.ruoyi.framework.web.domain.BaseEntity;
@@ -151,6 +152,8 @@ public class TRelCompo extends BaseEntity
 
     private Integer hasMemo;
 
+    private List<TRelThickness> thicknessList;
+
     public void setCompoId(Long compoId)
     {
         this.compoId = compoId;
@@ -460,6 +463,16 @@ public class TRelCompo extends BaseEntity
         return hasMemo;
     }
 
+    public void setThicknessList(List<TRelThickness> thicknessList)
+    {
+        this.thicknessList = thicknessList;
+    }
+
+    public List<TRelThickness> getThicknessList()
+    {
+        return thicknessList;
+    }
+
     @Override
     public String toString() {
         return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

+ 14 - 0
master/src/main/java/com/ruoyi/project/reliability/domain/TRelMaintRecord.java

@@ -1,6 +1,7 @@
 package com.ruoyi.project.reliability.domain;
 
 import java.util.Date;
+import java.util.List;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.framework.aspectj.lang.annotation.Excel;
 import com.ruoyi.framework.web.domain.BaseEntity;
@@ -168,6 +169,9 @@ public class TRelMaintRecord extends BaseEntity
     /** 备忘时间(不存储到数据库) */
     private Date memoTime;
 
+    /** 测厚记录(不存储到数据库) */
+    private List<TRelThickness> thicknessList;
+
     public void setMaintPlan(TRelMaintPlan maintPlan)
     {
         this.maintPlan = maintPlan;
@@ -258,6 +262,16 @@ public class TRelMaintRecord extends BaseEntity
         return memoTime;
     }
 
+    public void setThicknessList(List<TRelThickness> thicknessList)
+    {
+        this.thicknessList = thicknessList;
+    }
+
+    public List<TRelThickness> getThicknessList()
+    {
+        return thicknessList;
+    }
+
     public void setRecordId(Long recordId)
     {
         this.recordId = recordId;

+ 230 - 0
master/src/main/java/com/ruoyi/project/reliability/domain/TRelThickness.java

@@ -0,0 +1,230 @@
+package com.ruoyi.project.reliability.domain;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.framework.web.domain.BaseEntity;
+
+public class TRelThickness extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    private Long thicknessId;
+
+    private String plant;
+
+    private String devName;
+
+    private String devTag;
+
+    private String compoId;
+
+    private String compoName;
+
+    private String compoModel;
+
+    private Long recordId;
+
+    private String thicknessPt;
+
+    private Double thicknessData;
+
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date thicknessDate;
+
+    private Long delFlag;
+
+    private String createrCode;
+
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date createdate;
+
+    private String updaterCode;
+
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date updatedate;
+
+    private Long deptId;
+
+    private String remarks;
+
+    public Long getThicknessId()
+    {
+        return thicknessId;
+    }
+
+    public void setThicknessId(Long thicknessId)
+    {
+        this.thicknessId = thicknessId;
+    }
+
+    public String getPlant()
+    {
+        return plant;
+    }
+
+    public void setPlant(String plant)
+    {
+        this.plant = plant;
+    }
+
+    public String getDevName()
+    {
+        return devName;
+    }
+
+    public void setDevName(String devName)
+    {
+        this.devName = devName;
+    }
+
+    public String getDevTag()
+    {
+        return devTag;
+    }
+
+    public void setDevTag(String devTag)
+    {
+        this.devTag = devTag;
+    }
+
+    public String getCompoId()
+    {
+        return compoId;
+    }
+
+    public void setCompoId(String compoId)
+    {
+        this.compoId = compoId;
+    }
+
+    public String getCompoName()
+    {
+        return compoName;
+    }
+
+    public void setCompoName(String compoName)
+    {
+        this.compoName = compoName;
+    }
+
+    public String getCompoModel()
+    {
+        return compoModel;
+    }
+
+    public void setCompoModel(String compoModel)
+    {
+        this.compoModel = compoModel;
+    }
+
+    public Long getRecordId()
+    {
+        return recordId;
+    }
+
+    public void setRecordId(Long recordId)
+    {
+        this.recordId = recordId;
+    }
+
+    public String getThicknessPt()
+    {
+        return thicknessPt;
+    }
+
+    public void setThicknessPt(String thicknessPt)
+    {
+        this.thicknessPt = thicknessPt;
+    }
+
+    public Double getThicknessData()
+    {
+        return thicknessData;
+    }
+
+    public void setThicknessData(Double thicknessData)
+    {
+        this.thicknessData = thicknessData;
+    }
+
+    public Date getThicknessDate()
+    {
+        return thicknessDate;
+    }
+
+    public void setThicknessDate(Date thicknessDate)
+    {
+        this.thicknessDate = thicknessDate;
+    }
+
+    public Long getDelFlag()
+    {
+        return delFlag;
+    }
+
+    public void setDelFlag(Long delFlag)
+    {
+        this.delFlag = delFlag;
+    }
+
+    public String getCreaterCode()
+    {
+        return createrCode;
+    }
+
+    public void setCreaterCode(String createrCode)
+    {
+        this.createrCode = createrCode;
+    }
+
+    public Date getCreatedate()
+    {
+        return createdate;
+    }
+
+    public void setCreatedate(Date createdate)
+    {
+        this.createdate = createdate;
+    }
+
+    public String getUpdaterCode()
+    {
+        return updaterCode;
+    }
+
+    public void setUpdaterCode(String updaterCode)
+    {
+        this.updaterCode = updaterCode;
+    }
+
+    public Date getUpdatedate()
+    {
+        return updatedate;
+    }
+
+    public void setUpdatedate(Date updatedate)
+    {
+        this.updatedate = updatedate;
+    }
+
+    public Long getDeptId()
+    {
+        return deptId;
+    }
+
+    public void setDeptId(Long deptId)
+    {
+        this.deptId = deptId;
+    }
+
+    public String getRemarks()
+    {
+        return remarks;
+    }
+
+    public void setRemarks(String remarks)
+    {
+        this.remarks = remarks;
+    }
+}

+ 28 - 0
master/src/main/java/com/ruoyi/project/reliability/mapper/TRelThicknessMapper.java

@@ -0,0 +1,28 @@
+package com.ruoyi.project.reliability.mapper;
+
+import java.util.List;
+
+import com.ruoyi.project.reliability.domain.TRelThickness;
+
+public interface TRelThicknessMapper
+{
+    public TRelThickness selectTRelThicknessById(Long thicknessId);
+
+    public List<TRelThickness> selectTRelThicknessList(TRelThickness tRelThickness);
+
+    public List<TRelThickness> selectTRelThicknessByRecordIds(Long[] recordIds);
+
+    public List<TRelThickness> selectTRelThicknessByCompoIds(String[] compoIds);
+
+    public List<TRelThickness> selectTRelThicknessByRecordId(Long recordId);
+
+    public int insertTRelThickness(TRelThickness tRelThickness);
+
+    public int updateTRelThickness(TRelThickness tRelThickness);
+
+    public int deleteTRelThicknessById(Long thicknessId);
+
+    public int deleteTRelThicknessByIds(Long[] thicknessIds);
+
+    public int deleteTRelThicknessByRecordId(Long recordId);
+}

+ 1 - 2
master/src/main/java/com/ruoyi/project/reliability/service/ITRelMaintPlanService.java

@@ -4,7 +4,6 @@ import java.util.Date;
 import java.util.List;
 
 import com.ruoyi.project.reliability.domain.TRelMaintPlan;
-import com.ruoyi.project.reliability.domain.TRelMaintRecord;
 
 /**
  * 设备维修计划Service接口
@@ -70,7 +69,7 @@ public interface ITRelMaintPlanService
      */
     public int deleteTRelMaintPlanById(Long planId);
 
-    void syncMaintRecordsOnly(Long planId, List<TRelMaintRecord> maintComponents, Long operatorUserId);
+    void syncMaintRecordsOnly(TRelMaintPlan tRelMaintPlan, Long operatorUserId);
 
     /**
      * 查询在指定结束日期区间内且未完成的维修计划(用于到期提醒)

+ 28 - 0
master/src/main/java/com/ruoyi/project/reliability/service/ITRelThicknessService.java

@@ -0,0 +1,28 @@
+package com.ruoyi.project.reliability.service;
+
+import java.util.List;
+
+import com.ruoyi.project.reliability.domain.TRelThickness;
+
+public interface ITRelThicknessService
+{
+    public TRelThickness selectTRelThicknessById(Long thicknessId);
+
+    public List<TRelThickness> selectTRelThicknessList(TRelThickness tRelThickness);
+
+    public List<TRelThickness> selectTRelThicknessByRecordIds(Long[] recordIds);
+
+    public List<TRelThickness> selectTRelThicknessByCompoIds(String[] compoIds);
+
+    public List<TRelThickness> selectTRelThicknessByRecordId(Long recordId);
+
+    public int insertTRelThickness(TRelThickness tRelThickness);
+
+    public int updateTRelThickness(TRelThickness tRelThickness);
+
+    public int deleteTRelThicknessById(Long thicknessId);
+
+    public int deleteTRelThicknessByIds(Long[] thicknessIds);
+
+    public int deleteTRelThicknessByRecordId(Long recordId);
+}

+ 54 - 3
master/src/main/java/com/ruoyi/project/reliability/service/impl/TRelCompoServiceImpl.java

@@ -1,10 +1,15 @@
 package com.ruoyi.project.reliability.service.impl;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.project.reliability.mapper.TRelCompoMapper;
+import com.ruoyi.project.reliability.mapper.TRelThicknessMapper;
 import com.ruoyi.project.reliability.domain.TRelCompo;
+import com.ruoyi.project.reliability.domain.TRelThickness;
 import com.ruoyi.project.reliability.service.ITRelCompoService;
 
 /**
@@ -19,6 +24,9 @@ public class TRelCompoServiceImpl implements ITRelCompoService
     @Autowired
     private TRelCompoMapper tRelCompoMapper;
 
+    @Autowired
+    private TRelThicknessMapper tRelThicknessMapper;
+
     /**
      * 查询可靠性部件清单
      *
@@ -28,7 +36,12 @@ public class TRelCompoServiceImpl implements ITRelCompoService
     @Override
     public TRelCompo selectTRelCompoById(Long compoId)
     {
-        return tRelCompoMapper.selectTRelCompoById(compoId);
+        TRelCompo compo = tRelCompoMapper.selectTRelCompoById(compoId);
+        if (compo != null && compo.getCompoId() != null) {
+            List<TRelThickness> thicknessList = tRelThicknessMapper.selectTRelThicknessByCompoIds(new String[] { String.valueOf(compo.getCompoId()) });
+            compo.setThicknessList(thicknessList);
+        }
+        return compo;
     }
 
     /**
@@ -40,7 +53,9 @@ public class TRelCompoServiceImpl implements ITRelCompoService
     @Override
     public List<TRelCompo> selectTRelCompoByDevTag(String devTag)
     {
-        return tRelCompoMapper.selectTRelCompoByDevTag(devTag);
+        List<TRelCompo> list = tRelCompoMapper.selectTRelCompoByDevTag(devTag);
+        fillThicknessList(list);
+        return list;
     }
 
     /**
@@ -52,7 +67,43 @@ public class TRelCompoServiceImpl implements ITRelCompoService
     @Override
     public List<TRelCompo> selectTRelCompoList(TRelCompo tRelCompo)
     {
-        return tRelCompoMapper.selectTRelCompoList(tRelCompo);
+        List<TRelCompo> list = tRelCompoMapper.selectTRelCompoList(tRelCompo);
+        fillThicknessList(list);
+        return list;
+    }
+
+    private void fillThicknessList(List<TRelCompo> list) {
+        if (list == null || list.isEmpty()) {
+            return;
+        }
+
+        List<String> compoIds = new ArrayList<>();
+        for (TRelCompo c : list) {
+            if (c != null && c.getCompoId() != null) {
+                compoIds.add(String.valueOf(c.getCompoId()));
+            }
+        }
+        if (compoIds.isEmpty()) {
+            return;
+        }
+
+        List<TRelThickness> thicknessList = tRelThicknessMapper.selectTRelThicknessByCompoIds(compoIds.toArray(new String[0]));
+        if (thicknessList == null || thicknessList.isEmpty()) {
+            return;
+        }
+
+        Map<String, List<TRelThickness>> grouped = new HashMap<>();
+        for (TRelThickness t : thicknessList) {
+            if (t != null && t.getCompoId() != null && !t.getCompoId().isEmpty()) {
+                grouped.computeIfAbsent(t.getCompoId(), k -> new ArrayList<>()).add(t);
+            }
+        }
+
+        for (TRelCompo c : list) {
+            if (c != null && c.getCompoId() != null) {
+                c.setThicknessList(grouped.get(String.valueOf(c.getCompoId())));
+            }
+        }
     }
 
     /**

+ 13 - 1
master/src/main/java/com/ruoyi/project/reliability/service/impl/TRelDeviceServiceImpl.java

@@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.project.reliability.mapper.TRelDeviceMapper;
 import com.ruoyi.project.reliability.domain.TRelDevice;
+import com.ruoyi.project.reliability.service.ITRelCompoService;
 import com.ruoyi.project.reliability.service.ITRelDeviceService;
 
 /**
@@ -19,6 +20,9 @@ public class TRelDeviceServiceImpl implements ITRelDeviceService
     @Autowired
     private TRelDeviceMapper tRelDeviceMapper;
 
+    @Autowired
+    private ITRelCompoService tRelCompoService;
+
     /**
      * 查询可靠性设备清单
      *
@@ -28,7 +32,15 @@ public class TRelDeviceServiceImpl implements ITRelDeviceService
     @Override
     public TRelDevice selectTRelDeviceById(Long devId)
     {
-        return tRelDeviceMapper.selectTRelDeviceById(devId);
+        TRelDevice device = tRelDeviceMapper.selectTRelDeviceById(devId);
+        if (device != null && device.getDevTag() != null && !device.getDevTag().isEmpty()) {
+            // 说明:TRelDeviceMapper.xml 中 selectTRelDeviceById 使用了 <collection select="TRelCompoMapper.selectTRelCompoByDevTag">
+            // 来装配 compoList,但该方式只会走 Mapper,不会走 Service 层的“测厚数据批量挂载”逻辑。
+            // 因此,这里主动使用 Service 再查一次 compoList,确保返回的部件列表包含 thicknessList,
+            // 并且避免在前端/其他位置再次触发 N+1 式的单条查询。
+            device.setCompoList(tRelCompoService.selectTRelCompoByDevTag(device.getDevTag()));
+        }
+        return device;
     }
 
     /**

+ 45 - 4
master/src/main/java/com/ruoyi/project/reliability/service/impl/TRelMaintPlanServiceImpl.java

@@ -2,8 +2,10 @@ package com.ruoyi.project.reliability.service.impl;
 
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -87,6 +89,29 @@ public class TRelMaintPlanServiceImpl implements ITRelMaintPlanService
             // 根据planId查询维修记录列表(使用精确匹配,高性能)
             List<TRelMaintRecord> recordList = tRelMaintRecordService.selectTRelMaintRecordByPlanId(planId);
             plan.setMaintRecordsList(recordList);
+
+            // 前端“维修计划 form”页面会直接使用这里返回的 compoList 渲染“部件维修选择”表格。
+            // 为了更直观,把“已勾选/已存在维修记录”的部件排在最前面(仅影响返回顺序,不影响数据库)。
+            if (plan.getCompoList() != null && !plan.getCompoList().isEmpty() && recordList != null && !recordList.isEmpty()) {
+                // 以维修记录中的 compoId 作为“已勾选”的判断依据
+                // 注意:TRelMaintRecord.compoId 是 String,而 TRelCompo.compoId 是 Long,这里统一转换为 Long 进行匹配
+                Set<Long> checkedCompoIds = new HashSet<>();
+                for (TRelMaintRecord r : recordList) {
+                    if (r != null && r.getCompoId() != null) {
+                        try {
+                            checkedCompoIds.add(Long.parseLong(r.getCompoId()));
+                        } catch (NumberFormatException e) {
+                            // compoId 非数字时忽略(避免影响主流程)
+                        }
+                    }
+                }
+                // 排序规则:已勾选的在前,未勾选的在后;同组内不强制改变原有顺序
+                plan.getCompoList().sort((a, b) -> {
+                    boolean aChecked = a != null && a.getCompoId() != null && checkedCompoIds.contains(a.getCompoId());
+                    boolean bChecked = b != null && b.getCompoId() != null && checkedCompoIds.contains(b.getCompoId());
+                    return Boolean.compare(bChecked, aChecked);
+                });
+            }
         }
         
         return plan;
@@ -149,15 +174,18 @@ public class TRelMaintPlanServiceImpl implements ITRelMaintPlanService
     }
 
     @Override
-    public void syncMaintRecordsOnly(Long planId, List<TRelMaintRecord> maintComponents, Long operatorUserId)
+    public void syncMaintRecordsOnly(TRelMaintPlan tRelMaintPlan, Long operatorUserId)
     {
-        if (planId == null) {
+        if (tRelMaintPlan == null || tRelMaintPlan.getPlanId() == null) {
             throw new IllegalArgumentException("计划ID不能为空");
         }
-        if (maintComponents == null) {
+        if (tRelMaintPlan.getMaintComponents() == null) {
             throw new IllegalArgumentException("维修部件列表不能为空");
         }
 
+        Long planId = tRelMaintPlan.getPlanId();
+        List<TRelMaintRecord> maintComponents = tRelMaintPlan.getMaintComponents();
+
         TRelMaintPlan existing = tRelMaintPlanMapper.selectTRelMaintPlanById(planId);
         if (existing == null) {
             throw new IllegalArgumentException("维修计划不存在");
@@ -168,6 +196,19 @@ public class TRelMaintPlanServiceImpl implements ITRelMaintPlanService
             throw new IllegalStateException("仅计划中(9)的维修计划允许仅保存");
         }
 
+        TRelMaintPlan planUpdate = new TRelMaintPlan();
+        planUpdate.setPlanId(planId);
+        planUpdate.setPlanTime(tRelMaintPlan.getPlanTime());
+        planUpdate.setPlanEndTime(tRelMaintPlan.getPlanEndTime());
+        planUpdate.setResponsible(tRelMaintPlan.getResponsible());
+        planUpdate.setRemarks(tRelMaintPlan.getRemarks());
+        planUpdate.setApprover(tRelMaintPlan.getApprover());
+        if (operatorUserId != null) {
+            planUpdate.setUpdaterCode(String.valueOf(operatorUserId));
+        }
+        planUpdate.setUpdatedate(new Date());
+        tRelMaintPlanMapper.updateTRelMaintPlan(planUpdate);
+
         TRelMaintPlan planForSync = new TRelMaintPlan();
         planForSync.setPlant(existing.getPlant());
         planForSync.setDevName(existing.getDevName());
@@ -242,7 +283,7 @@ public class TRelMaintPlanServiceImpl implements ITRelMaintPlanService
                 if (!newMap.containsKey(compoId)) {
                     // 该记录在前端部件中不存在
                     if (existingRecord.getRecordStatus() != null) {
-                        if (existingRecord.getRecordStatus() == 0) {
+                        if (existingRecord.getRecordStatus() == 0 || existingRecord.getRecordStatus() == 9) {
                             // 新增申请中的记录,直接物理删除
                             tRelMaintRecordService.deleteTRelMaintRecordById(existingRecord.getRecordId());
                             logger.info("物理删除新增申请中的维修记录:compoId=" + compoId);

+ 47 - 1
master/src/main/java/com/ruoyi/project/reliability/service/impl/TRelMaintRecordServiceImpl.java

@@ -1,17 +1,22 @@
 package com.ruoyi.project.reliability.service.impl;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.project.reliability.mapper.TRelMaintRecordMapper;
 import com.ruoyi.project.reliability.mapper.TRelMaintPlanMapper;
 import com.ruoyi.project.reliability.mapper.TRelCompoMapper;
 import com.ruoyi.project.reliability.mapper.TRelMaintMemoMapper;
+import com.ruoyi.project.reliability.mapper.TRelThicknessMapper;
 import com.ruoyi.project.reliability.domain.TRelMaintRecord;
 import com.ruoyi.project.reliability.service.ITRelMaintRecordService;
 import com.ruoyi.project.reliability.domain.TRelMaintPlan;
 import com.ruoyi.project.reliability.domain.TRelCompo;
 import com.ruoyi.project.reliability.domain.TRelMaintMemo;
+import com.ruoyi.project.reliability.domain.TRelThickness;
 
 /**
  * 部件维修记录Service业务层处理
@@ -34,6 +39,9 @@ public class TRelMaintRecordServiceImpl implements ITRelMaintRecordService
     @Autowired
     private TRelMaintMemoMapper tRelMaintMemoMapper;
 
+    @Autowired
+    private TRelThicknessMapper tRelThicknessMapper;
+
     /**
      * 查询部件维修记录
      *
@@ -71,7 +79,9 @@ public class TRelMaintRecordServiceImpl implements ITRelMaintRecordService
     @Override
     public List<TRelMaintRecord> selectTRelMaintRecordByPlanId(Long planId)
     {
-        return tRelMaintRecordMapper.selectTRelMaintRecordByPlanId(planId);
+        List<TRelMaintRecord> list = tRelMaintRecordMapper.selectTRelMaintRecordByPlanId(planId);
+        fillThicknessList(list);
+        return list;
     }
 
     /**
@@ -101,6 +111,7 @@ public class TRelMaintRecordServiceImpl implements ITRelMaintRecordService
                 fillMemoInfo(record);
             }
         }
+        fillThicknessList(list);
         return list;
     }
 
@@ -194,6 +205,7 @@ public class TRelMaintRecordServiceImpl implements ITRelMaintRecordService
                 fillMemoInfo(record);
             }
         }
+        fillThicknessList(list);
         return list;
     }
 
@@ -212,4 +224,38 @@ public class TRelMaintRecordServiceImpl implements ITRelMaintRecordService
             }
         }
     }
+
+    private void fillThicknessList(List<TRelMaintRecord> list) {
+        if (list == null || list.isEmpty()) {
+            return;
+        }
+
+        List<Long> recordIds = new ArrayList<>();
+        for (TRelMaintRecord r : list) {
+            if (r != null && r.getRecordId() != null) {
+                recordIds.add(r.getRecordId());
+            }
+        }
+        if (recordIds.isEmpty()) {
+            return;
+        }
+
+        List<TRelThickness> thicknessList = tRelThicknessMapper.selectTRelThicknessByRecordIds(recordIds.toArray(new Long[0]));
+        if (thicknessList == null || thicknessList.isEmpty()) {
+            return;
+        }
+
+        Map<Long, List<TRelThickness>> grouped = new HashMap<>();
+        for (TRelThickness t : thicknessList) {
+            if (t != null && t.getRecordId() != null) {
+                grouped.computeIfAbsent(t.getRecordId(), k -> new ArrayList<>()).add(t);
+            }
+        }
+
+        for (TRelMaintRecord r : list) {
+            if (r != null && r.getRecordId() != null) {
+                r.setThicknessList(grouped.get(r.getRecordId()));
+            }
+        }
+    }
 }

+ 77 - 0
master/src/main/java/com/ruoyi/project/reliability/service/impl/TRelThicknessServiceImpl.java

@@ -0,0 +1,77 @@
+package com.ruoyi.project.reliability.service.impl;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.ruoyi.project.reliability.domain.TRelThickness;
+import com.ruoyi.project.reliability.mapper.TRelThicknessMapper;
+import com.ruoyi.project.reliability.service.ITRelThicknessService;
+
+@Service
+public class TRelThicknessServiceImpl implements ITRelThicknessService
+{
+    @Autowired
+    private TRelThicknessMapper tRelThicknessMapper;
+
+    @Override
+    public TRelThickness selectTRelThicknessById(Long thicknessId)
+    {
+        return tRelThicknessMapper.selectTRelThicknessById(thicknessId);
+    }
+
+    @Override
+    public List<TRelThickness> selectTRelThicknessList(TRelThickness tRelThickness)
+    {
+        return tRelThicknessMapper.selectTRelThicknessList(tRelThickness);
+    }
+
+    @Override
+    public List<TRelThickness> selectTRelThicknessByRecordIds(Long[] recordIds)
+    {
+        return tRelThicknessMapper.selectTRelThicknessByRecordIds(recordIds);
+    }
+
+    @Override
+    public List<TRelThickness> selectTRelThicknessByCompoIds(String[] compoIds)
+    {
+        return tRelThicknessMapper.selectTRelThicknessByCompoIds(compoIds);
+    }
+
+    @Override
+    public List<TRelThickness> selectTRelThicknessByRecordId(Long recordId)
+    {
+        return tRelThicknessMapper.selectTRelThicknessByRecordId(recordId);
+    }
+
+    @Override
+    public int insertTRelThickness(TRelThickness tRelThickness)
+    {
+        return tRelThicknessMapper.insertTRelThickness(tRelThickness);
+    }
+
+    @Override
+    public int updateTRelThickness(TRelThickness tRelThickness)
+    {
+        return tRelThicknessMapper.updateTRelThickness(tRelThickness);
+    }
+
+    @Override
+    public int deleteTRelThicknessById(Long thicknessId)
+    {
+        return tRelThicknessMapper.deleteTRelThicknessById(thicknessId);
+    }
+
+    @Override
+    public int deleteTRelThicknessByIds(Long[] thicknessIds)
+    {
+        return tRelThicknessMapper.deleteTRelThicknessByIds(thicknessIds);
+    }
+
+    @Override
+    public int deleteTRelThicknessByRecordId(Long recordId)
+    {
+        return tRelThicknessMapper.deleteTRelThicknessByRecordId(recordId);
+    }
+}

+ 8 - 1
master/src/main/resources/mybatis/reliability/TRelMaintRecordMapper.xml

@@ -70,7 +70,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="deptId != null "> and dept_id = #{deptId}</if>
             <if test="remarks != null  and remarks != ''"> and remarks = #{remarks}</if>
             <if test="planId != null "> and plan_id = #{planId}</if>
-            <if test="recordStatus != null"> and record_status = #{recordStatus}</if>
+            <if test="recordStatusCompleted != null and recordStatusCompleted == true">
+                <!-- 查询已完成的记录(包括已完成和已延期) -->
+                and (d.record_status = 2 or d.record_status = 3)
+            </if>
+            <if test="recordStatusCompleted == null or recordStatusCompleted == false">
+                <if test="recordStatus != null"> and d.record_status = #{recordStatus}</if>
+                <if test="recordStatusNot != null"> and d.record_status != #{recordStatusNot}</if>
+            </if>
             and d.del_flag = 0
         </where>
         <!-- 数据范围过滤 -->

+ 167 - 0
master/src/main/resources/mybatis/reliability/TRelThicknessMapper.xml

@@ -0,0 +1,167 @@
+<?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.project.reliability.mapper.TRelThicknessMapper">
+
+    <resultMap type="TRelThickness" id="TRelThicknessResult">
+        <result property="thicknessId" column="thickness_id" />
+        <result property="plant" column="plant" />
+        <result property="devName" column="dev_name" />
+        <result property="devTag" column="dev_tag" />
+        <result property="compoId" column="compo_id" />
+        <result property="compoName" column="compo_name" />
+        <result property="compoModel" column="compo_model" />
+        <result property="recordId" column="record_id" />
+        <result property="thicknessPt" column="thickness_pt" />
+        <result property="thicknessData" column="thickness_data" />
+        <result property="thicknessDate" column="thickness_date" />
+        <result property="delFlag" column="del_flag" />
+        <result property="createrCode" column="creater_code" />
+        <result property="createdate" column="createdate" />
+        <result property="updaterCode" column="updater_code" />
+        <result property="updatedate" column="updatedate" />
+        <result property="deptId" column="dept_id" />
+        <result property="remarks" column="remarks" />
+    </resultMap>
+
+    <sql id="selectTRelThicknessVo">
+        select t.thickness_id, t.plant, t.dev_name, t.dev_tag, t.compo_id, t.compo_name, t.compo_model, t.record_id, t.thickness_pt, t.thickness_data, t.thickness_date, t.del_flag, t.creater_code, t.createdate, t.updater_code, t.updatedate, t.dept_id, t.remarks
+        from t_rel_thickness t
+    </sql>
+
+    <select id="selectTRelThicknessList" parameterType="TRelThickness" resultMap="TRelThicknessResult">
+        <include refid="selectTRelThicknessVo"/>
+        <where>
+            <if test="thicknessId != null"> and t.thickness_id = #{thicknessId}</if>
+            <if test="plant != null  and plant != ''"> and t.plant = #{plant}</if>
+            <if test="devName != null  and devName != ''"> and t.dev_name like concat(concat('%', #{devName}), '%')</if>
+            <if test="devTag != null  and devTag != ''"> and t.dev_tag = #{devTag}</if>
+            <if test="compoId != null  and compoId != ''"> and t.compo_id = #{compoId}</if>
+            <if test="compoName != null  and compoName != ''"> and t.compo_name like concat(concat('%', #{compoName}), '%')</if>
+            <if test="compoModel != null  and compoModel != ''"> and t.compo_model = #{compoModel}</if>
+            <if test="recordId != null"> and t.record_id = #{recordId}</if>
+            <if test="thicknessPt != null  and thicknessPt != ''"> and t.thickness_pt = #{thicknessPt}</if>
+            <if test="thicknessDate != null"> and t.thickness_date = #{thicknessDate}</if>
+            and t.del_flag = 0
+        </where>
+        order by t.thickness_date desc, t.thickness_pt asc
+    </select>
+
+    <select id="selectTRelThicknessById" parameterType="Long" resultMap="TRelThicknessResult">
+        <include refid="selectTRelThicknessVo"/>
+        where t.thickness_id = #{thicknessId}
+    </select>
+
+    <select id="selectTRelThicknessByRecordId" parameterType="Long" resultMap="TRelThicknessResult">
+        <include refid="selectTRelThicknessVo"/>
+        where t.record_id = #{recordId}
+          and t.del_flag = 0
+        order by t.thickness_pt asc
+    </select>
+
+    <select id="selectTRelThicknessByRecordIds" parameterType="Long" resultMap="TRelThicknessResult">
+        <include refid="selectTRelThicknessVo"/>
+        where t.record_id in
+        <foreach item="recordId" collection="array" open="(" separator="," close=")">
+            #{recordId}
+        </foreach>
+          and t.del_flag = 0
+        order by t.record_id asc, t.thickness_pt asc
+    </select>
+
+    <select id="selectTRelThicknessByCompoIds" parameterType="String" resultMap="TRelThicknessResult">
+        <include refid="selectTRelThicknessVo"/>
+        where t.compo_id in
+        <foreach item="compoId" collection="array" open="(" separator="," close=")">
+            #{compoId}
+        </foreach>
+          and t.del_flag = 0
+        order by t.compo_id asc, t.thickness_date desc, t.thickness_pt asc
+    </select>
+
+    <insert id="insertTRelThickness" parameterType="TRelThickness">
+        <selectKey keyProperty="thicknessId" resultType="long" order="BEFORE">
+            SELECT seq_t_rel_thickness.NEXTVAL as thicknessId FROM DUAL
+        </selectKey>
+        insert into t_rel_thickness
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="thicknessId != null">thickness_id,</if>
+            <if test="plant != null">plant,</if>
+            <if test="devName != null">dev_name,</if>
+            <if test="devTag != null">dev_tag,</if>
+            <if test="compoId != null">compo_id,</if>
+            <if test="compoName != null">compo_name,</if>
+            <if test="compoModel != null">compo_model,</if>
+            <if test="recordId != null">record_id,</if>
+            <if test="thicknessPt != null">thickness_pt,</if>
+            <if test="thicknessData != null">thickness_data,</if>
+            <if test="thicknessDate != null">thickness_date,</if>
+            <if test="delFlag != null">del_flag,</if>
+            <if test="createrCode != null">creater_code,</if>
+            <if test="createdate != null">createdate,</if>
+            <if test="updaterCode != null">updater_code,</if>
+            <if test="updatedate != null">updatedate,</if>
+            <if test="deptId != null">dept_id,</if>
+            <if test="remarks != null">remarks,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="thicknessId != null">#{thicknessId},</if>
+            <if test="plant != null">#{plant},</if>
+            <if test="devName != null">#{devName},</if>
+            <if test="devTag != null">#{devTag},</if>
+            <if test="compoId != null">#{compoId},</if>
+            <if test="compoName != null">#{compoName},</if>
+            <if test="compoModel != null">#{compoModel},</if>
+            <if test="recordId != null">#{recordId},</if>
+            <if test="thicknessPt != null">#{thicknessPt},</if>
+            <if test="thicknessData != null">#{thicknessData},</if>
+            <if test="thicknessDate != null">#{thicknessDate},</if>
+            <if test="delFlag != null">#{delFlag},</if>
+            <if test="createrCode != null">#{createrCode},</if>
+            <if test="createdate != null">#{createdate},</if>
+            <if test="updaterCode != null">#{updaterCode},</if>
+            <if test="updatedate != null">#{updatedate},</if>
+            <if test="deptId != null">#{deptId},</if>
+            <if test="remarks != null">#{remarks},</if>
+        </trim>
+    </insert>
+
+    <update id="updateTRelThickness" parameterType="TRelThickness">
+        update t_rel_thickness
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="plant != null">plant = #{plant},</if>
+            <if test="devName != null">dev_name = #{devName},</if>
+            <if test="devTag != null">dev_tag = #{devTag},</if>
+            <if test="compoId != null">compo_id = #{compoId},</if>
+            <if test="compoName != null">compo_name = #{compoName},</if>
+            <if test="compoModel != null">compo_model = #{compoModel},</if>
+            <if test="recordId != null">record_id = #{recordId},</if>
+            <if test="thicknessPt != null">thickness_pt = #{thicknessPt},</if>
+            <if test="thicknessData != null">thickness_data = #{thicknessData},</if>
+            <if test="thicknessDate != null">thickness_date = #{thicknessDate},</if>
+            <if test="delFlag != null">del_flag = #{delFlag},</if>
+            <if test="updaterCode != null">updater_code = #{updaterCode},</if>
+            <if test="updatedate != null">updatedate = #{updatedate},</if>
+            <if test="deptId != null">dept_id = #{deptId},</if>
+            <if test="remarks != null">remarks = #{remarks},</if>
+        </trim>
+        where thickness_id = #{thicknessId}
+    </update>
+
+    <update id="deleteTRelThicknessById" parameterType="Long">
+        update t_rel_thickness set del_flag = 2 where thickness_id = #{thicknessId}
+    </update>
+
+    <update id="deleteTRelThicknessByIds" parameterType="String">
+        update t_rel_thickness set del_flag = 2 where thickness_id in
+        <foreach item="thicknessId" collection="array" open="(" separator="," close=")">
+            #{thicknessId}
+        </foreach>
+    </update>
+
+    <delete id="deleteTRelThicknessByRecordId" parameterType="Long">
+        delete from t_rel_thickness where record_id = #{recordId}
+    </delete>
+
+</mapper>

+ 8 - 0
ui/src/api/reliability/rel_maint_record.js

@@ -60,3 +60,11 @@ export function listMyRel_maint_record(query) {
     params: query
   })
 }
+
+// 下载模板
+export function importTemplate() {
+  return request({
+    url: '/reliability/rel_maint_record/importTemplate',
+    method: 'post'
+  })
+}

+ 2 - 2
ui/src/views/login.vue

@@ -324,8 +324,8 @@ export default {
   justify-content: center;
   align-items: center;
   height: 100%;
-  background-image: url("../assets/image/CPMS20210107.jpg");
-  //background-image: url("../assets/image/cpms-test.jpg");
+  //background-image: url("../assets/image/CPMS20210107.jpg");
+  background-image: url("../assets/image/cpms-test.jpg");
   background-size: cover;
 }
 

+ 69 - 31
ui/src/views/reliability/rel_compo/index.vue

@@ -134,6 +134,19 @@
       </el-table-column>
       <el-table-column label="部件型号" align="center" prop="compoModel" width="150" :show-overflow-tooltip="true"/>
       <el-table-column label="测厚点" align="center" prop="thicknessPt" width="120" :show-overflow-tooltip="true"/>
+      <el-table-column label="测厚记录" align="center" width="110">
+        <template slot-scope="scope">
+          <el-button
+            v-if="scope.row.thicknessList && scope.row.thicknessList.length"
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleViewThickness(scope.row)">
+            查看({{ scope.row.thicknessList.length }})
+          </el-button>
+          <span v-else>-</span>
+        </template>
+      </el-table-column>
       <el-table-column label="部件描述" align="center" prop="compoDesc" width="180" :show-overflow-tooltip="true"/>
       <el-table-column label="部件照片" align="center" prop="compoPhoto" width="100">
         <template slot-scope="scope">
@@ -430,37 +443,55 @@
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
-      <!-- 用户导入对话框 -->
-      <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
-          <el-upload
-                  ref="upload"
-                  :limit="1"
-                  accept=".xlsx, .xls"
-                  :headers="upload.headers"
-                  :action="upload.url + '?updateSupport=1'"
-                  :disabled="upload.isUploading"
-                  :on-progress="handleFileUploadProgress"
-                  :on-success="handleFileSuccess"
-                  :auto-upload="false"
-                  drag
-          >
-              <i class="el-icon-upload"></i>
-              <div class="el-upload__text">
-                  将文件拖到此处,或
-                  <em>点击上传</em>
-              </div>
-              <div class="el-upload__tip" slot="tip">
-                  <el-link type="info" style="font-size:12px" @click="importTemplate">下载模板</el-link>
-                  <form ref="downloadFileForm" :action="upload.downloadAction" target="FORMSUBMIT">
-                    <input name="type" :value="upload.type" hidden/>
-                  </form>
-              </div>
-              <div class="el-upload__tip" style="color:red" slot="tip">提示:仅允许导入“xls”或“xlsx”格式文件!</div>
-          </el-upload>
-          <div slot="footer" class="dialog-footer">
-              <el-button type="primary" @click="submitFileForm">确 定</el-button>
-              <el-button @click="upload.open = false">取 消</el-button>
-          </div>
+    <!-- 用户导入对话框 -->
+    <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
+      <el-upload
+        ref="upload"
+        :limit="1"
+        accept=".xlsx, .xls"
+        :headers="upload.headers"
+        :action="upload.url + '?updateSupport=1'"
+        :disabled="upload.isUploading"
+        :on-progress="handleFileUploadProgress"
+        :on-success="handleFileSuccess"
+        :auto-upload="false"
+        drag
+      >
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">
+          将文件拖到此处,或
+          <em>点击上传</em>
+        </div>
+        <div class="el-upload__tip" slot="tip">
+          <el-link type="info" style="font-size:12px" @click="importTemplate">下载模板</el-link>
+          <form ref="downloadFileForm" :action="upload.downloadAction" target="FORMSUBMIT">
+            <input name="type" :value="upload.type" hidden/>
+          </form>
+        </div>
+        <div class="el-upload__tip" style="color:red" slot="tip">提示:仅允许导入“xls”或“xlsx”格式文件!</div>
+      </el-upload>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitFileForm">确 定</el-button>
+        <el-button @click="upload.open = false">取 消</el-button>
+      </div>
+    </el-dialog>
+
+      <el-dialog title="测厚记录" :visible.sync="thicknessDialogVisible" width="650px" append-to-body>
+        <el-table :data="thicknessViewList" border size="small">
+          <el-table-column label="序号" type="index" width="60" align="center" />
+          <el-table-column label="测厚点" prop="thicknessPt" width="180" :show-overflow-tooltip="true" />
+          <el-table-column label="测厚日期" width="140" align="center">
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.thicknessDate, '{y}-{m}-{d}') }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="测厚数据" prop="thicknessData" width="120" align="center" />
+          <el-table-column label="备注" prop="remarks" :show-overflow-tooltip="true" />
+        </el-table>
+        <div v-if="thicknessViewList.length === 0" style="text-align: center; color: #999; padding: 20px;">暂无测厚记录</div>
+        <div slot="footer" class="dialog-footer">
+          <el-button @click="thicknessDialogVisible = false">关 闭</el-button>
+        </div>
       </el-dialog>
 
       <!-- 图片预览对话框 -->
@@ -539,6 +570,8 @@ export default {
       // 图片预览相关
       photoPreviewVisible: false,
       previewPhotoUrl: '',
+      thicknessDialogVisible: false,
+      thicknessViewList: [],
       // 频率拆分数据
       inspFreqNumber: null,
       inspFreqUnit: 'y',
@@ -867,6 +900,11 @@ export default {
         }
       },
 
+      handleViewThickness(row) {
+        this.thicknessViewList = (row && row.thicknessList) ? row.thicknessList : [];
+        this.thicknessDialogVisible = true;
+      },
+
       /** 根据人员ID获取人员姓名 */
       getStaffName(staffId) {
         if (!staffId) return '-';

+ 51 - 1
ui/src/views/reliability/rel_device/detail.vue

@@ -76,6 +76,19 @@
                   <el-tag v-if="scope.row.hasMemo" type="warning" size="mini" style="margin-left: 6px;">备</el-tag>
                 </template>
               </el-table-column>
+              <el-table-column label="测厚记录" align="center" width="110">
+                <template slot-scope="scope">
+                  <el-button
+                    v-if="scope.row.thicknessList && scope.row.thicknessList.length"
+                    size="mini"
+                    type="text"
+                    icon="el-icon-view"
+                    @click="handleViewThickness(scope.row)">
+                    查看({{ scope.row.thicknessList.length }})
+                  </el-button>
+                  <span v-else>-</span>
+                </template>
+              </el-table-column>
               <el-table-column label="检查频率" align="center" prop="inspFreq" width="110" :show-overflow-tooltip="true">
                 <template slot-scope="scope">
                   {{ translateFrequency(scope.row.inspFreq) }}
@@ -135,6 +148,18 @@
                   <span>{{ parseTime(scope.row.inspectTime, '{y}-{m}-{d}') }}</span>
                 </template>
               </el-table-column>
+              <el-table-column label="测厚记录" align="center" width="110">
+                <template slot-scope="scope">
+                  <el-button
+                    v-if="scope.row.thicknessList && scope.row.thicknessList.length"
+                    type="text"
+                    icon="el-icon-view"
+                    @click="handleViewThickness(scope.row)">
+                    查看({{ scope.row.thicknessList.length }})
+                  </el-button>
+                  <span v-else>-</span>
+                </template>
+              </el-table-column>
               <el-table-column label="维修内容" align="center" prop="maintContent" width="150" :show-overflow-tooltip="true"/>
               <el-table-column label="维修时间" align="center" prop="maintTime" width="120">
                 <template slot-scope="scope">
@@ -161,6 +186,24 @@
       </div>
     </div>
 
+    <el-dialog title="测厚记录" :visible.sync="thicknessDialogVisible" width="650px" append-to-body>
+      <el-table :data="thicknessViewList" border size="small">
+        <el-table-column label="序号" type="index" width="60" align="center" />
+        <el-table-column label="测厚点" prop="thicknessPt" width="180" :show-overflow-tooltip="true" />
+        <el-table-column label="测厚日期" width="140" align="center">
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.thicknessDate, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="测厚数据" prop="thicknessData" width="120" align="center" />
+        <el-table-column label="备注" prop="remarks" :show-overflow-tooltip="true" />
+      </el-table>
+      <div v-if="thicknessViewList.length === 0" style="text-align: center; color: #999; padding: 20px;">暂无测厚记录</div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="thicknessDialogVisible = false">关 闭</el-button>
+      </span>
+    </el-dialog>
+
     <!-- 部件详情对话框 -->
     <el-dialog :visible.sync="compoDialogVisible" width="900px" append-to-body class="compo-detail-dialog">
       <template slot="title">
@@ -270,7 +313,9 @@ export default {
       compoDialogVisible: false,
       selectedCompo: null,
       compoMaintRecordList: [],
-      compoMaintRecordLoading: false
+      compoMaintRecordLoading: false,
+      thicknessDialogVisible: false,
+      thicknessViewList: []
     }
   },
   created() {
@@ -335,6 +380,11 @@ export default {
       this.loadCompoMaintRecords(compo.compoName);
     },
 
+    handleViewThickness(row) {
+      this.thicknessViewList = (row && row.thicknessList) ? row.thicknessList : [];
+      this.thicknessDialogVisible = true;
+    },
+
     // 加载部件维修记录
     async loadCompoMaintRecords(compoName) {
       try {

+ 6 - 1
ui/src/views/reliability/rel_maint_plan/form.vue

@@ -9,7 +9,7 @@
         <el-button icon="el-icon-arrow-left" @click="goBack">返回</el-button>
         <el-button v-if="formData.planId && isPlannedStatus" @click="handleSaveOnly" :loading="savingOnly">仅保存</el-button>
         <el-button type="primary" @click="handleSubmit" :loading="submitting">
-          {{ isPlannedStatus ? '提交申请' : (formData.planId && formData.approvalStatus === '1' ? '再次提交申请' : '确 定') }}
+          {{ isPlannedStatus ? '提交申请' : (!formData.planId ? '提交申请' : (formData.approvalStatus === '1' ? '再次提交申请' : '确 定')) }}
         </el-button>
       </div>
     </div>
@@ -420,6 +420,11 @@ export default {
 
       saveOnlyRel_maint_plan({
         planId: this.formData.planId,
+        planTime: this.formData.planTime,
+        planEndTime: this.formData.planEndTime,
+        responsible: this.formData.responsible,
+        remarks: this.formData.remarks,
+        approver: this.formData.approver,
         maintComponents: this.formData.maintComponents
       }).then(() => {
         this.$message.success("保存成功");

+ 12 - 4
ui/src/views/reliability/rel_maint_plan/index.vue

@@ -479,7 +479,9 @@ export default {
         ...this.queryParams,
         completionStatus: '9',
         pageNum: this.plannedPage.pageNum,
-        pageSize: this.plannedPage.pageSize
+        pageSize: this.plannedPage.pageSize,
+        orderByColumn: 'planTime',
+        isAsc: 'asc'
       }).then(response => {
         this.plannedList = response.rows;
         this.plannedTotal = response.total;
@@ -494,7 +496,9 @@ export default {
         ...this.queryParams,
         completionStatus: '0',
         pageNum: this.incompletePage.pageNum,
-        pageSize: this.incompletePage.pageSize
+        pageSize: this.incompletePage.pageSize,
+        orderByColumn: 'planTime',
+        isAsc: 'desc'
       }).then(response => {
         this.incompleteList = response.rows;
         this.incompleteTotal = response.total;
@@ -509,7 +513,9 @@ export default {
         ...this.queryParams,
         completionStatus: '1',
         pageNum: this.completedPage.pageNum,
-        pageSize: this.completedPage.pageSize
+        pageSize: this.completedPage.pageSize,
+        orderByColumn: 'planTime',
+        isAsc: 'desc'
       }).then(response => {
         this.completedList = response.rows;
         this.completedTotal = response.total;
@@ -524,7 +530,9 @@ export default {
         ...this.queryParams,
         completionStatus: '-1',
         pageNum: this.rejectedPage.pageNum,
-        pageSize: this.rejectedPage.pageSize
+        pageSize: this.rejectedPage.pageSize,
+        orderByColumn: 'planTime',
+        isAsc: 'desc'
       }).then(response => {
         this.rejectedList = response.rows;
         this.rejectedTotal = response.total;

+ 291 - 21
ui/src/views/reliability/rel_maint_record/index.vue

@@ -1,6 +1,12 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-tabs v-model="activeTab" class="compact-tabs">
+      <el-tab-pane label="维修记录" name="record" />
+      <el-tab-pane label="维修备忘录" name="memo" />
+    </el-tabs>
+
+    <div v-show="activeTab === 'record'">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="recordShowSearch" label-width="68px">
       <el-form-item label="装置" prop="plant">
         <el-input
           v-model="queryParams.plant"
@@ -46,10 +52,6 @@
       </el-form-item>
       <el-form-item label="维修状态" prop="recordStatus">
         <el-select v-model="queryParams.recordStatus" placeholder="请选择维修状态" clearable size="small">
-          <el-option label="计划中" value="9" />
-          <el-option label="删除申请中" value="-1" />
-          <el-option label="新增申请中" value="0" />
-          <el-option label="待完成" value="1" />
           <el-option label="已完成" value="2" />
           <el-option label="已延期" value="3" />
         </el-select>
@@ -63,9 +65,10 @@
       </el-form-item>
     </el-form>
 
-    <el-row :gutter="10" class="mb8">
+    <el-row :gutter="10" class="mb8 compact-row">
       <el-col :span="1.5">
         <el-button
+          class="compact-button"
           type="success"
           icon="el-icon-edit"
           size="mini"
@@ -76,6 +79,7 @@
       </el-col>
       <el-col :span="1.5">
         <el-button
+          class="compact-button"
           type="danger"
           icon="el-icon-delete"
           size="mini"
@@ -86,6 +90,7 @@
       </el-col>
       <el-col :span="1.5">
         <el-button
+          class="compact-button"
           type="warning"
           icon="el-icon-download"
           size="mini"
@@ -93,15 +98,7 @@
           v-hasPermi="['reliability:rel_maint_record:list']"
         >导出</el-button>
       </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="info"
-          icon="el-icon-document"
-          size="mini"
-          @click="handleViewMemoList"
-        >查看维修备忘录</el-button>
-      </el-col>
-	  <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+	  <right-toolbar :showSearch.sync="recordShowSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
     <el-table v-loading="loading" :data="rel_maint_recordList" @selection-change="handleSelectionChange" :height="clientHeight" border>
@@ -159,6 +156,19 @@
         </template>
       </el-table-column>
 
+      <el-table-column label="测厚记录" align="center" width="110">
+        <template slot-scope="scope">
+          <el-button
+            v-if="scope.row.thicknessList && scope.row.thicknessList.length"
+            type="text"
+            icon="el-icon-view"
+            @click="handleViewThickness(scope.row)">
+            查看({{ scope.row.thicknessList.length }})
+          </el-button>
+          <span v-else>-</span>
+        </template>
+      </el-table-column>
+
       <el-table-column label="维修部门" align="center" prop="maintDept" :show-overflow-tooltip="true"/>
       <el-table-column label="维修内容" align="center" prop="maintContent" :show-overflow-tooltip="true"/>
       <el-table-column label="维修结果" align="center" prop="maintResult" :show-overflow-tooltip="true"/>
@@ -200,6 +210,7 @@
         <template slot-scope="scope">
           <el-button
             size="mini"
+            class="compact-link"
             type="text"
             icon="el-icon-edit"
             @click="handleUpdate(scope.row)"
@@ -207,6 +218,7 @@
           >修改</el-button>
           <el-button
             size="mini"
+            class="compact-link"
             type="text"
             icon="el-icon-delete"
             @click="handleDelete(scope.row)"
@@ -224,6 +236,139 @@
       @pagination="getList"
     />
 
+    </div>
+
+    <div v-show="activeTab === 'memo'">
+    <el-form :model="memoQueryParams" ref="memoQueryForm" :inline="true" v-show="memoShowSearch" label-width="68px">
+      <el-form-item label="装置" prop="plant">
+        <el-input
+          v-model="memoQueryParams.plant"
+          placeholder="请输入装置"
+          clearable
+          size="small"
+          @keyup.enter.native="handleMemoQuery"
+        />
+      </el-form-item>
+      <el-form-item label="设备名称" prop="devName">
+        <el-input
+          v-model="memoQueryParams.devName"
+          placeholder="请输入设备名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleMemoQuery"
+        />
+      </el-form-item>
+      <el-form-item label="设备位号" prop="devTag">
+        <el-input
+          v-model="memoQueryParams.devTag"
+          placeholder="请输入设备位号"
+          clearable
+          size="small"
+          @keyup.enter.native="handleMemoQuery"
+        />
+      </el-form-item>
+      <el-form-item label="部件名称" prop="compoName">
+        <el-input
+          v-model="memoQueryParams.compoName"
+          placeholder="请输入部件名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleMemoQuery"
+        />
+      </el-form-item>
+      <el-form-item label="维修类型" prop="maintType">
+        <el-select v-model="memoQueryParams.maintType" placeholder="请选择维修类型" clearable size="small">
+          <el-option label="检查" value="1" />
+          <el-option label="维修" value="2" />
+          <el-option label="更换" value="3" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="维修责任人" prop="responsible">
+        <el-input
+          v-model="memoQueryParams.responsible"
+          placeholder="请输入维修责任人"
+          clearable
+          size="small"
+          @keyup.enter.native="handleMemoQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleMemoQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetMemoQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8 compact-row">
+      <el-col :span="1.5">
+        <el-button
+          class="compact-button"
+          type="danger"
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="memoMultiple"
+          @click="handleMemoDelete"
+          v-hasPermi="['reliability:rel_maint_record:remove']"
+        >删除</el-button>
+      </el-col>
+	  <right-toolbar :showSearch.sync="memoShowSearch" @queryTable="getMemoList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="memoLoading" :data="rel_maint_memoList" @selection-change="handleMemoSelectionChange" :height="clientHeight" border>
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="装置" align="center" prop="plant" :show-overflow-tooltip="true"/>
+      <el-table-column label="设备名称" align="center" prop="devName" :show-overflow-tooltip="true"/>
+      <el-table-column label="设备位号" align="center" prop="devTag" :show-overflow-tooltip="true"/>
+      <el-table-column label="部件名称" align="center" prop="compoName" :show-overflow-tooltip="true"/>
+      <el-table-column label="维修类型" align="center" width="100">
+        <template slot-scope="scope">
+          <span v-if="scope.row.maintType === '1'">检查</span>
+          <span v-else-if="scope.row.maintType === '2'">维修</span>
+          <span v-else-if="scope.row.maintType === '3'">更换</span>
+          <span v-else>{{ scope.row.maintType || '-' }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="维修责任人" align="center" width="120">
+        <template slot-scope="scope">
+          <span>{{ getStaffNameById(scope.row.responsible) || '-' }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="维修内容" align="center" prop="maintContent" :show-overflow-tooltip="true"/>
+      <el-table-column label="备忘原因" align="center" prop="memoReason" :show-overflow-tooltip="true"/>
+      <el-table-column label="备忘时间" align="center" prop="memoTime" width="100">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.memoTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="备注" align="center" prop="remarks" :show-overflow-tooltip="true"/>
+      <el-table-column label="操作" align="center" fixed="right" width="120" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleViewMemo(scope.row)">
+            查看
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleMemoDelete(scope.row)"
+            v-hasPermi="['reliability:rel_maint_record:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="memoTotal>0"
+      :total="memoTotal"
+      :page.sync="memoQueryParams.pageNum"
+      :limit.sync="memoQueryParams.pageSize"
+      @pagination="getMemoList"
+    />
+    </div>
+
     <!-- 添加或修改部件维修记录对话框 -->
     <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
       <el-form ref="form" :model="form" :rules="rules" label-width="80px">
@@ -379,6 +524,24 @@
       </div>
     </el-dialog>
 
+    <el-dialog title="测厚记录" :visible.sync="thicknessDialogVisible" width="650px" append-to-body>
+      <el-table :data="thicknessViewList" border size="small">
+        <el-table-column label="序号" type="index" width="60" align="center" />
+        <el-table-column label="测厚点" prop="thicknessPt" width="180" :show-overflow-tooltip="true" />
+        <el-table-column label="测厚日期" width="140" align="center">
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.thicknessDate, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="测厚数据" prop="thicknessData" width="120" align="center" />
+        <el-table-column label="备注" prop="remarks" :show-overflow-tooltip="true" />
+      </el-table>
+      <div v-if="thicknessViewList.length === 0" style="text-align: center; color: #999; padding: 20px;">暂无测厚记录</div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="thicknessDialogVisible = false">关 闭</el-button>
+      </div>
+    </el-dialog>
+
     <!-- 照片预览对话框 -->
     <el-dialog title="照片预览" :visible.sync="photoPreviewVisible" width="800px" append-to-body>
       <div class="photo-preview-container">
@@ -449,7 +612,7 @@
 
 <script>
 import { listRel_maint_record, getRel_maint_record, delRel_maint_record, addRel_maint_record, updateRel_maint_record, exportRel_maint_record, importTemplate} from "@/api/reliability/rel_maint_record";
-import { getRel_maint_memo } from "@/api/reliability/rel_maint_memo";
+import { listRel_maint_memo, delRel_maint_memo } from "@/api/reliability/rel_maint_memo";
 import { treeselect } from "@/api/system/dept";
 import { getToken } from "@/utils/auth";
 import { listStaffmgrAll } from "@/api/plant/staffmgr";
@@ -464,6 +627,7 @@ export default {
   // components: { Editor },
   data() {
     return {
+      activeTab: 'record',
       // 遮罩层
       loading: true,
       // 选中数组
@@ -473,11 +637,19 @@ export default {
       // 非多个禁用
       multiple: true,
       // 显示搜索条件
-      showSearch: false,
+      recordShowSearch: false,
+      memoShowSearch: false,
       // 总条数
       total: 0,
       // 部件维修记录表格数据
       rel_maint_recordList: [],
+
+      // 维修备忘录tab
+      memoLoading: false,
+      memoTotal: 0,
+      rel_maint_memoList: [],
+      memoIds: [],
+      memoMultiple: true,
       // 弹出层标题
       title: "",
       // 部门树选项
@@ -528,7 +700,20 @@ export default {
         updatedate: null,
         deptId: null,
         remarks: null,
-        recordStatus: null
+        recordStatus: null,
+        // 仅查询已完成/已延期(由后端 SQL 处理)
+        recordStatusCompleted: true
+      },
+
+      memoQueryParams: {
+        pageNum: 1,
+        pageSize: 20,
+        plant: null,
+        devName: null,
+        devTag: null,
+        compoName: null,
+        maintType: null,
+        responsible: null
       },
       // 表单参数
       form: {},
@@ -541,6 +726,8 @@ export default {
       // 维修计划详情对话框
       planDetailVisible: false,
       planDetailId: null,
+      thicknessDialogVisible: false,
+      thicknessViewList: [],
       // 照片预览对话框
       photoPreviewVisible: false,
       previewPhotoList: [],
@@ -556,6 +743,12 @@ export default {
         deptName(val) {
             this.$refs.tree.filter(val);
         }
+        ,
+        activeTab(val) {
+          if (val === 'memo' && this.rel_maint_memoList.length === 0) {
+            this.getMemoList();
+          }
+        }
    },
   created() {
       //设置表格高度对应屏幕高度
@@ -576,6 +769,18 @@ export default {
         this.loading = false;
       });
     },
+
+    /** 查询维修备忘录列表 */
+    getMemoList() {
+      this.memoLoading = true;
+      listRel_maint_memo(this.memoQueryParams).then(response => {
+        this.rel_maint_memoList = response.rows;
+        this.memoTotal = response.total;
+        this.memoLoading = false;
+      }).catch(() => {
+        this.memoLoading = false;
+      });
+    },
      /** 查询部门下拉树结构 */
      getTreeselect() {
           treeselect().then(response => {
@@ -662,6 +867,11 @@ export default {
       this.viewAttachmentList = this.parseFileList(attachments, 'file');
       this.attachmentDialogVisible = true;
     },
+
+    handleViewThickness(row) {
+      this.thicknessViewList = (row && row.thicknessList) ? row.thicknessList : [];
+      this.thicknessDialogVisible = true;
+    },
     /** 下载附件 */
     downloadAttachment(file) {
       if (file.url) {
@@ -722,12 +932,30 @@ export default {
       this.resetForm("queryForm");
       this.handleQuery();
     },
+
+    /** 备忘录tab - 搜索按钮操作 */
+    handleMemoQuery() {
+      this.memoQueryParams.pageNum = 1;
+      this.getMemoList();
+    },
+
+    /** 备忘录tab - 重置按钮操作 */
+    resetMemoQuery() {
+      this.resetForm("memoQueryForm");
+      this.handleMemoQuery();
+    },
     // 多选框选中数据
     handleSelectionChange(selection) {
       this.ids = selection.map(item => item.recordId)
       this.single = selection.length!==1
       this.multiple = !selection.length
     },
+
+    // 备忘录tab - 多选框选中数据
+    handleMemoSelectionChange(selection) {
+      this.memoIds = selection.map(item => item.memoId)
+      this.memoMultiple = !selection.length
+    },
     /** 新增按钮操作 */
     handleAdd() {
       this.reset();
@@ -791,9 +1019,20 @@ export default {
           this.download(response.msg);
         })
     },
-    /** 查看维修备忘录列表页面 */
-    handleViewMemoList() {
-      this.$router.push({ path: '/reliability/rel_maint_memo' });
+
+    /** 备忘录tab - 删除按钮操作 */
+    handleMemoDelete(row) {
+      const memoIds = row && row.memoId ? row.memoId : this.memoIds;
+      this.$confirm('是否确认删除?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delRel_maint_memo(memoIds);
+        }).then(() => {
+          this.getMemoList();
+          this.msgSuccess("删除成功");
+        })
     },
       /** 导入按钮操作 */
       handleImport() {
@@ -827,6 +1066,37 @@ export default {
 </script>
 
 <style scoped>
+.app-container {
+  /* 仅当前页面收紧顶部留白 */
+  padding-top: 8px;
+}
+
+/* 适度压缩标签与内容的上下间距 */
+.compact-tabs {
+  margin-bottom: 4px;
+}
+
+/* 覆盖 el-tabs 默认 header 间距 */
+.compact-tabs >>> .el-tabs__header {
+  margin-bottom: 4px;
+}
+
+.compact-row {
+  margin-bottom: 4px;
+}
+
+.compact-button {
+  /* 仅用于减少上下留白时的外边距,不改变默认按钮尺寸 */
+  margin-top: 0;
+  margin-bottom: 0;
+}
+
+.compact-link {
+  /* 保持链接按钮尺寸,压缩上下空隙 */
+  margin-top: 0;
+  margin-bottom: 0;
+}
+
 /* 照片预览容器样式 */
 .photo-preview-container {
   display: flex;

+ 155 - 2
ui/src/views/reliability/rel_maint_record/myRecord.vue

@@ -90,6 +90,19 @@
         </template>
       </el-table-column>
       <el-table-column label="检查内容" align="center" prop="inspectContent" :show-overflow-tooltip="true"/>
+
+      <el-table-column label="测厚记录" align="center" width="110">
+        <template slot-scope="scope">
+          <el-button
+            v-if="scope.row.thicknessList && scope.row.thicknessList.length"
+            type="text"
+            icon="el-icon-view"
+            @click="handleViewThickness(scope.row)">
+            查看({{ scope.row.thicknessList.length }})
+          </el-button>
+          <span v-else>-</span>
+        </template>
+      </el-table-column>
       <el-table-column label="维修时间" align="center" prop="maintTime" width="100">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.maintTime, '{y}-{m}-{d}') }}</span>
@@ -197,6 +210,19 @@
               </template>
             </el-table-column>
             <el-table-column label="检查内容" align="center" prop="inspectContent" :show-overflow-tooltip="true"/>
+
+            <el-table-column label="测厚记录" align="center" width="110">
+              <template slot-scope="scope">
+                <el-button
+                  v-if="scope.row.thicknessList && scope.row.thicknessList.length"
+                  type="text"
+                  icon="el-icon-view"
+                  @click="handleViewThickness(scope.row)">
+                  查看({{ scope.row.thicknessList.length }})
+                </el-button>
+                <span v-else>-</span>
+              </template>
+            </el-table-column>
             <el-table-column label="维修时间" align="center" prop="maintTime" width="100">
               <template slot-scope="scope">
                 <span>{{ parseTime(scope.row.maintTime, '{y}-{m}-{d}') }}</span>
@@ -273,6 +299,33 @@
           <el-form-item label="检查内容" prop="inspectContent">
             <el-input v-model="processForm.inspectContent" type="textarea" :rows="5" placeholder="请输入检查内容" />
           </el-form-item>
+          <el-form-item label="测厚记录" v-if="processForm.thicknessList && processForm.thicknessList.length">
+            <el-table :data="processForm.thicknessList" border size="small">
+              <el-table-column label="测厚点" prop="thicknessPt" width="160" :show-overflow-tooltip="true" />
+              <el-table-column label="测厚日期" width="160">
+                <template slot-scope="scope">
+                  <el-date-picker
+                    clearable
+                    style="width: 100%"
+                    v-model="scope.row.thicknessDate"
+                    type="date"
+                    value-format="yyyy-MM-dd"
+                    placeholder="选择日期">
+                  </el-date-picker>
+                </template>
+              </el-table-column>
+              <el-table-column label="测厚数据" width="180">
+                <template slot-scope="scope">
+                  <el-input-number
+                    v-model="scope.row.thicknessData"
+                    :min="0"
+                    :precision="3"
+                    :step="0.001"
+                    style="width: 100%" />
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-form-item>
           <el-form-item label="是否需要维修/更换">
             <el-checkbox v-model="processForm.needMaintOrReplace">发现需要维修或更换</el-checkbox>
           </el-form-item>
@@ -452,6 +505,33 @@
               </el-col>
             </el-row>
           </template>
+          <el-form-item label="测厚记录" v-if="processForm.thicknessList && processForm.thicknessList.length">
+            <el-table :data="processForm.thicknessList" border size="small">
+              <el-table-column label="测厚点" prop="thicknessPt" width="160" :show-overflow-tooltip="true" />
+              <el-table-column label="测厚日期" width="160">
+                <template slot-scope="scope">
+                  <el-date-picker
+                    clearable
+                    style="width: 100%"
+                    v-model="scope.row.thicknessDate"
+                    type="date"
+                    value-format="yyyy-MM-dd"
+                    placeholder="选择日期">
+                  </el-date-picker>
+                </template>
+              </el-table-column>
+              <el-table-column label="测厚数据" width="180">
+                <template slot-scope="scope">
+                  <el-input-number
+                    v-model="scope.row.thicknessData"
+                    :min="0"
+                    :precision="3"
+                    :step="0.001"
+                    style="width: 100%" />
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-form-item>
           <el-form-item label="照片" prop="photoUrl">
             <el-upload
               class="upload-demo"
@@ -566,11 +646,29 @@
       </div>
     </el-dialog>
 
+    <el-dialog title="测厚记录" :visible.sync="thicknessDialogVisible" width="650px" append-to-body>
+      <el-table :data="thicknessViewList" border size="small">
+        <el-table-column label="序号" type="index" width="60" align="center" />
+        <el-table-column label="测厚点" prop="thicknessPt" width="180" :show-overflow-tooltip="true" />
+        <el-table-column label="测厚日期" width="140" align="center">
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.thicknessDate, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="测厚数据" prop="thicknessData" width="120" align="center" />
+        <el-table-column label="备注" prop="remarks" :show-overflow-tooltip="true" />
+      </el-table>
+      <div v-if="thicknessViewList.length === 0" style="text-align: center; color: #999; padding: 20px;">暂无测厚记录</div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="thicknessDialogVisible = false">关 闭</el-button>
+      </div>
+    </el-dialog>
+
   </div>
 </template>
 
 <script>
-import { listMyRel_maint_record, getRel_maint_record, delRel_maint_record, updateRel_maint_record, exportRel_maint_record, importTemplate} from "@/api/reliability/rel_maint_record";
+import { listMyRel_maint_record, getRel_maint_record, delRel_maint_record, addRel_maint_record, updateRel_maint_record, exportRel_maint_record, importTemplate} from "@/api/reliability/rel_maint_record";
 import { getRel_maint_memo } from "@/api/reliability/rel_maint_memo";
 import { treeselect } from "@/api/system/dept";
 import { getToken } from "@/utils/auth";
@@ -646,6 +744,8 @@ export default {
       // 附件查看对话框
       attachmentDialogVisible: false,
       viewAttachmentList: [],
+      thicknessDialogVisible: false,
+      thicknessViewList: [],
         // 用户导入参数
         upload: {
             // 是否显示弹出层(用户导入)
@@ -713,6 +813,48 @@ export default {
         this.incompleteLoading = false;
       });
     },
+    initThicknessList() {
+      const ptStr = this.processForm && this.processForm.compo ? this.processForm.compo.thicknessPt : null;
+      const points = (ptStr || '')
+        .split(/[;;]/)
+        .map(s => (s || '').trim())
+        .filter(s => s);
+
+      const existing = Array.isArray(this.processForm.thicknessList) ? this.processForm.thicknessList : [];
+      const existingMap = new Map(
+        existing
+          .filter(r => r && r.thicknessPt)
+          .map(r => [String(r.thicknessPt).trim(), r])
+      );
+
+      this.processForm.thicknessList = points.map(pt => {
+        const old = existingMap.get(pt);
+        if (old) {
+          return {
+            thicknessPt: pt,
+            thicknessDate: old.thicknessDate || null,
+            thicknessData: old.thicknessData === 0 ? 0 : (old.thicknessData != null && old.thicknessData !== '' ? Number(old.thicknessData) : undefined)
+          };
+        }
+        return { thicknessPt: pt, thicknessDate: null, thicknessData: undefined };
+      });
+    },
+    validateThicknessList() {
+      const list = this.processForm ? this.processForm.thicknessList : null;
+      if (!Array.isArray(list) || list.length === 0) {
+        return true;
+      }
+      for (const row of list) {
+        const pt = row ? row.thicknessPt : '';
+        const date = row ? row.thicknessDate : null;
+        const val = row ? row.thicknessData : null;
+        if (!date || val === null || val === undefined || val === '') {
+          this.$message.error((pt ? `请填写测厚记录:${pt}` : '请填写测厚记录') + '(日期和数值必填)');
+          return false;
+        }
+      }
+      return true;
+    },
     /** 查询已完成列表(包括已完成和已延期) */
     getCompletedList() {
       this.completedLoading = true;
@@ -848,6 +990,8 @@ export default {
         } else {
           this.processForm.processLoss = Number(this.processForm.processLoss);
         }
+
+        this.initThicknessList();
         // 根据维修类型打开对应的对话框
         if (this.processForm.maintType === '1') {
           this.processInspectOpen = true;
@@ -884,7 +1028,8 @@ export default {
         newResponsible: null,
         cannotMaintOrReplace: false,
         memoReason: null,
-        memoTime: null
+        memoTime: null,
+        thicknessList: []
       };
       // 清空文件列表
       this.photoFileList = [];
@@ -942,6 +1087,9 @@ export default {
 
       formRef.validate(valid => {
         if (valid) {
+          if (!this.validateThicknessList()) {
+            return;
+          }
           // 更新维修状态为已完成
           this.processForm.recordStatus = 2;
           // 将是否需要创建新记录的信息传递给后端
@@ -1190,6 +1338,11 @@ export default {
       this.viewAttachmentList = this.parseFileList(attachments, 'file');
       this.attachmentDialogVisible = true;
     },
+
+    handleViewThickness(row) {
+      this.thicknessViewList = (row && row.thicknessList) ? row.thicknessList : [];
+      this.thicknessDialogVisible = true;
+    },
     /** 下载附件 */
     downloadAttachment(file) {
       if (file.url) {