fuliqi
2024-09-25 8244adbb31a684de274a7b11a2e5293eb6dea46d
工单号生成修改
9个文件已修改
175 ■■■■ 已修改文件
ycl-common/src/main/java/constant/RedisConstant.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-pojo/src/main/java/com/ycl/platform/domain/query/WorkOrderQuery.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/platform/controller/WorkOrderController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/platform/service/impl/WorkOrderServiceImpl.java 114 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/task/ClearRedisTask.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/utils/redis/RedisCache.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/java/com/ycl/utils/uuid/IdUtils.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/resources/mapper/zgyw/WorkOrderMapper.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-server/src/main/resources/mapper/zgyw/YwPointMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-common/src/main/java/constant/RedisConstant.java
@@ -10,4 +10,8 @@
    /** 点位在线,hash的key */
    public final static String ONLINE_KEY = "ONLINE_";
    /** redis锁 */
    public final static String WORKORDER_NUM_LOCK = "WORKORDER_NUM_LOCK";
    /** 每日工单数 */
    public final static String WORKORDER_NUM = "WORKORDER_NUM";
}
ycl-pojo/src/main/java/com/ycl/platform/domain/query/WorkOrderQuery.java
@@ -29,13 +29,13 @@
    /**
     * 运维处理时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date start;
    /**
     * 运维处理时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date end;
    /**
ycl-server/src/main/java/com/ycl/platform/controller/WorkOrderController.java
@@ -146,8 +146,6 @@
        return workOrderService.all();
    }
    @GetMapping("/detail/info/{workOrderNo}")
    @ApiOperation(value = "详情", notes = "详情")
    @PreAuthorize("@ss.hasPermi('work:order:detail')")
ycl-server/src/main/java/com/ycl/platform/service/impl/WorkOrderServiceImpl.java
@@ -37,6 +37,7 @@
import com.ycl.utils.redis.RedisCache;
import com.ycl.utils.uuid.IdUtils;
import constant.Constants;
import constant.RedisConstant;
import enumeration.general.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -47,6 +48,7 @@
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
@@ -80,7 +82,6 @@
    private final SysConfigMapper configMapper;
    private final ReportMapper reportMapper;
    private final WorkOrderCheckImgMapper workOrderCheckImgMapper;
    @Value("${rtsp.server:http://127.0.0.1:7788}")
    private String rtspServer;
@@ -92,6 +93,7 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    //TODO:Redis加锁,从Redis读取当日工单数据量
    public synchronized Boolean innerAddWorkOrder(List<WorkOrder> workOrderList) {
        int total = workOrderList.size();
        workOrderList.stream().filter(item -> {
@@ -138,7 +140,7 @@
                    continue;
                } else {
                    for (String errorType : errorTypes) {
                        if (! errorNameList.contains(errorType)) {
                        if (!errorNameList.contains(errorType)) {
                            // 错误类型不一样,就新增一个错误类型,并且重置工单状态为待处理
                            WorkOrderErrorType workOrderErrorType = new WorkOrderErrorType();
                            workOrderErrorType.setWorkOrderNo(databaseWorkOrder.getWorkOrderNo());
@@ -196,13 +198,43 @@
        SysConfig normal = configMapper.checkConfigKeyUnique("normal.wordkorder.alarm.time");
        // 如果即将生成工单,但是设备国标码查不到点位,则不添加?
        List<WorkOrder> notAddList = new ArrayList<>();
        //查redis今日工单数量
        int workOrderNum = 1;
        //UUID作为value,保证上锁的线程自己解锁
        String requestId = IdUtils.fastSimpleUUID();
        try {
            for (int i = 0; i < 3; i++) {
                boolean result = redisCache.acquireLock(RedisConstant.WORKORDER_NUM_LOCK, requestId, 10000);
                if (result) {
                    //查今日工单量
                    Object redisNum = redisCache.getCacheObject(RedisConstant.WORKORDER_NUM);
                    workOrderNum = redisNum == null ? 1 : (Integer) redisNum;
                    break;
                } else {
                    if (i == 2) {
                        log.error("锁被占用");
                        return Boolean.FALSE;
                    }
                    //等待一段时间后继续
                    Thread.sleep(3000);
                }
            }
        } catch (InterruptedException e) {
            log.error("获取锁异常");
            return Boolean.FALSE;
        } finally {
            redisCache.releaseLock(RedisConstant.WORKORDER_NUM_LOCK, requestId);
        }
        for (WorkOrder workOrder : waitAddList) {
            YwPoint point = pointMapping.get(workOrder.getSerialNumber());
            if (Objects.isNull(point)) {
                notAddList.add(workOrder);
                continue;
            }
            workOrder.setWorkOrderNo(IdUtils.randomNO(now));
            //数字前面补0
            workOrder.setWorkOrderNo(IdUtils.randomNO(now, String.format("%05d", workOrderNum)));
            workOrderNum++;
            if (Objects.nonNull(point.getUnitId())) {
                workOrder.setUnitId(Math.toIntExact(point.getUnitId()));
            }
@@ -225,9 +257,11 @@
        if (CollectionUtils.isEmpty(waitAddList)) {
            return Boolean.TRUE;
        }
        //记录工单数
        redisCache.setCacheObject(RedisConstant.WORKORDER_NUM, workOrderNum);
        // 保存工单和故障类型
        baseMapper.addMany(waitAddList);
        if (! CollectionUtils.isEmpty(waitAddErrorTypeList)) {
        if (!CollectionUtils.isEmpty(waitAddErrorTypeList)) {
            workOrderErrorTypeService.getBaseMapper().addMany(waitAddErrorTypeList);
        }
        // 如果是直接下发,添加下发记录
@@ -253,22 +287,38 @@
    /**
     * 添加
     *
     * @param form
     * @return
     */
    @Override
    public Result add(WorkOrderForm form) {
        //查redis今日工单数量
        int workOrderNum = 1;
        //UUID作为value,保证上锁的线程自己解锁
        String requestId = IdUtils.fastSimpleUUID();
        boolean result = redisCache.acquireLock(RedisConstant.WORKORDER_NUM_LOCK, requestId, 10000);
        if (result) {
            //查今日工单量
            Object redisNum = redisCache.getCacheObject(RedisConstant.WORKORDER_NUM);
            workOrderNum = redisNum == null ? 1 : (Integer) redisNum;
            redisCache.releaseLock(RedisConstant.WORKORDER_NUM_LOCK, requestId);
        } else {
            return Result.error("工单正在添加,请稍后再试");
        }
        WorkOrder entity = WorkOrderForm.getEntityByForm(form, null);
        entity.setCreateTime(DateUtils.getNowDate());
        entity.setStatus(WorkOrderStatusEnum.WAIT_DISTRIBUTE);
        Date now = new Date();
        entity.setCreateTime(now);
        entity.setUpdateTime(now);
        entity.setWorkOrderNo(IdUtils.randomNO(now));
        entity.setWorkOrderNo(IdUtils.randomNO(now, String.format("%05d", workOrderNum)));
        workOrderNum++;
        redisCache.setCacheObject(RedisConstant.WORKORDER_NUM, workOrderNum);
        entity.setErrorType(String.join(",", form.getErrorType()));
        List<WorkOrderErrorType> workOrderErrorTypes = form.getErrorType().stream().map(errorType -> new WorkOrderErrorType(entity.getWorkOrderNo(), errorType)).toList();
        workOrderErrorTypeService.getBaseMapper().insertWorkOrderErrorTypeList(workOrderErrorTypes);
        if(baseMapper.insert(entity) > 0) {
        if (baseMapper.insert(entity) > 0) {
            return Result.ok("添加成功");
        }
        return Result.error("添加失败");
@@ -276,6 +326,7 @@
    /**
     * 修改
     *
     * @param form
     * @return
     */
@@ -406,9 +457,9 @@
    @Override
    public List<WorkOrderAuditingRecord> selectYwAuditingListByYwId(String workOrderNo) {
        return new LambdaQueryChainWrapper<>(workOrderAuditingRecordMapper)
                        .eq(WorkOrderAuditingRecord::getWorkOrderNo, workOrderNo)
                        .orderByAsc(WorkOrderAuditingRecord::getCreateTime)
                        .list();
                .eq(WorkOrderAuditingRecord::getWorkOrderNo, workOrderNo)
                .orderByAsc(WorkOrderAuditingRecord::getCreateTime)
                .list();
    }
    @Override
@@ -423,12 +474,13 @@
    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @Override
    public Result remove(List<String> ids) {
        if(baseMapper.deleteBatchIds(ids) > 0) {
        if (baseMapper.deleteBatchIds(ids) > 0) {
            return Result.ok("删除成功");
        }
        return Result.error("删除失败");
@@ -436,12 +488,13 @@
    /**
     * id删除
     *
     * @param id
     * @return
     */
    @Override
    public Result removeById(String id) {
        if(baseMapper.deleteById(id) > 0) {
        if (baseMapper.deleteById(id) > 0) {
            return Result.ok("删除成功");
        }
        return Result.error("删除失败");
@@ -449,6 +502,7 @@
    /**
     * 分页查询
     *
     * @param query
     * @return
     */
@@ -456,8 +510,10 @@
    public Result page(WorkOrderQuery query) {
        IPage<WorkOrderVO> page = PageUtil.getPage(query, WorkOrderVO.class);
        query.setUnitId(SecurityUtils.getUnitId());
        query.setStart(DateUtils.getDayStart(query.getStart()));
        query.setEnd(DateUtils.getDayEnd(query.getEnd()));
        baseMapper.page(page, query);
        if (! CollectionUtils.isEmpty(page.getRecords())) {
        if (!CollectionUtils.isEmpty(page.getRecords())) {
            page.getRecords().stream().forEach(item -> {
                if (StringUtils.hasText(item.getErrorType())) {
                    item.setErrorTypeList(List.of(item.getErrorType().split(",")));
@@ -488,14 +544,14 @@
                data.setStart(now.minusHours(1));
                break;
            case LAST_TWO_HOUR:
               data.setStart(now.minusHours(2));
               break;
                data.setStart(now.minusHours(2));
                break;
            case LAST_DAY:
                data.setStart(now.minusDays(1));
                break;
            default:
                break;
           }
        }
        if (Objects.isNull(data.getStart())) {
            throw new RuntimeException("无法生成快速下发的时间范围,请选择正确的快速下发方式");
        }
@@ -512,8 +568,12 @@
        List<String> workOrderNoList = list.stream().map(WorkOrder::getWorkOrderNo).toList();
        List<String> serialNumberList = list.stream().map(WorkOrder::getSerialNumber).toList();
        if (workOrderNoList.isEmpty()) { return Result.error("没有符合条件的工单"); }
        if (!getDistributeLock()) { return Result.error("此刻有人下发中,为避免冲突,请稍后重试"); }
        if (workOrderNoList.isEmpty()) {
            return Result.error("没有符合条件的工单");
        }
        if (!getDistributeLock()) {
            return Result.error("此刻有人下发中,为避免冲突,请稍后重试");
        }
        try {
            new LambdaUpdateChainWrapper<>(baseMapper)
                    .set(WorkOrder::getStatus, WorkOrderStatusEnum.DISTRIBUTED)
@@ -534,7 +594,9 @@
    @Transactional
    public Result selectedIdsDistribute(DistributeWorkOrderQuery query) {
        WorkOrderDistributeWayEnum distributeWayEnum = WorkOrderDistributeWayEnum.SELECTED_DISTRIBUTE;
        if (!getDistributeLock()) { return Result.error("此刻有人下发中,为避免冲突,请稍后重试"); }
        if (!getDistributeLock()) {
            return Result.error("此刻有人下发中,为避免冲突,请稍后重试");
        }
        try {
            if (query.getWorkOrderNOList().isEmpty()) {
                query.setWorkOrderNOList(new LambdaQueryChainWrapper<>(baseMapper)
@@ -547,7 +609,9 @@
                        .collect(Collectors.toList()));
                distributeWayEnum = WorkOrderDistributeWayEnum.ALL_DISTRIBUTE;
            }
            if (query.getWorkOrderNOList().isEmpty()) { return Result.error("没有工单待下发"); }
            if (query.getWorkOrderNOList().isEmpty()) {
                return Result.error("没有工单待下发");
            }
            new LambdaUpdateChainWrapper<>(baseMapper)
                    .set(WorkOrder::getStatus, WorkOrderStatusEnum.DISTRIBUTED)
                    .in(WorkOrder::getWorkOrderNo, query.getWorkOrderNOList())
@@ -566,6 +630,7 @@
    /**
     * 申请工单下发锁
     *
     * @return 工单下发锁申请结果
     */
    public synchronized Boolean getDistributeLock() {
@@ -586,6 +651,7 @@
    /**
     * 添加工单下发记录
     *
     * @param workOrderNoList 工单id
     */
    private void addDistributeRecord(List<String> workOrderNoList, WorkOrderDistributeWayEnum distributeWay) {
@@ -599,6 +665,7 @@
    /**
     * 根据id查找
     *
     * @param id
     * @return
     */
@@ -613,6 +680,7 @@
    /**
     * 列表
     *
     * @return
     */
    @Override
@@ -675,8 +743,8 @@
        for (WorkOrderRegionVO vo : vos) {
            for (WorkOrderRegionVO workOrder : workOrderRegionVOS) {
                //赋值
                if(vo.getArea().equals(workOrder.getArea())){
                    BeanUtils.copyProperties(workOrder,vo);
                if (vo.getArea().equals(workOrder.getArea())) {
                    BeanUtils.copyProperties(workOrder, vo);
                }
            }
        }
@@ -837,7 +905,7 @@
        if (Objects.nonNull(beforeRecord)) {
            if (now.before(beforeRecord.getBeginCreateTime())) {
                process.setBeforeReportMsg("事前报备已失效");
            } else if (now.after(beforeRecord.getEndCreateTime())){
            } else if (now.after(beforeRecord.getEndCreateTime())) {
                process.setBeforeReportMsg("事前报备未生效");
            } else {
                process.setBeforeReportMsg("已事前报备");
@@ -846,7 +914,7 @@
        if (Objects.nonNull(afterRecord)) {
            if (now.before(afterRecord.getBeginCreateTime())) {
                process.setAfterReportMsg("事后报备已失效");
            } else if (now.after(afterRecord.getEndCreateTime())){
            } else if (now.after(afterRecord.getEndCreateTime())) {
                process.setAfterReportMsg("事后报备未生效");
            } else {
                process.setAfterReportMsg("已事后报备");
ycl-server/src/main/java/com/ycl/task/ClearRedisTask.java
@@ -25,4 +25,11 @@
        redisTemplate.delete(RedisConstant.ONLINE_KEY);
    }
    /**
     * 清除redis每日工单数
     *
     */
    public void clearWorkOrderNum() {
        redisTemplate.delete(RedisConstant.WORKORDER_NUM);
    }
}
ycl-server/src/main/java/com/ycl/utils/redis/RedisCache.java
@@ -262,4 +262,36 @@
    {
        return redisTemplate.keys(pattern);
    }
    /**
     * 尝试获取锁
     *
     * @param lockKey    锁的键
     * @param requestId  请求标识,用于区分不同的锁持有者
     * @param expireTime 锁的过期时间,单位为毫秒
     * @return 如果成功获取锁,返回 true;否则返回 false
     */
    public boolean acquireLock(String lockKey, String requestId, long expireTime) {
        // 使用 setIfAbsent 方法尝试设置键值对,如果键不存在则设置成功并返回 true,否则返回 false
        Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, expireTime, TimeUnit.MILLISECONDS);
        return result != null && result;
    }
    /**
     * 释放锁
     *
     * @param lockKey   锁的键
     * @param requestId 请求标识,用于确保只有锁的持有者才能释放锁
     * @return 如果成功释放锁,返回 true;否则返回 false
     */
    public boolean releaseLock(String lockKey, String requestId) {
        // 获取当前锁的值
        String currentValue = (String) redisTemplate.opsForValue().get(lockKey);
        // 检查当前锁的值是否等于请求标识,确保只有锁的持有者才能释放锁
        if (currentValue != null && currentValue.equals(requestId)) {
            // 删除锁键
            return Boolean.TRUE.equals(redisTemplate.delete(lockKey));
        }
        return false;
    }
}
ycl-server/src/main/java/com/ycl/utils/uuid/IdUtils.java
@@ -59,8 +59,8 @@
     *
     * @return 编号
     */
    public static String randomNO(Date now)
    public static String randomNO(Date now,String orderNumber)
    {
        return DAY_FORMAT.format(now) + UUID.randomUUID().toString().replaceAll("-","").substring(0, 18);
        return DAY_FORMAT.format(now) + orderNumber;
    }
}
ycl-server/src/main/resources/mapper/zgyw/WorkOrderMapper.xml
@@ -68,14 +68,14 @@
        <if test="query.status != null and query.status != ''">
            AND wo.status = #{query.status}
        </if>
        <if test="query.start != null">
            AND wo.yw_handle_time BETWEEN #{query.start} AND #{query.end}
        <if test="query.start != null and query.end != null">
            AND wo.create_time BETWEEN #{query.start} AND #{query.end}
        </if>
        GROUP BY
        wo.id, wo.status, wo.work_order_no, wo.serial_number,wo.create_time, wo.unit_id, wo.yw_people_id,tm.name, wo.yw_handle_time, wo.yw_result, wo.yw_check_result, wo.overtime, wo.deduct,
        u.unit_name,
        p.yw_person_name
        ORDER BY wo.create_time DESC
        ORDER BY wo.work_order_no DESC
    </select>
    <select id="distributePage" resultType="com.ycl.platform.domain.vo.WorkOrderVO">
ycl-server/src/main/resources/mapper/zgyw/YwPointMapper.xml
@@ -55,7 +55,7 @@
        </where>
    </select>
    <select id="dataCenterPage">
    <select id="dataCenterPage" resultType="com.ycl.platform.domain.vo.PointDetailVO">
        SELECT
               m.*
        FROM