package com.xy.service; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.yitter.idgen.YitIdHelper; import com.xy.collections.list.JArrayList; import com.xy.collections.list.JList; import com.xy.collections.map.JHashMap; import com.xy.collections.map.JMap; import com.xy.config.DeviceThreadPoolConfig; import com.xy.device.EnumAlgorithmPayConfig; import com.xy.device.EnumDeviceAlgorithmChargingHistoryStatus; import com.xy.device.EnumDeviceAlgorithmChargingType; import com.xy.device.EnumDeviceType; import com.xy.dto.*; import com.xy.dto.be.MercDto; import com.xy.entity.*; import com.xy.mapper.DeviceAlgorithmChargingMapper; import com.xy.mapper.entity.DeviceAlgorithmChargingChargingQueryParams; import com.xy.service.be.MercService; import com.xy.utils.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import javax.validation.constraints.NotEmpty; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; import static com.xy.utils.PlusBeans.toPageBean; /** *

* 设备算法计费表 服务实现类 *

* * @author lijin * @since 2023-06-29 */ @Slf4j @Service @AllArgsConstructor @Api(tags = "设备算法计费表") public class DeviceAlgorithmChargingServiceImpl extends ServiceImpl implements DeviceAlgorithmChargingService { private DeviceAlgorithmChargingHistoryServiceImpl deviceAlgorithmChargingHistoryService; private DeviceInfoServiceImpl deviceInfoService; private MercService mercService; private DeviceSysinfoServiceImpl deviceSysinfoService; private AlipayDeviceService alipayDeviceService; @PostMapping("count") @ApiOperation("查询条数") public R> count(@RequestBody @Validated DeviceAlgorithmChargingDto.Count count) { //默认值 List deviceIds = count.getDeviceIds(); JList countVos = new JArrayList<>(deviceIds.size()); deviceIds.forEach(deviceId -> { DeviceAlgorithmChargingDto.CountVo countVo = new DeviceAlgorithmChargingDto.CountVo() .setDeviceId(deviceId) .setCount(0); countVos.add(countVo); }); JMap cover = countVos.toMap(DeviceAlgorithmChargingDto.CountVo::getDeviceId).cover(); //查询数据 String thisTime = DataTime.getSring("yyyyMMdd"); List list = list(new LambdaQueryWrapper() .in(DeviceAlgorithmCharging::getDeviceId, deviceIds) .gt(DeviceAlgorithmCharging::getUnusedSize, 0) .and(deviceAlgorithmChargingLambdaQueryWrapper -> deviceAlgorithmChargingLambdaQueryWrapper .eq(DeviceAlgorithmCharging::getTimeout, -1) .or() .ge(DeviceAlgorithmCharging::getTimeout, thisTime) ) .le(DeviceAlgorithmCharging::getBeginTime, thisTime) ); JMap> group = new JArrayList<>(list).toMap(DeviceAlgorithmCharging::getDeviceId).group(); group.forEach((deviceId, deviceAlgorithmChargings) -> cover.get(deviceId).setCount(deviceAlgorithmChargings.size())); return R.ok(countVos); } @PostMapping("page") @ApiOperation("分页查询") public R> page(@RequestBody @Validated DeviceAlgorithmChargingDto.Page page) { LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(page, DeviceAlgorithmCharging.class) .build() .orderByDesc(DeviceAlgorithmCharging::getTimeout, DeviceAlgorithmCharging::getUnusedSize); IPage iPage = page(PlusBeans.toIPage(page.getPage()), lambdaQueryWrapper); return R.ok(toPageBean(DeviceAlgorithmChargingDto.Vo.class, iPage)); } @PostMapping("check") @ApiOperation("检查") public R check(@RequestBody @Validated DeviceAlgorithmChargingDto.Check check) { int yyyyMMdd = Integer.valueOf(DataTime.getSring("yyyyMMdd")); DeviceInfoDto.Vo deviceInfo = deviceInfoService.obj(new DeviceInfoDto.Obj().setDeviceId(check.getDeviceId())).getData(); List deviceAlgorithmChargings = list(new LambdaQueryWrapper() .eq(DeviceAlgorithmCharging::getDeviceId, deviceInfo.getDeviceId()) .eq(DeviceAlgorithmCharging::getAlgorithmId, deviceInfo.getAlgorithmId()) .gt(DeviceAlgorithmCharging::getUnusedSize, 0) .and(deviceAlgorithmChargingLambdaQueryWrapper -> deviceAlgorithmChargingLambdaQueryWrapper .ge(DeviceAlgorithmCharging::getTimeout, yyyyMMdd) .or() .eq(DeviceAlgorithmCharging::getTimeout, -1) ) .ge(DeviceAlgorithmCharging::getBeginTime, yyyyMMdd) ); if (!Emptys.check(deviceAlgorithmChargings)) { return R.fail(R.Enum.ALGORITHM_CHARGING.getCode(), R.Enum.ALGORITHM_CHARGING.getMsg()); } return R.ok(); } @Override @ApiOperation("购买") public R pay(DeviceAlgorithmChargingDto.Pay pay) { JList deviceAlgorithmChargings = new JArrayList<>(pay.getDeviceAlgorithmChargings()); LocalDateTime now = LocalDateTime.now(); List deviceAlgorithmChargingHistories = new ArrayList<>(deviceAlgorithmChargings.size()); deviceAlgorithmChargings.forEach(deviceAlgorithmCharging -> { DeviceAlgorithmChargingHistory deviceAlgorithmChargingHistory = new DeviceAlgorithmChargingHistory() .setId(YitIdHelper.nextId()) .setMercId(pay.getMercId()) .setOrderId(pay.getOrderId()) .setDeviceId(deviceAlgorithmCharging.getDeviceId()) .setAlgorithmId(deviceAlgorithmCharging.getAlgorithmId()) .setChargingSize(deviceAlgorithmCharging.getChargingSize()) .setChargingMoney(deviceAlgorithmCharging.getMoney()) .setType(deviceAlgorithmCharging.getType()) .setName(deviceAlgorithmCharging.getName()) .setChargingType(pay.getPayType()) .setCreateTime(now) .setUpdateTime(now) .setNote(pay.getNote()); deviceAlgorithmChargingHistories.add(deviceAlgorithmChargingHistory); }); //添加设备算法计费历史表 if (Emptys.check(deviceAlgorithmChargingHistories)) { deviceAlgorithmChargingHistoryService.saveBatch(deviceAlgorithmChargingHistories); } return R.ok(); } @Override @ApiOperation("购买回调") public R payNotice(DeviceAlgorithmChargingDto.PayNotice payNotice) { List list = deviceAlgorithmChargingHistoryService.list(new LambdaQueryWrapper().eq(DeviceAlgorithmChargingHistory::getOrderId, payNotice.getOrderId())); if (!Emptys.check(list)) { return R.ok(); } JList deviceAlgorithmChargingHistories = new JArrayList<>(list); JList infs = new JArrayList<>(); JList gives = new JArrayList<>(); LocalDateTime now = LocalDateTime.now(); int yyyyMMdd = Integer.valueOf(DataTime.getSring("yyyyMMdd")); //查询设备信息 List deviceInfos = deviceInfoService.list(new LambdaQueryWrapper().in(DeviceInfo::getDeviceId, deviceAlgorithmChargingHistories.getProperty(DeviceAlgorithmChargingHistory::getDeviceId))); JMap deviceInfoJMap = new JArrayList<>(deviceInfos).toMap(DeviceInfo::getDeviceId).cover(); //查询设备系统信息 List deviceSysinfos = deviceSysinfoService.list(new DeviceSysinfoDto.SelectList().setDeviceIds(deviceAlgorithmChargingHistories.getProperty(DeviceAlgorithmChargingHistory::getDeviceId))).getData(); JMap deviceSysinfosJMaps = new JArrayList<>(deviceSysinfos).toMap(DeviceSysinfoDto.Vo::getDeviceId).cover(); //获取算法包月字典 Map algorithmMoonConfigMaps = SysDictUtils.get(EnumAlgorithmPayConfig.Code.CODE.getCode()); //获取类型字典 Map deviceAlgorithmChargingTypeMaps = SysDictUtils.get(EnumDeviceAlgorithmChargingType.Code.CODE.getCode()); //查询商户信息 List mercs = mercService.list(new MercDto.SelectList().setMercIds(deviceAlgorithmChargingHistories.getProperty(DeviceAlgorithmChargingHistory::getMercId))).getData(); JMap mercsMaps = new JArrayList<>(mercs).toMap(MercDto.Vo::getId).cover(); JList updateDeviceInfos = new JArrayList<>(); JList> ailiActive = new JArrayList<>(); int aliDeviceType = SysDictUtils.getValue(EnumDeviceType.Code.CODE.getCode(), EnumDeviceType.N_5.getCode(), Integer.class); //处理有效期 deviceAlgorithmChargingHistories.forEach(deviceAlgorithmChargingHistory -> { //解冻设备 激活设备 if (deviceAlgorithmChargingHistory.getChargingType() != 100) { DeviceInfoDto.Update updateDeviceInfo = new DeviceInfoDto.Update() .setDeviceId(deviceAlgorithmChargingHistory.getDeviceId()); updateDeviceInfo.setFreezeStatus(1); updateDeviceInfo.setBusyState(1); DeviceInfo deviceInfo = deviceInfoJMap.get(deviceAlgorithmChargingHistory.getDeviceId()); if (deviceInfo.getActiveState() == 2) { updateDeviceInfo.setActiveState(1); } if (!Emptys.check(deviceInfo.getActiveTime())) { updateDeviceInfo.setActiveTime(now); } updateDeviceInfos.add(updateDeviceInfo); } //支付宝设备 DeviceInfo deviceInfo = deviceInfoJMap.get(deviceAlgorithmChargingHistory.getDeviceId()); if (deviceInfo.getDeviceType() == aliDeviceType) { if (deviceAlgorithmChargingHistory.getChargingType() != 100 && deviceInfo.getActiveState() == 2) { //支付宝绑定 DeviceSysinfoDto.Vo deviceSysinfo = deviceSysinfosJMaps.get(deviceAlgorithmChargingHistory.getDeviceId()); BindDeviceDTO bindDeviceDTO = new BindDeviceDTO().setTerminalId(String.valueOf(deviceInfo.getDeviceId())) .setBoardSn(deviceSysinfo.getDeviceSn()); //支付宝激活 BindActiveDTO bindActiveDTO = new BindActiveDTO() .setTerminalId(String.valueOf(deviceInfo.getDeviceId())) .setBoardSn(deviceSysinfo.getDeviceSn()) .setDeviceName(StrUtil.isNotEmpty(deviceInfo.getDeviceName()) ? deviceInfo.getDeviceName() : String.valueOf(deviceInfo.getDeviceId())); ailiActive.add(new Tuple.Tuple2<>(bindDeviceDTO, bindActiveDTO)); } } Integer type = deviceAlgorithmChargingHistory.getType(); SysDictRedis deviceAlgorithmChargingType2 = deviceAlgorithmChargingTypeMaps.get(EnumDeviceAlgorithmChargingType.N_2.getCode()); if (type.equals(Integer.valueOf(deviceAlgorithmChargingType2.getValue()))) { infs.add(deviceAlgorithmChargingHistory); return; } SysDictRedis deviceAlgorithmChargingType3 = deviceAlgorithmChargingTypeMaps.get(EnumDeviceAlgorithmChargingType.N_3.getCode()); if (type.equals(Integer.valueOf(deviceAlgorithmChargingType3.getValue()))) { gives.add(deviceAlgorithmChargingHistory); return; } SysDictRedis algorithmMoonConfigDict = algorithmMoonConfigMaps.get(deviceAlgorithmChargingHistory.getAlgorithmId().toString()); DeviceAlgorithmChargingDto.AlgorithmMoonConfig algorithmMoonConfig = JSONUtil.parseObj(algorithmMoonConfigDict.getValue()).toBean(DeviceAlgorithmChargingDto.AlgorithmMoonConfig.class); DeviceAlgorithmChargingDto.AlgorithmMoonConfig.Moon moon = algorithmMoonConfig.getMoon(); Integer chargingSize = deviceAlgorithmChargingHistory.getChargingSize(); for (Integer integer = 0; integer < chargingSize; integer++) { //查询生效时间最大的算法计费 LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper() .eq(DeviceAlgorithmCharging::getDeviceId, deviceAlgorithmChargingHistory.getDeviceId()) .eq(DeviceAlgorithmCharging::getAlgorithmId, deviceAlgorithmChargingHistory.getAlgorithmId()) .eq(DeviceAlgorithmCharging::getType, type) .orderByDesc(DeviceAlgorithmCharging::getBeginTime) .last("limit 1"); DeviceAlgorithmCharging deviceAlgorithmCharging = getOne(lambdaQueryWrapper); int beginTime; int timeout; if (deviceAlgorithmCharging == null) { beginTime = Integer.valueOf(DataTime.toString(deviceAlgorithmChargingHistory.getCreateTime(), "yyyyMMdd")); String stringAround = DataTime.getStringAround(0, 1, 0, 0, 0, 0, DataTime.toString(deviceAlgorithmChargingHistory.getCreateTime())); timeout = Integer.valueOf(DataTime.toString(DataTime.toLocal(stringAround), "yyyyMMdd")); } else { LocalDateTime localDateTime = DataTime.toLocal(deviceAlgorithmCharging.getBeginTime() + "01000000", "yyyyMMddHHmmss"); String s = DataTime.toString(localDateTime, "yyyy-MM-dd HH:mm:ss"); String stringAround = DataTime.getStringAround(0, 1, 0, 0, 0, 0, s); beginTime = Integer.valueOf(DataTime.toString(DataTime.toLocal(stringAround), "yyyyMMdd")); String stringAround1 = DataTime.getStringAround(0, 1, 0, 0, 0, 0, stringAround); timeout = Integer.valueOf(DataTime.toString(DataTime.toLocal(stringAround1), "yyyyMMdd")); } MercDto.Vo merc = mercsMaps.get(deviceAlgorithmChargingHistory.getMercId()); DeviceAlgorithmCharging deviceAlgorithmChargingInfo = new DeviceAlgorithmCharging() .setMercCode(merc.getMercCode()) .setDeviceId(deviceAlgorithmChargingHistory.getDeviceId()) .setAlgorithmId(deviceAlgorithmChargingHistory.getAlgorithmId()) .setUnusedSize(moon.getSize()) .setType(type) .setName(deviceAlgorithmChargingHistory.getName()) .setTimeout(timeout) .setBeginTime(beginTime) .setCreateTime(now) .setUpdateTime(now); save(deviceAlgorithmChargingInfo); } }); //处理无期限 infs.forEach(deviceAlgorithmChargingHistory -> { MercDto.Vo merc = mercsMaps.get(deviceAlgorithmChargingHistory.getMercId()); DeviceAlgorithmCharging deviceAlgorithmChargingInfo = new DeviceAlgorithmCharging() .setMercCode(merc.getMercCode()) .setDeviceId(deviceAlgorithmChargingHistory.getDeviceId()) .setAlgorithmId(deviceAlgorithmChargingHistory.getAlgorithmId()) .setUnusedSize(deviceAlgorithmChargingHistory.getChargingSize()) .setType(deviceAlgorithmChargingHistory.getType()) .setName(deviceAlgorithmChargingHistory.getName()) .setTimeout(-1) .setBeginTime(yyyyMMdd) .setCreateTime(now) .setUpdateTime(now); save(deviceAlgorithmChargingInfo); }); //处理赠送 gives.forEach(deviceAlgorithmChargingHistory -> { MercDto.Vo merc = mercsMaps.get(deviceAlgorithmChargingHistory.getMercId()); DeviceAlgorithmCharging deviceAlgorithmChargingInfo = new DeviceAlgorithmCharging() .setMercCode(merc.getMercCode()) .setDeviceId(deviceAlgorithmChargingHistory.getDeviceId()) .setAlgorithmId(deviceAlgorithmChargingHistory.getAlgorithmId()) .setUnusedSize(deviceAlgorithmChargingHistory.getChargingSize()) .setType(deviceAlgorithmChargingHistory.getType()) .setName(deviceAlgorithmChargingHistory.getName()) .setTimeout(payNotice.getTimeout()) .setBeginTime(yyyyMMdd) .setCreateTime(now) .setUpdateTime(now); save(deviceAlgorithmChargingInfo); }); //修改设备算法计费历史 if (Emptys.check(deviceAlgorithmChargingHistories)) { Integer status = SysDictUtils.getValue(EnumDeviceAlgorithmChargingHistoryStatus.Code.CODE.getCode(), EnumDeviceAlgorithmChargingHistoryStatus.N_2.getCode(), Integer.class); deviceAlgorithmChargingHistories.forEach(deviceAlgorithmChargingHistory -> deviceAlgorithmChargingHistory.setStatus(status)); deviceAlgorithmChargingHistoryService.updateBatchById(deviceAlgorithmChargingHistories); } //修改设备 if (Emptys.check(updateDeviceInfos)) { deviceInfoService.updateBatch(updateDeviceInfos); } //支付宝刷脸柜激活请求 log.info("支付宝刷脸柜激活请求参数:{}", ailiActive.toString()); if (Emptys.check(ailiActive)) { ThreadPoolUtils.Execute execute = ThreadPoolUtils.excPoll(DeviceThreadPoolConfig.ALI_DEVICE_ACTIVE, ailiActive.size()); ailiActive.forEach(bindDeviceDTOBindActiveDTOTuple2 -> execute.execute(() -> { //调用支付宝绑定 R.feignCheckData(alipayDeviceService.deviceBind(bindDeviceDTOBindActiveDTOTuple2.getV1())); //调用支付宝激活 R.feignCheckData(alipayDeviceService.deviceActive(bindDeviceDTOBindActiveDTOTuple2.getV2())); })); } return R.ok(); } @Override @ApiOperation("扣费") public R> charging(List chargings) { //查询商户信息 List mercs = mercService.list(new MercDto.SelectList().setMercIds(new JArrayList<>(chargings).getProperty(DeviceAlgorithmChargingDto.Charging::getMercId))).getData(); JMap mercsMaps = new JArrayList<>(mercs).toMap(MercDto.Vo::getId).cover(); //封装默认返回值 Map map = new JHashMap<>(chargings.size()); chargings.forEach(charging -> map.put(charging.getMercDeviceAlgorithmChargingId(), charging.getSize())); //查询数据 List queryList = new ArrayList<>(chargings.size()); for (DeviceAlgorithmChargingDto.Charging charging : chargings) { MercDto.Vo merc = mercsMaps.get(charging.getMercId()); String mercCode = merc.getMercCode(); List mercCodes = new ArrayList<>(); getMercCodes(mercCode, mercCodes); DeviceAlgorithmChargingChargingQueryParams deviceAlgorithmCharging = new DeviceAlgorithmChargingChargingQueryParams() .setMercCodes(mercCodes); deviceAlgorithmCharging.setDeviceId(charging.getDeviceId()); deviceAlgorithmCharging.setAlgorithmId(charging.getAlgorithmId()); deviceAlgorithmCharging.setBeginTime(charging.getAlgorithmDate()); queryList.add(deviceAlgorithmCharging); } List deviceAlgorithmChargingsList = baseMapper.chargingQuery(queryList); if (!Emptys.check(deviceAlgorithmChargingsList)) { return R.ok(map); } JList deviceAlgorithmChargings = new JArrayList<>(deviceAlgorithmChargingsList); //查询计费类型字典 Map deviceAlgorithmChargingTypeMap = SysDictUtils.get(EnumDeviceAlgorithmChargingType.Code.CODE.getCode()); SysDictRedis sysDictRedis1 = deviceAlgorithmChargingTypeMap.get(EnumDeviceAlgorithmChargingType.N_1.getCode()); SysDictRedis sysDictRedis2 = deviceAlgorithmChargingTypeMap.get(EnumDeviceAlgorithmChargingType.N_2.getCode()); SysDictRedis sysDictRedis3 = deviceAlgorithmChargingTypeMap.get(EnumDeviceAlgorithmChargingType.N_3.getCode()); //循环扣费 chargings.forEach(charging -> { //应扣数量 int size = charging.getSize(); //查找对应算法 JList deviceAlgorithmChargingJlist = deviceAlgorithmChargings.filter() .eq(DeviceAlgorithmCharging::getDeviceId, charging.getDeviceId()) .eq(DeviceAlgorithmCharging::getAlgorithmId, charging.getAlgorithmId()) .list(); if (!Emptys.check(deviceAlgorithmChargingJlist)) { return; } JMap> deviceAlgorithmChargingJMap = deviceAlgorithmChargingJlist.toMap(DeviceAlgorithmCharging::getType).group(); //递归扣费 扣费顺序为:赠送 -> 有期限 -> 无期限 int size2 = charging(size, deviceAlgorithmChargingJMap, new JArrayList().set(sysDictRedis3).set(sysDictRedis1).set(sysDictRedis2)); map.put(charging.getMercDeviceAlgorithmChargingId(), size2); }); return R.ok(map); } /** * 递归扣费 * * @return 未扣条数 */ private int charging(int size, JMap> deviceAlgorithmChargingJMap, List sysDictRediss) { if (size > 0 && Emptys.check(sysDictRediss)) { SysDictRedis sysDictRedis = sysDictRediss.remove(0); LocalDateTime now = LocalDateTime.now(); List deviceAlgorithmChargings = deviceAlgorithmChargingJMap.get(Integer.valueOf(sysDictRedis.getValue())); if (Emptys.check(deviceAlgorithmChargings)) { for (DeviceAlgorithmCharging deviceAlgorithmCharging : deviceAlgorithmChargings) { int unusedSize = deviceAlgorithmCharging.getUnusedSize(); if (unusedSize > 0) { int newUnusedSize = unusedSize - size; int makeSize; //扣除后=负数则算法条数不足 if (newUnusedSize < 0) { size = (~(newUnusedSize - 1)); newUnusedSize = 0; makeSize = unusedSize; } else { makeSize = size; size = 0; } DeviceAlgorithmCharging updateDeviceAlgorithmCharging = new DeviceAlgorithmCharging() .setId(deviceAlgorithmCharging.getId()) .setUnusedSize(newUnusedSize) .setMakeSize(deviceAlgorithmCharging.getMakeSize() + makeSize) .setUpdateTime(now); updateById(updateDeviceAlgorithmCharging); deviceAlgorithmCharging.setUnusedSize(updateDeviceAlgorithmCharging.getUnusedSize()) .setMakeSize(updateDeviceAlgorithmCharging.getMakeSize()); } } } if (size > 0 && Emptys.check(sysDictRediss)) { return charging(size, deviceAlgorithmChargingJMap, sysDictRediss); } } return size; } /** * 解析商户编码,获取上级及自身编码 * * @return */ public void getMercCodes(String mercCode, List mercCodes) { mercCodes.add(mercCode); int length = mercCode.length(); if (length == 5) { return; } String parentCode = mercCode.substring(0, length - 3); getMercCodes(parentCode, mercCodes); } }