|
|
@@ -0,0 +1,144 @@
|
|
|
+package org.dromara.risk.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.util.IdUtil;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.dromara.common.core.utils.MapstructUtils;
|
|
|
+import org.dromara.common.core.utils.StringUtils;
|
|
|
+import org.dromara.common.satoken.utils.LoginHelper;
|
|
|
+import org.dromara.risk.domain.RiskInspectionTask;
|
|
|
+import org.dromara.risk.domain.bo.MobilePunchBo;
|
|
|
+import org.dromara.risk.domain.RiskInspectionRecord;
|
|
|
+import org.dromara.risk.domain.vo.RiskInspectionRecordVo;
|
|
|
+import org.dromara.risk.mapper.RiskInspectionRecordMapper;
|
|
|
+import org.dromara.risk.mapper.RiskInspectionTaskMapper;
|
|
|
+import org.dromara.risk.service.IRiskInspectionRecordService;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.util.Assert;
|
|
|
+
|
|
|
+import java.util.Date;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 巡检打卡记录 业务层实现
|
|
|
+ *
|
|
|
+ * @author ruoyi
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@RequiredArgsConstructor
|
|
|
+@Service
|
|
|
+public class RiskInspectionRecordServiceImpl implements IRiskInspectionRecordService {
|
|
|
+
|
|
|
+ private final RiskInspectionRecordMapper baseMapper;
|
|
|
+ private final RiskInspectionTaskMapper taskMapper;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 移动端-提交巡检打卡
|
|
|
+ * <p>
|
|
|
+ * 流程:
|
|
|
+ * 1. 校验任务存在
|
|
|
+ * 2. 扫码打卡需要校验二维码
|
|
|
+ * 3. 写入主表 risk_inspection_record
|
|
|
+ * 4. 汇总:项目数/问题数
|
|
|
+ * 5. 若有异常项,任务状态置为"异常打卡";否则"已打卡"
|
|
|
+ * 6. 写完返回主键ID
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Long submitPunch(MobilePunchBo bo) {
|
|
|
+ // 1. 校验任务
|
|
|
+ RiskInspectionTask task = taskMapper.selectById(bo.getTaskId());
|
|
|
+ Assert.notNull(task, "巡检任务不存在: " + bo.getTaskId());
|
|
|
+
|
|
|
+ // 2. 扫码打卡:校验二维码(留宽松,空串通过)
|
|
|
+ if ("SCAN".equalsIgnoreCase(bo.getPunchType())
|
|
|
+ && StringUtils.isNotBlank(task.getQrCode())
|
|
|
+ && StringUtils.isNotBlank(bo.getQrCode())
|
|
|
+ && !task.getQrCode().trim().equals(bo.getQrCode().trim())) {
|
|
|
+ throw new IllegalArgumentException("二维码与任务不匹配,请扫描正确的巡检点二维码");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 主表数据
|
|
|
+ RiskInspectionRecord rec = new RiskInspectionRecord();
|
|
|
+ rec.setRecordCode("RC" + IdUtil.fastSimpleUUID().substring(0, 8).toUpperCase());
|
|
|
+ rec.setTaskId(task.getId());
|
|
|
+ rec.setTaskName(task.getTaskName());
|
|
|
+ rec.setStoreId(task.getStoreId());
|
|
|
+ rec.setStoreName(task.getStoreName());
|
|
|
+ rec.setCheckInTime(bo.getPunchTime() == null ? new Date() : bo.getPunchTime());
|
|
|
+ rec.setCheckInLocation(bo.getPunchLocation());
|
|
|
+ rec.setCheckInLng(bo.getLng());
|
|
|
+ rec.setCheckInLat(bo.getLat());
|
|
|
+ rec.setCheckInPhoto(bo.getPhotos());
|
|
|
+ rec.setRemark(bo.getRemark());
|
|
|
+
|
|
|
+ // 4. 巡检人
|
|
|
+ if (bo.getInspectorId() != null) {
|
|
|
+ rec.setInspectorId(bo.getInspectorId());
|
|
|
+ rec.setInspectorName(bo.getInspectorName());
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ rec.setInspectorId(LoginHelper.getUserId());
|
|
|
+ rec.setInspectorName(LoginHelper.getUsername());
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ // 移动端可能在 Sa-Token 上下文外调用,留空
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 汇总项目结果
|
|
|
+ int total = 0;
|
|
|
+ int problem = 0;
|
|
|
+ boolean hasAbnormal = false;
|
|
|
+ String overallResult = "0";
|
|
|
+ if (ObjectUtil.isNotEmpty(bo.getItems())) {
|
|
|
+ total = bo.getItems().size();
|
|
|
+ for (MobilePunchBo.ItemResult item : bo.getItems()) {
|
|
|
+ if ("1".equals(item.getResult())) {
|
|
|
+ problem++;
|
|
|
+ hasAbnormal = true;
|
|
|
+ overallResult = "1";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ rec.setTotalCount(total);
|
|
|
+ rec.setProblemCount(problem);
|
|
|
+ rec.setResult(overallResult);
|
|
|
+
|
|
|
+ // 6. 记录状态
|
|
|
+ rec.setRecordStatus(hasAbnormal ? "异常打卡" : "已打卡");
|
|
|
+
|
|
|
+ // 7. 写主表
|
|
|
+ baseMapper.insert(rec);
|
|
|
+
|
|
|
+ // 8. 更新任务状态(已打卡)
|
|
|
+ if (task.getActualStartTime() == null) {
|
|
|
+ task.setActualStartTime(rec.getCheckInTime());
|
|
|
+ }
|
|
|
+ if (!"已完成".equals(task.getTaskStatus())) {
|
|
|
+ task.setTaskStatus(rec.getRecordStatus());
|
|
|
+ }
|
|
|
+ task.setCompletedCount(ObjectUtil.defaultIfNull(task.getCompletedCount(), 0) + total);
|
|
|
+ task.setItemCount(ObjectUtil.defaultIfNull(task.getItemCount(), 0));
|
|
|
+ // 合格率
|
|
|
+ if (total > 0) {
|
|
|
+ double passRate = (double) (total - problem) / total * 100;
|
|
|
+ task.setPassRate(java.math.BigDecimal.valueOf(Math.round(passRate * 100) / 100.0));
|
|
|
+ }
|
|
|
+ taskMapper.updateById(task);
|
|
|
+
|
|
|
+ log.info("巡检打卡成功 recordId={} taskId={} result={} total={} problem={}",
|
|
|
+ rec.getId(), task.getId(), overallResult, total, problem);
|
|
|
+
|
|
|
+ return rec.getId();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 移动端-查询单条打卡记录
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public RiskInspectionRecordVo queryById(Long id) {
|
|
|
+ return baseMapper.selectVoById(id);
|
|
|
+ }
|
|
|
+}
|