赋值问题
This commit is contained in:
@@ -4,9 +4,9 @@ import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.czg.account.entity.PrintMachine;
|
||||
import com.czg.config.RedisCst;
|
||||
import com.czg.market.service.OrderInfoService;
|
||||
import com.czg.order.entity.OrderInfo;
|
||||
import com.czg.order.entity.PrintMachineLog;
|
||||
@@ -247,18 +247,8 @@ public class PrintMachineLogServiceImpl extends ServiceImpl<PrintMachineLogMappe
|
||||
} finally {
|
||||
//仅当是最后一次任务时,才执行更新操作
|
||||
if (isLastTask) {
|
||||
redisService.del("order:print:" + orderId);
|
||||
super.updateById(entity);
|
||||
OrderInfo orderInfo = orderInfoService.getOne(query().select(OrderInfo::getPrintStatus).eq(OrderInfo::getId, orderId));
|
||||
if (orderInfo == null) {
|
||||
orderInfo = new OrderInfo();
|
||||
}
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("id", config.getId());
|
||||
jsonObject.put("name", config.getName());
|
||||
jsonObject.put("time", LocalDateTime.now());
|
||||
orderInfo.upPrintStatus(jsonObject, isPrintSuccess);
|
||||
orderInfoService.update(orderInfo, query().eq(OrderInfo::getId, orderId));
|
||||
updateOrderEntity(orderId, config, isPrintSuccess);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -278,6 +268,26 @@ public class PrintMachineLogServiceImpl extends ServiceImpl<PrintMachineLogMappe
|
||||
registerShutdownHookOnce();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新状态
|
||||
*/
|
||||
private void updateOrderEntity(Long orderId, PrintMachine config, boolean isPrintSuccess) {
|
||||
redisService.runFunAndCheckKey(() -> {
|
||||
OrderInfo orderInfo = orderInfoService.getOne(query().select(OrderInfo::getPrintStatus).eq(OrderInfo::getId, orderId));
|
||||
if (orderInfo == null) {
|
||||
orderInfo = new OrderInfo();
|
||||
}
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("id", config.getId());
|
||||
jsonObject.put("name", config.getName());
|
||||
jsonObject.put("time", LocalDateTime.now());
|
||||
orderInfo.upPrintStatus(jsonObject, isPrintSuccess);
|
||||
orderInfoService.update(orderInfo, query().eq(OrderInfo::getId, orderId));
|
||||
return orderInfo;
|
||||
}, RedisCst.getLockKey("UP_ORDER_PRINT", orderId));
|
||||
redisService.del("order:print:" + orderId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一更新打印日志实体
|
||||
*
|
||||
@@ -300,66 +310,6 @@ public class PrintMachineLogServiceImpl extends ServiceImpl<PrintMachineLogMappe
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// public void checkPrintStatus(PrintMachine config, PrintMachineLog entity) {
|
||||
// // 云想印
|
||||
// if ("云想印".equals(config.getContentType())) {
|
||||
// String jsonStr = yxyPrinter.checkPrintStatus(config.getAddress(), entity.getTaskId());
|
||||
// log.info("云想印打印状态查询结果:{}", jsonStr);
|
||||
// JSONObject resp = JSONObject.parseObject(jsonStr);
|
||||
// int code = resp.getIntValue("code");
|
||||
// if (code == 0) {
|
||||
// JSONObject data = resp.getJSONObject("data");
|
||||
// boolean status = data.containsKey("status");
|
||||
// if (!status) {
|
||||
// return;
|
||||
// }
|
||||
// boolean success = data.getBooleanValue("status", false);
|
||||
// if (entity.getFailFlag() == 0 && success) {
|
||||
// entity.setFailFlag(0);
|
||||
// entity.setRespMsg("打印成功");
|
||||
// entity.setPrintTime(entity.getCreateTime());
|
||||
// } else if (entity.getFailFlag() == 1 && success) {
|
||||
// entity.setFailFlag(0);
|
||||
// entity.setPrintTime(DateUtil.date().toLocalDateTime());
|
||||
// entity.setRespMsg("打印成功");
|
||||
// // 如果设备在线 and 休眠5秒后查询结果是未打印,即视为设备已离线,云端3分钟后才会同步到离线信息
|
||||
// } else if (entity.getFailFlag() == 0 && !success) {
|
||||
// entity.setFailFlag(1);
|
||||
// entity.setPrintTime(null);
|
||||
// entity.setRespMsg("0_离线(设备上线后自动补打)");
|
||||
// } else {
|
||||
// entity.setFailFlag(1);
|
||||
// entity.setPrintTime(null);
|
||||
// entity.setRespMsg(StrUtil.concat(true, "打印失败,", "_", entity.getRespMsg()));
|
||||
// }
|
||||
// }
|
||||
// // 飞鹅云打印机
|
||||
// } else if ("飞鹅".equals(config.getContentType())) {
|
||||
// Boolean success = feiPrinter.checkFPrintStatus(entity.getTaskId());
|
||||
// if (success == null) {
|
||||
// entity.setFailFlag(1);
|
||||
// entity.setRespMsg("打印失败,未知错误");
|
||||
// } else if (success) {
|
||||
// entity.setFailFlag(0);
|
||||
// entity.setPrintTime(DateUtil.date().toLocalDateTime());
|
||||
// entity.setRespMsg("打印成功");
|
||||
// } else {
|
||||
// String msg = feiPrinter.checkOnline(entity.getAddress());
|
||||
// if (msg.indexOf("在线,工作状态正常") > 0) {
|
||||
// entity.setFailFlag(0);
|
||||
// entity.setPrintTime(DateUtil.date().toLocalDateTime());
|
||||
// entity.setRespMsg("打印成功");
|
||||
// } else {
|
||||
// entity.setFailFlag(1);
|
||||
// entity.setPrintTime(null);
|
||||
// entity.setRespMsg(StrUtil.concat(true, "打印失败,", "_", msg));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// super.updateById(entity);
|
||||
// }
|
||||
|
||||
// 静态标识,确保关闭钩子仅注册一次
|
||||
private static volatile boolean shutdownHookRegistered = false;
|
||||
// 锁对象,保证线程安全
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
package com.czg.service.order.utils;
|
||||
|
||||
import cn.hutool.core.lang.func.Func0;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class FunUtil {
|
||||
@Resource
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
public static int retryCount = 5;
|
||||
|
||||
/**
|
||||
* 执行任务并保证锁唯一
|
||||
* @param supplier 业务逻辑
|
||||
* @param lockKey Redis锁的Key
|
||||
* @return 业务逻辑返回值
|
||||
*/
|
||||
public <T> T runFunAndCheckKey(Supplier<T> supplier, String lockKey) {
|
||||
String lockValue = String.valueOf(System.nanoTime() + Thread.currentThread().threadId());
|
||||
try {
|
||||
// 尝试获取锁,超时时间 5 秒,防止死锁
|
||||
boolean lock = Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, 5, TimeUnit.SECONDS));
|
||||
int count = 0;
|
||||
// 初始等待 10ms
|
||||
int retryDelay = 10;
|
||||
|
||||
while (!lock) {
|
||||
// 最多重试 10 次,大约 10 秒
|
||||
if (count++ > 50) {
|
||||
throw new RuntimeException("系统繁忙, 稍后再试");
|
||||
}
|
||||
Thread.sleep(retryDelay);
|
||||
// 指数退避,最大等待 200ms
|
||||
retryDelay = Math.min(retryDelay * 2, 200);
|
||||
lock = Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, 5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
// 执行任务
|
||||
return supplier.get();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RuntimeException("线程被中断", e);
|
||||
} catch (Exception e) {
|
||||
log.error("执行出错:{}", e.getMessage(), e);
|
||||
throw e;
|
||||
} finally {
|
||||
// 释放锁(使用 Lua 脚本确保原子性)
|
||||
unlock(lockKey, lockValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 Lua 脚本确保释放锁的原子性
|
||||
* @param lockKey 锁的 Key
|
||||
* @param lockValue 当前线程的锁值
|
||||
*/
|
||||
private void unlock(String lockKey, String lockValue) {
|
||||
String luaScript =
|
||||
"if redis.call('get', KEYS[1]) == ARGV[1] then " +
|
||||
"return redis.call('del', KEYS[1]) " +
|
||||
"else return 0 end";
|
||||
redisTemplate.execute(new DefaultRedisScript<>(luaScript, Long.class),
|
||||
Collections.singletonList(lockKey), lockValue);
|
||||
}
|
||||
|
||||
public static <T, R> R runFunAndRetry(
|
||||
Supplier<R> function,
|
||||
Function<R, Boolean> check, Consumer<R> errFun) {
|
||||
log.info("工具类开始执行函数");
|
||||
R result = function.get();
|
||||
boolean flag = check.apply(result);
|
||||
|
||||
log.info("执行结果: {}", result);
|
||||
|
||||
while (flag && retryCount-- > 0) {
|
||||
log.info("执行函数失败, 剩余尝试次数{}", retryCount);
|
||||
result = function.get();
|
||||
log.info("执行结果: {}", result);
|
||||
flag = check.apply(result);
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
errFun.accept(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 防抖函数:在指定秒数内相同 Key 的任务只会执行一次
|
||||
* @param key 防抖使用的 Redis Key
|
||||
* @param seconds 防抖时间(秒)
|
||||
* @param task 要执行的业务逻辑
|
||||
* @return true 执行了任务;false 在防抖期内被拦截
|
||||
*/
|
||||
public boolean debounce(String key, long seconds, Runnable task) {
|
||||
try {
|
||||
Boolean success = redisTemplate.opsForValue().setIfAbsent(
|
||||
key, "1", seconds, TimeUnit.SECONDS
|
||||
);
|
||||
|
||||
if (Boolean.TRUE.equals(success)) {
|
||||
task.run();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
log.error("防抖函数执行失败 key={} err={}", key, e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user