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.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 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.*; import com.xy.dto.*; import com.xy.dto.be.MercDto; import com.xy.entity.*; import com.xy.mapper.DeviceChargingMapper; 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.context.annotation.Lazy; 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 java.math.BigDecimal; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static com.xy.utils.Beans.copy; import static com.xy.utils.PlusBeans.toIPage; import static com.xy.utils.PlusBeans.toPageBean; /** *

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

* * @author lijin * @since 2023-04-14 */ @Slf4j @Service @Api(tags = "设备计费表") @AllArgsConstructor(onConstructor_ = @Lazy) public class DeviceChargingServiceImpl extends ServiceImpl implements DeviceChargingService { private DeviceChargingHistoryServiceImpl deviceChargingHistoryService; private DeviceInfoServiceImpl deviceInfoService; private DeviceTypeAlgorithmBeforConfigServiceImpl deviceTypeAlgorithmBeforConfigService; private DeviceChargingConfigServiceImpl deviceChargingConfigService; private DeviceAlgorithmChargingServiceImpl deviceAlgorithmChargingService; private DeviceStatusServiceImpl deviceStatusService; private DeviceSysinfoServiceImpl deviceSysinfoService; private AlipayDeviceService alipayDeviceService; private MercFeeConfigService mercFeeConfigService; private MercService mercService; @PostMapping("updateTimeout") @ApiOperation("修改过期时间") public R updateTimeout(@RequestBody @Validated DeviceChargingDto.UpdateTimeout updateTimeout) { update(new LambdaUpdateWrapper() .set(DeviceCharging::getTimeout, updateTimeout.getTimeout()) .in(DeviceCharging::getDeviceId, updateTimeout.getDeviceIds()) ); return R.ok(); } @PostMapping("del") @ApiOperation("删除") public R del(@RequestBody @Validated DeviceChargingDto.Del del) { removeBatchByIds(del.getDeviceId()); return R.ok(); } @PostMapping("payCheck") @ApiOperation("购买反显") public R> payCheck(@RequestBody @Validated DeviceChargingDto.PayCheck payCheck) { Map result = new HashMap<>(); List deviceIds = payCheck.getDeviceId(); List list = deviceInfoService.list(new LambdaQueryWrapper() .in(DeviceInfo::getDeviceId, deviceIds) ); if (!Emptys.check(list)) { return R.fail("设备不存在"); } JList deviceInfos = new JArrayList<>(list); JMap cover = deviceInfos.toMap(DeviceInfo::getDeviceType).cover(); if (cover.size() > 1) { return R.fail("设备类型必须一致"); } // 佣金配置查询 MercFeeConfigDto.FeeConfigByMercVO mercFeeConfig = R.feignCheckData(mercFeeConfigService.getFeeConfigByMerc(new MercFeeConfigDto.FeeConfigByMerc().setMercCode(list.get(0).getMercCode()))); // 查询设备状态信息 List deviceStatuses = deviceStatusService.list(new LambdaQueryWrapper().in(DeviceStatus::getDeviceId, deviceIds)); JMap deviceStatusesJMaps = new JArrayList<>(deviceStatuses).toMap(DeviceStatus::getDeviceId).cover(); List mercCodes = new ArrayList<>(); deviceAlgorithmChargingService.getMercCodes(list.get(0).getMercCode(), mercCodes); // 查询设备计费配置表 设备管理费 List deviceChargingConfigs = deviceChargingConfigService.list(new LambdaQueryWrapper() .in(DeviceChargingConfig::getMercCode, mercCodes) .eq(DeviceChargingConfig::getType, SysDictUtils.getValue(EnumDeviceChargingConfigType.Code.CODE.getCode(), EnumDeviceChargingConfigType.N_2.getCode(), Integer.class)) .eq(DeviceChargingConfig::getDeviceType, list.get(0).getDeviceType()) .orderByDesc(DeviceChargingConfig::getMercCode) ); // 设备管理费 int standard = Emptys.check(deviceChargingConfigs) ? (deviceChargingConfigs.get(0).getConfigValue()) : SysDictUtils.getValue(EnumDeviceCharging.Code.CODE.getCode(), String.valueOf(list.get(0).getDeviceType()), Integer.class); standard = mercFeeConfig.getFeeDevice() + standard; String deviceTypeName = SysDictUtils.get(EnumDeviceType.Code.CODE.getCode(), String.valueOf(list.get(0).getDeviceType())).getMsg(); // 查询算法预充配置 设备激活 JList values = cover.getValues(); List deviceTypeAlgorithmBeforConfigs = deviceTypeAlgorithmBeforConfigService.list(new LambdaQueryWrapper() .eq(DeviceTypeAlgorithmBeforConfig::getDeviceType, list.get(0).getDeviceType()) .in(DeviceTypeAlgorithmBeforConfig::getMercCode, mercCodes) .in(DeviceTypeAlgorithmBeforConfig::getAlgorithmId, values.getProperty(DeviceInfo::getAlgorithmId)) ); JMap deviceTypeAlgorithmBeforConfigsJMaps = Emptys.check(deviceTypeAlgorithmBeforConfigs) ? new JArrayList<>(deviceTypeAlgorithmBeforConfigs).toMap(DeviceTypeAlgorithmBeforConfig::getAlgorithmId).cover() : new JHashMap<>(); // 查询默认算法信息 JList algorithmIds = deviceInfos.getProperty(DeviceInfo::getAlgorithmId); Map moonAlgorithmTypesMap = new HashMap<>(); Map algorithmPayConfigMap = new HashMap<>(); for (Long algorithmId : algorithmIds) { SysDictRedis moonAlgorithmTypes = SysDictUtils.get(EnumAlgorithmTypes.Code.CODE.getCode(), String.valueOf(algorithmId)); SysDictRedis algorithmPayConfig = SysDictUtils.get(EnumAlgorithmPayConfig.Code.CODE.getCode(), String.valueOf(algorithmId)); if (Emptys.check(moonAlgorithmTypes)) { moonAlgorithmTypesMap.put(algorithmId, moonAlgorithmTypes.getMsg()); } if (Emptys.check(algorithmPayConfig)) { algorithmPayConfigMap.put(algorithmId, algorithmPayConfig.getValue()); } } for (DeviceInfo deviceInfo : list) { // 封装设备信息 DeviceChargingDto.PayCheckVo payCheckVo = new DeviceChargingDto.PayCheckVo(); DeviceStatus deviceStatus = deviceStatusesJMaps.get(deviceInfo.getDeviceId()); DeviceChargingDto.PayCheckVo.DeviceInfo deviceInfoObj = Beans.copy(Beans.copy(DeviceChargingDto.PayCheckVo.DeviceInfo.class, deviceInfo), deviceStatus) .setDeviceTypeName(deviceTypeName) .setStandard(BigDecimal.valueOf(standard).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_DOWN).doubleValue() + "元/年") .setMoney(standard); // 封装算法购买信息 DeviceTypeAlgorithmBeforConfig deviceTypeAlgorithmBeforConfig = deviceTypeAlgorithmBeforConfigsJMaps.get(deviceInfo.getAlgorithmId()); String algorithmName = moonAlgorithmTypesMap.get(deviceInfo.getAlgorithmId()); String algorithmPayConfig = algorithmPayConfigMap.get(deviceInfo.getAlgorithmId()); DeviceAlgorithmChargingDto.AlgorithmMoonConfig algorithmMoonConfig = JSONUtil.parseObj(algorithmPayConfig).toBean(DeviceAlgorithmChargingDto.AlgorithmMoonConfig.class); DeviceAlgorithmChargingDto.AlgorithmMoonConfig.Inf inf = algorithmMoonConfig.getInf(); // 单笔算法费用 代理商额外收取 int extraSingleMoney = mercFeeConfig.getFeeAlgorithm(); DeviceChargingDto.PayCheckVo.DeviceAlgorithmCharging infDeviceAlgorithmCharging = Beans.copy(DeviceChargingDto.PayCheckVo.DeviceAlgorithmCharging.class, deviceInfo) .setDeviceTypeName(deviceTypeName) .setAlgorithmId(deviceInfo.getAlgorithmId()) .setAlgorithmName(algorithmName) // 算法计费标准 .setStandard(BigDecimal.valueOf(algorithmMoonConfig.getPrice() + extraSingleMoney).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_DOWN).doubleValue() + "元/每笔(" + inf.getSize() + "笔)") // 设备激活 代理商费用 deviceTypeAlgorithmBeforConfig.getExtraMoney() .setMoney(deviceTypeAlgorithmBeforConfig == null ? inf.getMoney() + mercFeeConfig.getFeeActive() : deviceTypeAlgorithmBeforConfig.getMoney() + mercFeeConfig.getFeeActive()); // 封装算法包月信息 DeviceAlgorithmChargingDto.AlgorithmMoonConfig.Moon moon = algorithmMoonConfig.getMoon(); DeviceChargingDto.PayCheckVo.DeviceAlgorithmCharging moonDeviceAlgorithmCharging = Beans.copy(DeviceChargingDto.PayCheckVo.DeviceAlgorithmCharging.class, deviceInfo) .setDeviceTypeName(deviceTypeName) .setAlgorithmId(deviceInfo.getAlgorithmId()) .setAlgorithmName(algorithmName) .setStandard(BigDecimal.valueOf(algorithmMoonConfig.getPrice()).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_DOWN).doubleValue() + "元/包月(" + moon.getSize() + "笔)") .setMoney(moon.getMoney()); payCheckVo.setDeviceInfo(deviceInfoObj) .setInfDeviceAlgorithmCharging(infDeviceAlgorithmCharging) .setMoonDeviceAlgorithmCharging(moonDeviceAlgorithmCharging); result.put(deviceInfo.getDeviceId(), payCheckVo); } return R.ok(result); } @PostMapping("check") @ApiOperation("检查") public R check(@RequestBody @Validated DeviceChargingDto.Check check) { LocalDateTime now = LocalDateTime.now(); DeviceCharging deviceCharging = getById(check.getDeviceId()); // 不存在则新增 if (deviceCharging == null) { // 查询设备计费配置表 DeviceInfoDto.Vo deviceInfo = deviceInfoService.obj(new DeviceInfoDto.Obj().setDeviceId(check.getDeviceId())).getData(); List mercCodes = new ArrayList<>(); deviceAlgorithmChargingService.getMercCodes(deviceInfo.getMercCode(), mercCodes); List deviceChargingConfigs = deviceChargingConfigService.list(new LambdaQueryWrapper() .in(DeviceChargingConfig::getMercCode, mercCodes) .eq(DeviceChargingConfig::getType, SysDictUtils.getValue(EnumDeviceChargingConfigType.Code.CODE.getCode(), EnumDeviceChargingConfigType.N_1.getCode(), Integer.class)) .eq(DeviceChargingConfig::getDeviceType, deviceInfo.getDeviceType()) .orderByDesc(DeviceChargingConfig::getMercCode) ); // 有则使用,无则使用默认字典 int chargingX = Emptys.check(deviceChargingConfigs) ? deviceChargingConfigs.get(0).getConfigValue() : SysDictUtils.getValue(EnumDeviceCharging.Code.CODE.getCode(), EnumDeviceCharging.N_X.getCode(), Integer.class); // 新增 String timeout = DataTime.getStringAround(0, 0, chargingX, 0, 0, 0); deviceCharging = new DeviceCharging() .setDeviceId(check.getDeviceId()) .setTimeout(DataTime.toLocal(timeout)) .setCreateTime(now); save(deviceCharging); } // 验证过期时间 int contrast = DataTime.stringContrast(DataTime.toString(deviceCharging.getTimeout()), DataTime.toString(now)); if (contrast <= 0) { return R.fail(R.Enum.CHARGING.getCode(), R.Enum.CHARGING.getMsg()); } return R.ok(); } @PostMapping("page") @ApiOperation("分页查询") public R> page(@RequestBody DeviceChargingDto.Page page) { Integer value = SysDictUtils.getValue(EnumDeviceCharging.Code.CODE.getCode(), EnumDeviceCharging.N_200.getCode(), Integer.class); Integer prep = SysDictUtils.getValue(EnumDeviceChargingConfigType.Code.CODE.getCode(), EnumDeviceChargingConfigType.N_2.getCode(), Integer.class); String theTime = DataTime.getStringAround(0, 0, value, 0, 0, 0); page.setThisTime(LocalDateTime.now()).setTheTime(DataTime.toLocal(theTime)); IPage iPage = baseMapper.page(toIPage(page.getPage()), page); List records = iPage.getRecords(); if (Emptys.check(records)) { Map stringSysDictRedisMap = SysDictUtils.get(EnumDeviceCharging.Code.CODE.getCode()); Long mercId = page.getMercId(); MercDto.Vo merc = mercService.obj(new MercDto.Vo().setId(mercId)).getData(); // 佣金配置查询 MercFeeConfigDto.FeeConfigByMercVO mercFeeConfig = R.feignCheckData(mercFeeConfigService.getFeeConfigByMerc(new MercFeeConfigDto.FeeConfigByMerc().setMercCode(merc.getMercCode()))); // 设备管理费佣金 Integer feeDevice = mercFeeConfig.getFeeDevice(); for (DeviceChargingDto.PageVo record : records) { // 封装过期状态说明 String timeoutStatus; DeviceChargingDto.Vo deviceCharging = record.getDeviceCharging(); LocalDateTime timeout = deviceCharging.getTimeout(); long s = DataTime.diff(page.getThisTime(), timeout, "s"); if (s <= 0) { timeoutStatus = "欠费(" + (~(s / 86400 - 1)) + "天)"; } else { timeoutStatus = s <= value * 86400 ? "即将到期(" + s / 86400 + "天)" : "正常(" + s / 86400 + "天)"; } record.getDeviceCharging().setTimeoutStatus(timeoutStatus); DeviceInfoDto.Vo deviceInfo = record.getDeviceInfo(); // 查询设备计费配置 DeviceChargingConfigDto.SelectList selectList = new DeviceChargingConfigDto.SelectList() .setDeviceType(deviceInfo.getDeviceType()) .setMercId(deviceInfo.getMercId()); selectList.setType(prep); List deviceChargingConfigs = deviceChargingConfigService.list2(selectList).getData(); if (Emptys.check(deviceChargingConfigs)) { // 获取自定义配置计费标准 DeviceChargingConfigDto.Vo deviceChargingConfig = deviceChargingConfigs.get(0); record.setChargingMoney(deviceChargingConfig.getConfigValue() + feeDevice); } else { // 获取默认计费标准 SysDictRedis sysDictRedis = stringSysDictRedisMap.get(deviceInfo.getDeviceType().toString()); if (sysDictRedis != null) { record.setChargingMoney(Integer.valueOf(sysDictRedis.getValue()) + feeDevice); } } } } return R.ok(toPageBean(iPage)); } @Override @ApiOperation("购买") public R pay(DeviceChargingDto.Pay pay) { JList deviceChargings = new JArrayList<>(pay.getDeviceChargings()); Integer payType = pay.getPayType(); LocalDateTime now = LocalDateTime.now(); JList deviceChargingHistories = new JArrayList<>(); deviceChargings.forEach(deviceCharging -> { DeviceChargingHistory deviceChargingHistory = new DeviceChargingHistory() .createId() .setMercId(pay.getMercId()) .setOrderId(pay.getOrderId()) .setDeviceId(deviceCharging.getDeviceId()) .setChargingSize(deviceCharging.getNum()) .setChargingMoney(deviceCharging.getChargingMoney()) .setChargingType(payType) .setCreateTime(now) .setUpdateTime(now) .setNote(pay.getNote()); deviceChargingHistories.add(deviceChargingHistory); }); if (!Emptys.check(deviceChargingHistories)) { return R.fail(); } // 添加设备计费历史表 deviceChargingHistoryService.saveBatch(deviceChargingHistories); return R.ok(); } @Override @ApiOperation("购买回调") public R payNotice(DeviceChargingDto.PayNotice payNotice) { // 查询设备计费历史表 List list = deviceChargingHistoryService.list(new LambdaQueryWrapper().eq(DeviceChargingHistory::getOrderId, payNotice.getOrderId())); if (!Emptys.check(list)) { return R.ok(); } LocalDateTime now = LocalDateTime.now(); JList deviceChargingHistories = new JArrayList<>(list); int aliDeviceType = SysDictUtils.getValue(EnumDeviceType.Code.CODE.getCode(), EnumDeviceType.N_5.getCode(), Integer.class); // 查询设备信息 List deviceInfos = deviceInfoService.list(new LambdaQueryWrapper().in(DeviceInfo::getDeviceId, deviceChargingHistories.getProperty(DeviceChargingHistory::getDeviceId))); JMap deviceInfoJMap = new JArrayList<>(deviceInfos).toMap(DeviceInfo::getDeviceId).cover(); // 查询设备系统信息 List deviceSysinfos = deviceSysinfoService.list(new DeviceSysinfoDto.SelectList().setDeviceIds(deviceChargingHistories.getProperty(DeviceChargingHistory::getDeviceId))).getData(); JMap deviceSysinfosJMaps = new JArrayList<>(deviceSysinfos).toMap(DeviceSysinfoDto.Vo::getDeviceId).cover(); // 查询设备计费表 List deviceChargings = list(new LambdaQueryWrapper().in(DeviceCharging::getDeviceId, deviceChargingHistories.getProperty(DeviceChargingHistory::getDeviceId))); JMap deviceChargingsJMaps = new JArrayList<>(deviceChargings).toMap(DeviceCharging::getDeviceId).cover(); // 获取已支付字典 Integer status = SysDictUtils.getValue(EnumDeviceChargingHistoryStatus.Code.CODE.getCode(), EnumDeviceChargingHistoryStatus.N_2.getCode(), Integer.class); JList updateDeviceCharging = new JArrayList<>(); JList updateDeviceInfos = new JArrayList<>(); JList updateDeviceChargingHistory = new JArrayList<>(); JList> ailiActive = new JArrayList<>(); for (DeviceChargingHistory deviceChargingHistory : deviceChargingHistories) { DeviceInfo deviceInfo = deviceInfoJMap.get(deviceChargingHistory.getDeviceId()); DeviceCharging deviceCharging = deviceChargingsJMaps.get(deviceChargingHistory.getDeviceId()) .setLastChargingPayType(deviceChargingHistory.getChargingType()) .setLastChargingMoney(deviceChargingHistory.getChargingMoney()) .setLastChargingTime(now); Integer chargingSize = deviceChargingHistory.getChargingSize(); boolean fal = false; // 设备计费历史完成 deviceChargingHistory.setStatus(status); String timeout = DataTime.getStringAround(chargingSize, 0, 0, 0, 0, 0, DataTime.toString(deviceCharging.getTimeout())); deviceCharging.setChargingSumMoney(deviceCharging.getChargingSumMoney() + deviceChargingHistory.getChargingMoney()) .setTimeout(DataTime.toLocal(timeout)); // 过期时间大于当前时间 if (DataTime.stringContrast(timeout, DataTime.toString(now)) > 0) { fal = true; } if (fal) { // 解冻设备 DeviceInfoDto.Update updateDeviceInfo = new DeviceInfoDto.Update() .setDeviceId(deviceChargingHistory.getDeviceId()); updateDeviceInfo.setFreezeStatus(1); // 激活设备 if (deviceChargingHistory.getChargingType() != 100) { if (deviceInfo.getActiveState() == 2) { updateDeviceInfo.setActiveState(1); } if (!Emptys.check(deviceInfo.getActiveTime())) { updateDeviceInfo.setActiveTime(now); } } updateDeviceInfos.add(updateDeviceInfo); } // 支付宝设备 if (deviceInfo.getDeviceType() == aliDeviceType) { if (deviceChargingHistory.getChargingType() != 100 && deviceInfo.getActiveState() == 2) { // 支付宝绑定 DeviceSysinfoDto.Vo deviceSysinfo = deviceSysinfosJMaps.get(deviceChargingHistory.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)); //运营状态运营 alipayDeviceService.changeStatus(new DeviceChangeStatusDTO() .setTerminalId(String.valueOf(deviceInfo.getDeviceId())) .setOperatorId("1") .setStatus(1) ); } } updateDeviceCharging.add(deviceCharging); updateDeviceChargingHistory.add(deviceChargingHistory); } int size = 50; // 修改设备计费记录 if (Emptys.check(updateDeviceCharging)) { JList> partition = updateDeviceCharging.partition(size); partition.forEach(data -> updateBatchById(data)); } // 修改设备计费历史记录 if (Emptys.check(updateDeviceChargingHistory)) { JList> partition = updateDeviceChargingHistory.partition(size); partition.forEach(data -> deviceChargingHistoryService.updateBatchById(data)); } // 修改设备 if (Emptys.check(updateDeviceInfos)) { JList> partition = updateDeviceInfos.partition(size); partition.forEach(data -> deviceInfoService.updateBatch(data)); } // 支付宝刷脸柜激活请求 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> list(DeviceChargingDto.SelectList selectList) { LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper() .in(DeviceCharging::getDeviceId, selectList.getDeviceIds()); List list = list(lambdaQueryWrapper); List copy = copy(DeviceChargingDto.Vo.class, list); return R.ok(copy); } @Override @ApiOperation("查询过期条数") public R deviceChargingTimeoutCount(DeviceChargingDto.DeviceChargingTimeoutCount deviceChargingTimeoutCount) { String now = DataTime.getSring(); int day = SysDictUtils.getValue(EnumDeviceCharging.Code.CODE.getCode(), EnumDeviceCharging.N_200.getCode(), Integer.class); String end1 = DataTime.getStringAround(0, 0, day, 0, 0, 0, now); deviceChargingTimeoutCount.setBegin1(now) .setEnd1(end1) .setEnd2(now); DeviceChargingDto.DeviceChargingTimeoutCountVo deviceChargingTimeoutCountVo = baseMapper.deviceChargingTimeoutCount(deviceChargingTimeoutCount); return R.ok(deviceChargingTimeoutCountVo); } }