package com.xy.service;
import com.alibaba.excel.EasyExcel;
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.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xy.annotation.Lock;
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.EnumDeviceQrCode;
import com.xy.dto.DeviceCreateIdsDto;
import com.xy.dto.SysWorkUser.ListDto;
import com.xy.dto.SysWorkUser.SysWorkVo;
import com.xy.entity.DeviceCreateIds;
import com.xy.entity.SysDictRedis;
import com.xy.error.CommRuntimeException;
import com.xy.mapper.DeviceCreateIdsMapper;
import com.xy.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
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 org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import static com.xy.utils.Beans.copy;
import static com.xy.utils.PlusBeans.toIPage;
import static com.xy.utils.PlusBeans.toPageBean;
/**
*
* 设备-机器ID号生成 服务实现类
*
*
* @author lijin
* @since 2022-12-29
*/
@Slf4j
@Service
@RequiredArgsConstructor
@Api(tags = "设备-机器ID号生成")
public class DeviceCreateIdsServiceImpl extends ServiceImpl implements DeviceCreateIdsService {
private final SysWorkUserService sysWorkUserService;
@SneakyThrows
@PostMapping("save")
@ApiOperation("添加")
@Lock("device-create-ids-save")
public R> save(@RequestBody @Validated DeviceCreateIdsDto.Save save) {
LocalDate localDate = LocalDate.now();
String year = String.valueOf(localDate.getYear());
String month = String.valueOf(localDate.getMonthValue());
String yearMonth = year.substring(2) + (month.length() == 1 ? "0" + month : month);
String property = LambdaUtils.getProperty(DeviceCreateIds::getDeviceId);
QueryWrapper queryWrapper = new QueryWrapper()
.select(String.format("max(%s) as %s", StringTools.humpToLine(property), property))
.eq(StringTools.humpToLine(LambdaUtils.getProperty(DeviceCreateIds::getIsCustom)), false);
DeviceCreateIds deviceCreateIds = getOne(queryWrapper);
JMap deviceCreateIdss = new JHashMap<>(save.getNum());
Long loginId = AuthorizeUtils.getLoginId(Long.class);
for (int i = 0; i < save.getNum(); i++) {
String tail = null;
if (deviceCreateIds != null) {
String substring = String.valueOf(deviceCreateIds.getDeviceId()).substring(0, 4);
if (substring.equals(yearMonth)) {
tail = String.valueOf(deviceCreateIds.getDeviceId() + (i + 1)).substring(4);
}
}
if (tail == null) {
tail = String.valueOf((i + 1));
int i0 = 6 - tail.length();
for (int i1 = 0; i1 < i0; i1++) {
tail = 0 + tail;
}
}
Long deviceId = Long.valueOf(yearMonth + tail);
DeviceCreateIds deviceCreateIdsInfo = copy(DeviceCreateIds.class, save)
.setDeviceId(deviceId)
.setCreateUserId(loginId)
.setCreateTime(LocalDateTime.now());
deviceCreateIdss.put(deviceId, deviceCreateIdsInfo);
}
//去重复
weight(deviceCreateIdss, save.getNum());
//添加
JList value = deviceCreateIdss.toList().value();
JList> partition = value.partition(20);
ThreadPoolUtils.Execute execute = ThreadPoolUtils.excPoll(DeviceThreadPoolConfig.DEVICE_COMMON_POLL, partition.size());
partition.forEach(createIds -> execute.execute(() -> saveBatch(createIds)));
execute.end();
return R.ok(value);
}
@PostMapping("saveCustom")
@ApiOperation("添加自定义机器号")
@Lock("device-create-ids-save")
public R saveCustom(@RequestBody @Validated DeviceCreateIdsDto.SaveCustom saveCustom) {
DeviceCreateIds deviceCreateIds = getById(saveCustom.getDeviceId());
if (deviceCreateIds != null) {
return R.fail("机器号已存在");
}
DeviceCreateIds deviceCreateIdsInfo = copy(DeviceCreateIds.class, saveCustom)
.setCreateUserId(AuthorizeUtils.getLoginId(Long.class))
.setIsCustom(true)
.setCreateTime(LocalDateTime.now());
save(deviceCreateIdsInfo);
return R.ok();
}
@PostMapping("page")
@ApiOperation("分页查询")
public R> page(@RequestBody DeviceCreateIdsDto.Page page) {
PageBean pageBean = page.getPage();
LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(page, DeviceCreateIds.class)
.ge(DeviceCreateIds::getCreateTime, page.getBeginCreateTime())
.le(DeviceCreateIds::getCreateTime, page.getEndCreateTime())
.ge(DeviceCreateIds::getBindTime, page.getBeginBindTime())
.le(DeviceCreateIds::getBindTime, page.getEndBindTime())
.build()
.orderByDesc(!Emptys.check(pageBean.getOrders()), DeviceCreateIds::getCreateTime);
IPage iPage = page(toIPage(pageBean), lambdaQueryWrapper);
PageBean voPageBean = toPageBean(PlusBeans.copy(DeviceCreateIdsDto.Vo.class, iPage));
List records = voPageBean.getRecords();
JList createUserIds = new JArrayList<>(records).getProperty(DeviceCreateIdsDto.Vo::getCreateUserId);
List sysWorkVos = sysWorkUserService.list(new ListDto().setId(createUserIds)).getData();
if (Emptys.check(sysWorkVos)) {
JMap sysWorkVoJMap = new JArrayList<>(sysWorkVos).toMap(SysWorkVo::getId).cover();
records.forEach(vo -> {
SysWorkVo sysWorkVo = sysWorkVoJMap.get(vo.getCreateUserId());
if (sysWorkVo == null) {
return;
}
vo.setCreateUserName(sysWorkVo.getAccount());
});
}
return R.ok(voPageBean);
}
@Override
@ApiOperation("修改")
public R update(DeviceCreateIdsDto.Update update) {
DeviceCreateIds deviceCreateIds = copy(DeviceCreateIds.class, update);
updateById(deviceCreateIds);
return R.ok();
}
@PostMapping("exportQrCode")
@ApiOperation("导出二维码")
public void exportQrCode(@RequestBody DeviceCreateIdsDto.ExportQrCode exportQrCode) {
SysDictRedis sysDictRedis = SysDictUtils.get(EnumDeviceQrCode.Code.CODE.getCode(), EnumDeviceQrCode.URL.getCode());
List list = new ArrayList<>();
Boolean isWhere = exportQrCode.getIsWhere() == null ? false : exportQrCode.getIsWhere();
if (!isWhere) {
List deviceIds = exportQrCode.getDeviceIds();
if (Emptys.check(deviceIds)) {
deviceIds.forEach(deviceId -> list.add(deviceId.toString()));
}
} else {
LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(exportQrCode, DeviceCreateIds.class)
.ge(DeviceCreateIds::getCreateTime, exportQrCode.getBeginCreateTime())
.le(DeviceCreateIds::getCreateTime, exportQrCode.getEndCreateTime())
.ge(DeviceCreateIds::getBindTime, exportQrCode.getBeginBindTime())
.le(DeviceCreateIds::getBindTime, exportQrCode.getEndBindTime())
.build();
List deviceCreateIds = list(lambdaQueryWrapper);
deviceCreateIds.forEach(deviceCreateIds1 -> list.add(String.valueOf(deviceCreateIds1.getDeviceId())));
}
if (!Emptys.check(list)) {
throw new CommRuntimeException("没有导出的数据");
}
List infos = new ArrayList<>();
for (String deviceId : list) {
infos.add(sysDictRedis.getValue() + deviceId);
}
QRCodeUtils.create(infos, 400, 400, "back1.png", list).download(list);
}
@SneakyThrows
@ApiOperation("下载自定义设备id模板")
@PostMapping("downloadIdTemplet")
public void downloadIdTemplet(HttpServletResponse response) {
InputStream inputStream = IoUtils.inputStream("id_templet.xlsx").get();
response.setHeader("Content-Disposition", "attachment; filename=" + "id_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);
}
}
@ApiOperation("批量添加自定义机器号")
@PostMapping("uploadSaveCustom")
public R uploadSaveCustom(@RequestParam("file") MultipartFile file, @RequestParam("deviceType") Integer deviceType, @RequestParam("doorType") String doorType, @RequestParam("createPc") String createPc) {
ThreadPoolUtils.excPoll(DeviceThreadPoolConfig.DEVICE_COMMON_POLL, 1)
.execute(() -> {
try {
EasyExcel.read(file.getInputStream(), UploadSaveCustom.class, new UploadSaveCustomListener(deviceType, doorType, createPc, AuthorizeUtils.getLoginId(Long.class), this)).sheet().doRead();
} catch (IOException e) {
log.error("", e);
}
});
return R.ok();
}
private void weight(JMap deviceCreateIdss, int num) {
List list = list(new LambdaQueryWrapper().in(DeviceCreateIds::getDeviceId, deviceCreateIdss.toList().key()));
if (Emptys.check(list)) {
list.forEach(deviceCreateIdsInfo -> {
//添加
DeviceCreateIds deviceCreateIdsOld = deviceCreateIdss.get(deviceCreateIdsInfo.getDeviceId());
Long deviceId = deviceCreateIdsOld.getDeviceId() + num;
deviceCreateIdss.put(deviceId, copy(DeviceCreateIds.class, deviceCreateIdsOld).setDeviceId(deviceId));
//删除
deviceCreateIdss.remove(deviceCreateIdsInfo.getDeviceId());
});
weight(deviceCreateIdss, num);
}
}
@Slf4j
@RequiredArgsConstructor
public static class UploadSaveCustomListener implements ReadListener {
private final Integer deviceType;
private final String doorType;
private final String createPc;
private final Long loginId;
private final DeviceCreateIdsServiceImpl deviceCreateIdsService;
private JMap deviceIds = new JHashMap<>();
/**
* 这个每一条数据解析都会来调用
*
* @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param context
*/
@Override
public void invoke(UploadSaveCustom data, AnalysisContext context) {
deviceIds.put(data.getDeviceId(), data);
}
/**
* 所有数据解析完成了 都会来调用
*
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
List list = deviceCreateIdsService.list(new LambdaQueryWrapper().in(DeviceCreateIds::getDeviceId, deviceIds.toList().key()));
if (Emptys.check(list)) {
list.forEach(deviceCreateIds -> {
deviceIds.remove(deviceCreateIds.getDeviceId());
log.info("重复的设备号:{}", deviceCreateIds.getDeviceId());
});
}
if (Emptys.check(deviceIds)) {
LocalDateTime now = LocalDateTime.now();
JList deviceIds2 = deviceIds.toList().key();
List saves = new ArrayList<>(deviceIds2.size());
deviceIds2.forEach(deviceId -> {
DeviceCreateIds deviceCreateIdsInfo = new DeviceCreateIds()
.setDeviceId(deviceId)
.setDeviceType(deviceType)
.setDoorType(doorType)
.setCreatePc(createPc)
.setCreateUserId(loginId)
.setIsCustom(true)
.setCreateTime(now);
saves.add(deviceCreateIdsInfo);
});
deviceCreateIdsService.saveBatch(saves);
log.info("批量添加自定义机器号完成,共{}条", saves.size());
}
}
}
@Data
public static class UploadSaveCustom {
private Long deviceId;
}
}