package com.xy.service;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
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.dto.CommandMqtt;
import com.xy.dto.DeviceAnnualFeeDto;
import com.xy.dto.MqttUserDto;
import com.xy.dto.be.MercDto;
import com.xy.entity.*;
import com.xy.error.CommRuntimeException;
import com.xy.mapper.DeviceAnnualFeeMapper;
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.Data;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.util.*;
import static com.xy.utils.PlusBeans.toIPage;
import static com.xy.utils.PlusBeans.toPageBean;
/**
*
* 设备年费表 服务实现类
*
*
* @author lijin
* @since 2025-02-28
*/
@Slf4j
@Service
@AllArgsConstructor(onConstructor_ = @Lazy)
@Api(tags = "设备年费表")
public class DeviceAnnualFeeServiceImpl extends ServiceImpl implements DeviceAnnualFeeService {
private DeviceCreateIdsServiceImpl deviceCreateIdsService;
private DeviceRegisterServiceImpl deviceRegisterService;
private DeviceInfoServiceImpl deviceInfoService;
private DeviceSysinfoServiceImpl deviceSysinfoService;
private DeviceStatusServiceImpl deviceStatusService;
private DevicePartServiceImpl devicePartService;
private MqttUserServiceImpl mqttUserService;
private MercService mercService;
private MqttService mqttService;
@PostMapping("check")
@ApiOperation("检查")
public R check(@RequestBody @Validated DeviceAnnualFeeDto.Check check) {
log.info("独立部署检查:{},{},运行环境:{}", check.getDeviceId(), check.getSn(), check.getRunPlatform());
Long deviceId = check.getDeviceId();
String sn = check.getSn();
if (!Emptys.check(deviceId) && !Emptys.check(sn)) {
throw new CommRuntimeException("deviceId和sn必须传入一个");
}
if (!Emptys.check(deviceId)) {
DeviceSysinfo deviceSysinfo = deviceSysinfoService.getOne(new LambdaQueryWrapper()
.eq(DeviceSysinfo::getDeviceSn, sn)
);
if (deviceSysinfo == null) {
throw new CommRuntimeException("sn未查找到设备");
}
deviceId = deviceSysinfo.getDeviceId();
}
DeviceAnnualFee deviceAnnualFee = getOne(new LambdaQueryWrapper()
.eq(DeviceAnnualFee::getDeviceId, deviceId)
.eq(DeviceAnnualFee::getIsThis, true)
);
if (deviceAnnualFee == null) {
return R.fail("设备未分配到年费商家");
}
deviceAnnualFee.setRunPlatform(check.getRunPlatform());
updateById(deviceAnnualFee);
String timeout = DataTime.toString(deviceAnnualFee.getTimeout());
int i = DataTime.stringContrast(timeout, DataTime.getSring());
if (i < 0) {
return R.fail("已欠费");
}
return R.ok(timeout);
}
@PostMapping("page")
@ApiOperation("分页查询")
public R> page(@RequestBody DeviceAnnualFeeDto.Page page) {
LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery()
.eqWrapper(page, DeviceAnnualFee.class)
.ge(DeviceAnnualFee::getTimeout, page.getBeginTime())
.le(DeviceAnnualFee::getTimeout, page.getEndTime())
.build();
IPage iPage = page(toIPage(page.getPage()), lambdaQueryWrapper);
PageBean pageBean = toPageBean(DeviceAnnualFeeDto.Vo.class, iPage);
List records = pageBean.getRecords();
if (Emptys.check(records)) {
List mercs = mercService.list(new MercDto.SelectList().setMercIds(new JArrayList<>(records).getProperty(DeviceAnnualFeeDto.Vo::getMercId).comparing())).getData();
JMap cover = new JArrayList<>(mercs).toMap(MercDto.Vo::getId).cover();
Map stringSysDictRedisMap = SysDictUtils.get("merc_device_annual_fee");
for (DeviceAnnualFeeDto.Vo record : records) {
MercDto.Vo merc = cover.get(record.getMercId());
SysDictRedis sysDictRedis = stringSysDictRedisMap.get(String.valueOf(record.getMercId()));
JSONObject jsonObject = JSONUtil.parseObj(sysDictRedis.getValue());
record.setMoney(jsonObject.getInt("money"))
.setMercName(merc.getName());
}
}
return R.ok(pageBean);
}
@PostMapping("mercPage")
@ApiOperation("商家分页查询(无token)")
public R> mercPage(@RequestBody DeviceAnnualFeeDto.Page page) {
if (!Emptys.check(page.getCode())) {
return R.fail("code不能为空");
}
Map stringSysDictRedisMap = SysDictUtils.get("merc_device_annual_fee");
SysDictRedis sysDictRedis = stringSysDictRedisMap.get(page.getCode());
if (sysDictRedis == null) {
return R.fail("code未配置商家");
}
page.setMercId(Long.valueOf(sysDictRedis.getValue())).setRegisterStatus(true);
return page(page);
}
@SneakyThrows
@ApiOperation("导出年费模版")
@PostMapping("download")
public void download(HttpServletResponse response) {
InputStream inputStream = IoUtils.inputStream("device_annual_fee_templet.xlsx").get();
response.setHeader("Content-Disposition", "attachment; filename=" + "device_annual_fee_templet.xlsx");
response.setContentType("application/xlsx");
byte[] buffer = new byte[1024];
int bytesRead;
OutputStream outputStream = response.getOutputStream();
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outputStream.close();
}
@SneakyThrows
@ApiOperation("导入年费数据")
@PostMapping("upload")
public R upload(@RequestParam("file") MultipartFile file) {
EasyExcel.read(file.getInputStream(), UploadInfo.class, new UploadListener(this)).sheet().doRead();
return R.ok();
}
@PostMapping("sendDeviceInfo")
@ApiOperation("推送设备到商家平台(无token)")
public R sendDeviceInfo(@RequestBody @Validated DeviceAnnualFeeDto.SendDeviceInfo sendDeviceInfo) {
List deviceIds = sendDeviceInfo.getDeviceIds();
//设备年费信息
List deviceAnnualFees = list(new LambdaQueryWrapper()
.in(DeviceAnnualFee::getDeviceId, deviceIds)
.eq(DeviceAnnualFee::getIsThis, true)
);
JMap deviceAnnualFeesJMaps = new JArrayList<>(deviceAnnualFees).toMap(DeviceAnnualFee::getDeviceId).cover();
//设备id创建信息
List deviceCreateIdss = deviceCreateIdsService.listByIds(deviceIds);
JMap deviceCreateIdsJMaps = new JArrayList<>(deviceCreateIdss).toMap(DeviceCreateIds::getDeviceId).cover();
//设备注册信息
List deviceRegisters = deviceRegisterService.listByIds(deviceIds);
JMap deviceRegistersJMaps = new JArrayList<>(deviceRegisters).toMap(DeviceRegister::getDeviceId).cover();
//设备信息
List deviceInfos = deviceInfoService.listByIds(deviceIds);
JMap deviceInfosJMaps = new JArrayList<>(deviceInfos).toMap(DeviceInfo::getDeviceId).cover();
//设备系统信息
List deviceSysinfos = deviceSysinfoService.listByIds(deviceIds);
JMap deviceSysinfosJMaps = new JArrayList<>(deviceSysinfos).toMap(DeviceSysinfo::getDeviceId).cover();
//设备状态信息
List deviceStatuses = deviceStatusService.listByIds(deviceIds);
JMap deviceStatusesJMaps = new JArrayList<>(deviceStatuses).toMap(DeviceStatus::getDeviceId).cover();
//设备配件信息
List devicePartss = devicePartService.list(new LambdaQueryWrapper()
.in(DevicePart::getDeviceId, deviceIds)
);
JMap> devicePartsJMaps = new JHashMap<>();
if (Emptys.check(devicePartss)) {
devicePartsJMaps = new JArrayList<>(devicePartss).toMap(DevicePart::getDeviceId).group();
}
JMap> finalDevicePartsJMaps = devicePartsJMaps;
//mqtt连接信息
List mqttUsers = mqttUserService.list(new LambdaQueryWrapper()
.in(MqttUser::getDeviceId, deviceIds)
);
JMap mqttUsersJMaps = new JArrayList<>(mqttUsers).toMap(MqttUser::getDeviceId).cover();
//字典信息
Map stringSysDictRedisMap = SysDictUtils.get("merc_device_annual_fee");
//组装请求对象
FunctionUtils.NoParamsResult