Explorar el Código

巡检与考核开发8.27

admin hace 2 semanas
padre
commit
d61c2d358d

+ 16 - 0
client-app/src/main/java/com/sapit/client/app/manage/controller/inspect/AssessResultManageController.java

@@ -45,6 +45,22 @@ public class AssessResultManageController {
         return getPageResult(page, list);
     }
 
+    /**
+     * 门店考核详情(I05-A02)
+     * @param id 考核结果ID
+     */
+    @PostMapping("/getAssessDetail")
+    @AuthToken(type = "admin")
+    public ResultBean assessDetail(Long id) {
+        if (id == null) {
+            return paramError();
+        }
+        ResultBean bean = new ResultBean();
+        bean.setObj(assessResultService.getAssessDetailVO(id));
+        bean.getRtnBean().setRtnCode(ReturnCode.SUCCESS);
+        return bean;
+    }
+
     /**
      * 门店考核趋势查询
      * @param storeIds 门店ID集合

+ 15 - 0
client-app/src/main/java/com/sapit/client/app/manage/controller/inspect/InspectTaskManageController.java

@@ -74,6 +74,21 @@ public class InspectTaskManageController {
         List<?> list = inspectTaskService.getTaskPage(page, searchBean);
         return getPageResult(page, list);
     }
+    /**
+     * 巡检员本人任务列表(I03-A02)
+     * @param inspectorId 巡检员ID
+     * @param status 可选任务状态(如1待执行)
+     */
+    @PostMapping("/getMyTaskList")
+    @AuthToken(type = "admin")
+    public ResultBean myTaskList(int pageSize, int currentPage, Long inspectorId, Integer status) {
+        if (inspectorId == null) {
+            return paramError();
+        }
+        PageControlData page = buildPage(pageSize, currentPage);
+        List<?> list = inspectTaskService.getMyTaskList(page, inspectorId, status);
+        return getPageResult(page, list);
+    }
     /**
      * 巡检任务详情
      * @param id

+ 45 - 0
client-app/src/main/java/com/sapit/client/app/manage/controller/inspect/RectificationManageController.java

@@ -5,6 +5,7 @@ import com.sapit.common.constant.ReturnCode;
 import com.sapit.common.framwork.AuthToken;
 import com.sapit.common.framwork.PageControlData;
 import com.sapit.common.framwork.ResultBean;
+import com.sapit.common.entity.inspect.BuRectification;
 import com.sapit.common.search.inspect.BuRectificationSearchBean;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.format.annotation.DateTimeFormat;
@@ -14,8 +15,11 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 @RestController
 @RequestMapping(value = "rectificationManage", produces = "application/json")
@@ -38,6 +42,40 @@ public class RectificationManageController {
         return getPageResult(page, list);
     }
 
+    /**
+     * 整改统计(I04-A06):按门店统计整改次数、超期数、平均整改时长
+     */
+    @PostMapping("/getRectStatistics")
+    @AuthToken(type = "admin")
+    public ResultBean rectStatistics() {
+        ResultBean bean = new ResultBean();
+        bean.setList(rectificationService.getRectStatistics());
+        bean.getRtnBean().setRtnCode(ReturnCode.SUCCESS);
+        return bean;
+    }
+
+    /**
+     * 整改详情(时间轴,I04-A02):返回该整改所属完整轮次链
+     */
+    @PostMapping("/getRectDetail")
+    @AuthToken(type = "admin")
+    public ResultBean rectDetail(Long id) {
+        if (id == null) {
+            return paramError();
+        }
+        BuRectification root = rectificationService.getRectificationById(id);
+        if (root == null) {
+            return failed("整改记录不存在");
+        }
+        List<BuRectification> rounds = rectificationService.getRectChain(id, root.getStoreId());
+        Map<String, Object> obj = new LinkedHashMap<>();
+        obj.put("rounds", rounds == null ? new ArrayList<>() : rounds);
+        ResultBean bean = new ResultBean();
+        bean.setObj(obj);
+        bean.getRtnBean().setRtnCode(ReturnCode.SUCCESS);
+        return bean;
+    }
+
     /**
      * 批量更新整改截止日期
      * @param rectIds 整改记录ID集合
@@ -112,6 +150,13 @@ public class RectificationManageController {
         return bean;
     }
 
+    private ResultBean failed(String message) {
+        ResultBean bean = new ResultBean();
+        bean.getRtnBean().setRtnCode(ReturnCode.FAILED);
+        bean.getRtnBean().setRtnMsg(message);
+        return bean;
+    }
+
     private PageControlData buildPage(int pageSize, int currentPage) {
         PageControlData page = new PageControlData();
         page.setPageSize(pageSize);

+ 34 - 0
client-app/src/main/java/com/sapit/client/app/manage/inspect/service/AssessResultService.java

@@ -29,6 +29,40 @@ public class AssessResultService {
         return (BuAssessResult) assessResultDao.findById(BuAssessResult.class, id);
     }
 
+    /**
+     * 门店考核详情组合(I05-A02):返回单接口聚合 结果 + 周期内任务 + 整改记录 + 历史趋势。
+     */
+    public Map<String, Object> getAssessDetailVO(Long id) {
+        BuAssessResult result = getAssessDetail(id);
+        if (result == null) {
+            return null;
+        }
+        Map<String, Object> obj = new LinkedHashMap<>();
+        // 周期内巡检任务
+        obj.put("tasks", getAssessDetailTasks(result.getStoreId(), result.getPeriodType(), result.getPeriodCode()));
+        // 该门店整改记录
+        List<Map<String, Object>> rects = new ArrayList<>();
+        List<?> rectRows = inspectPlanDao.searchBySql(
+                "select INDICATOR_NAME, RECT_ROUND, DEADLINE_DATE, STATUS "
+                        + "from bu_rectification where STORE_ID = " + result.getStoreId()
+                        + " order by CREATE_DATE desc, RECT_ID desc");
+        if (rectRows != null) {
+            for (Object row : rectRows) {
+                Object[] arr = (Object[]) row;
+                Map<String, Object> r = new LinkedHashMap<>();
+                r.put("indicatorName", arr[0]);
+                r.put("rectRound", arr[1]);
+                r.put("deadlineDate", arr[2]);
+                r.put("status", arr[3]);
+                rects.add(r);
+            }
+        }
+        obj.put("rects", rects);
+        // 历史得分趋势
+        obj.put("trend", getAssessTrend(new Long[]{result.getStoreId()}, result.getPeriodType()));
+        return obj;
+    }
+
     public List<Map<String, Object>> getAssessDetailTasks(Long storeId, Integer periodType, String periodCode) {
         List<Map<String, Object>> tasks = new ArrayList<>();
         if (storeId == null || periodType == null || periodCode == null) {

+ 10 - 0
client-app/src/main/java/com/sapit/client/app/manage/inspect/service/InspectTaskService.java

@@ -33,6 +33,16 @@ public class InspectTaskService {
         return inspectTaskDao.getList(page, searchBean, " order by taskDate desc, taskId desc");
     }
 
+    /**
+     * 巡检员查看分配给自己的任务(PRD I03-A02):按巡检员过滤,status 可选(1待执行等)。
+     */
+    public List<BuInspectTask> getMyTaskList(PageControlData page, Long inspectorId, Integer status) {
+        BuInspectTaskSearchBean searchBean = new BuInspectTaskSearchBean();
+        searchBean.setInspectorId(inspectorId);
+        searchBean.setStatus(status);
+        return inspectTaskDao.getList(page, searchBean, " order by taskDate asc, taskId asc");
+    }
+
     public BuInspectTask getTaskDetail(Long id) {
         return (BuInspectTask) inspectTaskDao.findById(BuInspectTask.class, id);
     }

+ 52 - 3
client-app/src/main/java/com/sapit/client/app/manage/inspect/service/RectificationService.java

@@ -9,8 +9,10 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -25,12 +27,59 @@ public class RectificationService {
         return rectificationDao.getList(page, searchBean, " order by deadlineDate asc, rectId desc");
     }
 
-    public BuRectification getRectDetail(Long id) {
+    public BuRectification getRectificationById(Long id) {
         return (BuRectification) rectificationDao.findById(BuRectification.class, id);
     }
 
-    public BuRectification getRectificationById(Long id) {
-        return getRectDetail(id);
+    /**
+     * 获取某个整改记录所属的完整整改时间轴(多轮次,按轮次升序)。
+     * 同一 TASK_ITEM_ID 下所有轮次属于同一条整改链,归属校验在调用方完成。
+     */
+    public List<BuRectification> getRectChain(Long rectId, Long storeId) {
+        BuRectification root = getRectificationById(rectId);
+        if (root == null || !storeId.equals(root.getStoreId())) {
+            return null;
+        }
+        if (root.getTaskItemId() == null) {
+            List<BuRectification> single = new ArrayList<>();
+            single.add(root);
+            return single;
+        }
+        BuRectificationSearchBean searchBean = new BuRectificationSearchBean();
+        searchBean.setStoreId(storeId);
+        searchBean.setTaskItemId(root.getTaskItemId());
+        return rectificationDao.getList(searchBean, " order by rectRound asc, rectId asc");
+    }
+
+    public BuRectification getRectDetail(Long id) {
+        return getRectificationById(id);
+    }
+
+    /**
+     * 整改统计(PRD I04-A06):按门店统计整改次数、超期数、平均整改时长(天)。
+     */
+    public List<Map<String, Object>> getRectStatistics() {
+        String sql = "select STORE_ID, STORE_NAME, "
+                + "count(*) as rectCount, "
+                + "sum(case when STATUS = 6 then 1 else 0 end) as overtimeCount, "
+                + "round(ifnull(avg(case when RECHECK_DATE is not null "
+                + "then timestampdiff(SECOND, CREATE_DATE, RECHECK_DATE) / 86400.0 end), 0), 1) as avgDays "
+                + "from bu_rectification group by STORE_ID, STORE_NAME order by rectCount desc";
+        List<?> rows = rectificationDao.searchBySql(sql);
+        List<Map<String, Object>> result = new ArrayList<>();
+        if (rows != null) {
+            for (Object row : rows) {
+                Object[] arr = (Object[]) row;
+                Map<String, Object> item = new LinkedHashMap<>();
+                item.put("storeId", arr[0]);
+                item.put("storeName", arr[1]);
+                item.put("rectCount", arr[2]);
+                item.put("overtimeCount", arr[3]);
+                item.put("avgDays", arr[4]);
+                result.add(item);
+            }
+        }
+        return result;
     }
 
     public List<BuRectification> getMyRectificationList(Long storeId) {

+ 99 - 19
client-app/src/main/java/com/sapit/client/app/store/controller/inspect/RectificationApiController.java

@@ -3,10 +3,11 @@ package com.sapit.client.app.store.controller.inspect;
 import com.sapit.client.app.manage.inspect.service.RectificationService;
 import com.sapit.common.constant.ReturnCode;
 import com.sapit.common.entity.inspect.BuRectification;
-import com.sapit.common.framwork.AuthToken;
 import com.sapit.common.framwork.ResultBean;
+import com.sapit.common.util.ApiUtil;
 import com.sapit.common.util.DateUtil;
 import com.sapit.common.util.FileFtpUploadUtil;
+import com.sapit.common.util.SystemParam;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -17,13 +18,15 @@ import org.springframework.web.multipart.MultipartFile;
 import javax.servlet.http.HttpServletRequest;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 店铺端整改接口。
  *
- * 门店身份由现有销售端 token 体系负责解析,当前接口保留 storeId 参数,
- * 便于兼容项目已有 Controller 的参数绑定方式
+ * 鉴权与商家端一致:timestamp + sign( = MD5(storeUserId+timestamp+secretKey) ) + storeId 签名校验。
+ * 数据均强制按 storeId 归属校验
  */
 @RestController
 @RequestMapping(value = "rectificationApi", produces = "application/json")
@@ -31,57 +34,126 @@ public class RectificationApiController {
     @Autowired
     private RectificationService rectificationService;
 
+    /**
+     * 获取我的整改列表。
+     * @param storeId 店铺ID
+     * @param storeUserId 店铺用户ID
+     * @param timestamp 时间戳
+     * @param sign 签名
+     * @return 整改列表
+         */
     @PostMapping("/getMyRectList")
-    @AuthToken(type = "sales")
-    public ResultBean getMyRectList(Long storeId) {
-        if (storeId == null) {
+    public ResultBean getMyRectList(Long storeId, Long storeUserId, String timestamp, String sign) {
+        if (storeId == null || storeUserId == null || timestamp == null || sign == null) {
             return paramError();
         }
+        if (!signValid(storeUserId, timestamp, sign)) {
+            return signWrong();
+        }
         return listResult(rectificationService.getMyRectificationList(storeId));
     }
 
+    /**
+     * 开始整改。
+     * @param id 整改记录ID
+     * @param storeId 店铺ID
+     * @param storeUserId 店铺用户ID
+     * @param timestamp 时间戳
+     * @param sign 签名
+     * @return 整改记录
+     */
     @PostMapping("/startRect")
-    @AuthToken(type = "sales")
-    public ResultBean startRect(Long id, Long storeId) {
-        if (id == null || storeId == null) {
+    public ResultBean startRect(Long id, Long storeId, Long storeUserId, String timestamp, String sign) {
+        if (id == null || storeId == null || storeUserId == null || timestamp == null || sign == null) {
             return paramError();
         }
+        if (!signValid(storeUserId, timestamp, sign)) {
+            return signWrong();
+        }
         return updateResult(rectificationService.startRectification(id, storeId), "开始整改完成");
     }
 
+    /**
+     * 提交整改反馈。
+     * @param id 整改记录ID
+     * @param storeId
+     * @param storeUserId 店铺用户ID
+     * @param timestamp 时间戳
+     * @param sign 签名
+     * @param feedbackContent 反馈内容
+     * @param feedbackPictures 反馈图片URL
+     * @return 整改记录
+     */
     @PostMapping("/submitRect")
-    @AuthToken(type = "sales")
-    public ResultBean submitRect(Long id, Long storeId, String feedbackContent, String feedbackPictures) {
-        if (id == null || storeId == null) {
+    public ResultBean submitRect(Long id, Long storeId, Long storeUserId, String timestamp, String sign,
+                                 String feedbackContent, String feedbackPictures) {
+        if (id == null || storeId == null || storeUserId == null || timestamp == null || sign == null) {
             return paramError();
         }
+        if (!signValid(storeUserId, timestamp, sign)) {
+            return signWrong();
+        }
         BuRectification rectification = rectificationService.getRectificationById(id);
         if (rectification == null || !storeId.equals(rectification.getStoreId())) {
             return failed("整改记录不存在");
         }
+        // 严格按 PRD:仅整改中(2) 可提交反馈 → 待复检(3)
+        if (rectification.getStatus() == null || rectification.getStatus() != 2) {
+            return failed("仅整改中状态可提交反馈");
+        }
         return updateResult(rectificationService.submitRectification(id, feedbackContent, feedbackPictures), "提交整改完成");
     }
 
+    /**
+     * 获取整改详情。
+     * @param id 整改记录ID
+     * @param storeId 店铺ID
+     * @param storeUserId 店铺用户ID
+     * @param timestamp 时间戳
+     * @param sign 签名
+     * @return 整改详情
+     */
     @PostMapping("/getRectDetail")
-    @AuthToken(type = "sales")
-    public ResultBean getRectDetail(Long id, Long storeId) {
-        if (id == null || storeId == null) {
+    public ResultBean getRectDetail(Long id, Long storeId, Long storeUserId, String timestamp, String sign) {
+        if (id == null || storeId == null || storeUserId == null || timestamp == null || sign == null) {
             return paramError();
         }
-        BuRectification rectification = rectificationService.getRectificationById(id);
-        if (rectification == null || !storeId.equals(rectification.getStoreId())) {
+        if (!signValid(storeUserId, timestamp, sign)) {
+            return signWrong();
+        }
+        List<BuRectification> rounds = rectificationService.getRectChain(id, storeId);
+        if (rounds == null || rounds.isEmpty()) {
             return failed("整改记录不存在");
         }
+        Map<String, Object> obj = new LinkedHashMap<>();
+        obj.put("rectId", id);
+        obj.put("rounds", rounds);
         ResultBean bean = new ResultBean();
-        bean.setObj(rectification);
+        bean.setObj(obj);
         bean.getRtnBean().setRtnCode(ReturnCode.SUCCESS);
         return bean;
     }
 
+    /**
+     * 上传整改图片。
+     * @param file 图片文件对象
+     * @param storeId 店铺ID
+     * @param storeUserId 店铺用户ID
+     * @param timestamp 时间戳
+     * @param sign 签名
+     * @param request HTTP请求对象
+     * @return
+     */
     @PostMapping("/uploadPicture")
-    @AuthToken(type = "sales")
     public ResultBean uploadPicture(@RequestParam(value = "file", required = false) MultipartFile file,
+                                    Long storeId, Long storeUserId, String timestamp, String sign,
                                     HttpServletRequest request) {
+        if (storeId == null || storeUserId == null || timestamp == null || sign == null) {
+            return paramError();
+        }
+        if (!signValid(storeUserId, timestamp, sign)) {
+            return signWrong();
+        }
         ResultBean bean = new ResultBean();
         if (file == null || file.getOriginalFilename() == null || file.getOriginalFilename().isEmpty()) {
             return paramError();
@@ -123,6 +195,10 @@ public class RectificationApiController {
         return bean;
     }
 
+    private boolean signValid(Long authKey, String timestamp, String sign) {
+        return ApiUtil.validate(authKey + timestamp + SystemParam.secretKey, sign);
+    }
+
     private ResultBean updateResult(int result, String message) {
         ResultBean bean = new ResultBean();
         bean.getRtnBean().setRtnCode(result > 0 ? ReturnCode.SUCCESS : ReturnCode.FAILED);
@@ -141,6 +217,10 @@ public class RectificationApiController {
         return failed("参数错误");
     }
 
+    private ResultBean signWrong() {
+        return failed("签名错误!");
+    }
+
     private ResultBean failed(String message) {
         ResultBean bean = new ResultBean();
         bean.getRtnBean().setRtnCode(ReturnCode.PARAM_WRONG);

+ 1 - 1
client-app/src/main/resources/application-dev.yml

@@ -144,4 +144,4 @@ campus: 1
 platDataSource:
   url: jdbc:mysql://192.168.200.4:3306/eduepos-plat?useUnicode=true&characterEncoding=utf-8&serverTimezone=Hongkong
   username: root
-  password: 'Abcd@1234'
+  password: 'Abcd@1234'