package com.xy.service;
import cn.hutool.core.bean.BeanUtil;
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.collections.list.JArrayList;
import com.xy.collections.map.JConcurrentHashMap;
import com.xy.collections.map.JHashMap;
import com.xy.collections.map.JMap;
import com.xy.dto.DeviceDataDto;
import com.xy.dto.DeviceInfoDto;
import com.xy.entity.DeviceData;
import com.xy.entity.SysDictRedis;
import com.xy.mapper.DeviceDataMapper;
import com.xy.utils.*;
import com.xy.utils.enums.DictEnum;
import com.xy.utils.enums.DictSonEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
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-01-11
*/
@Service
@AllArgsConstructor(onConstructor_ = @Lazy)
@Api(tags = "设备统计数据")
public class DeviceDataServiceImpl extends ServiceImpl implements DeviceDataService {
private final DeviceInfoServiceImpl deviceInfoService;
@PostMapping("sumPage")
@ApiOperation("设备销售统计")
public R> sumPage(@RequestBody @Valid DeviceDataDto.SumPageDto dto) {
PageBean pageBean = dto.getPage();
String salesCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getSalesCount));
String salesMoney = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getSalesMoney));
String goodsCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getGoodsCount));
String refundMoney = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getRefundMoney));
String refundCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getRefundCount));
String riskCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getRiskCount));
String zeroCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getZeroCount));
String deviceId = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getDeviceId));
LambdaQueryWrapper lqw = new QueryWrapper()
.select(String.format("%s,sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s"
, deviceId, salesCount, salesCount, salesMoney, salesMoney, goodsCount, goodsCount
, refundMoney, refundMoney, refundCount, refundCount, riskCount, riskCount, zeroCount, zeroCount
))
.orderByAsc("asc".equals(dto.getOrderBy()), dto.getOrderByKey())
.orderByDesc("desc".equals(dto.getOrderBy()), dto.getOrderByKey())
.lambda()
.eq(Emptys.check(dto.getMercId()), DeviceData::getMercId, dto.getMercId())
.eq(DeviceData::getType, dto.getType())
.ge(Emptys.check(dto.getBeginDate()), DeviceData::getDateValue, dto.getBeginDate())
.le(Emptys.check(dto.getEndDate()), DeviceData::getDateValue, dto.getEndDate())
.groupBy(DeviceData::getDeviceId);
IPage ipage = page(toIPage(pageBean), lqw);
if (Emptys.check(ipage.getRecords())) {
List deviceIdList = ipage.getRecords().stream().map(DeviceData::getDeviceId).collect(Collectors.toList());
Map deviceMap = deviceInfoService.getDeviceNameList(new DeviceInfoDto.DeviceIdDto().setDeviceId(deviceIdList)).getData();
PageBean sumPageVoPageBean = toPageBean(DeviceDataDto.SumPageVo.class, ipage);
sumPageVoPageBean.getRecords().forEach(i -> {
i.setDeviceName(deviceMap.get(i.getDeviceId()));
});
return R.ok(sumPageVoPageBean);
}
return R.ok();
}
@PostMapping("sumCount")
@ApiOperation("设备销售统计总计")
public R sumCount(@RequestBody @Valid DeviceDataDto.SumCountDto dto) {
String salesCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getSalesCount));
String salesMoney = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getSalesMoney));
String goodsCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getGoodsCount));
String refundMoney = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getRefundMoney));
String refundCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getRefundCount));
String riskCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getRiskCount));
String zeroCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getZeroCount));
//查询总数
LambdaQueryWrapper lqw = new QueryWrapper()
.select(String.format("sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s"
, salesCount, salesCount, salesMoney, salesMoney, goodsCount, goodsCount
, refundMoney, refundMoney, refundCount, refundCount, riskCount, riskCount, zeroCount, zeroCount
))
.lambda()
.eq(Emptys.check(dto.getMercId()), DeviceData::getMercId, dto.getMercId())
.eq(DeviceData::getType, dto.getType())
.ge(Emptys.check(dto.getBeginDate()), DeviceData::getDateValue, dto.getBeginDate())
.le(Emptys.check(dto.getEndDate()), DeviceData::getDateValue, dto.getEndDate());
return R.ok(copy(DeviceDataDto.SumCountVo.class, getOne(lqw)));
}
@PostMapping("obj")
@ApiOperation("对象查询")
public R obj(@RequestBody DeviceDataDto.Vo vo) {
LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(vo, DeviceData.class).build();
List list = list(lambdaQueryWrapper);
if (Emptys.check(list)) {
return R.ok(copy(DeviceDataDto.Vo.class, list).get(0));
}
return R.ok();
}
@PostMapping("page")
@ApiOperation("分页查询")
public R> page(@RequestBody DeviceDataDto.Page page) {
PageBean pageBean = page.getPage();
LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(page, DeviceData.class)
.ge(DeviceData::getCreateTime, page.getBeginCreateTime())
.le(DeviceData::getCreateTime, page.getEndCreateTime())
.build()
.orderByDesc(!Emptys.check(pageBean.getOrders()), DeviceData::getCreateTime);
IPage iPage = page(toIPage(pageBean), lambdaQueryWrapper);
return R.ok(toPageBean(DeviceDataDto.Vo.class, iPage));
}
@ApiOperation("添加/累加")
@PostMapping("saveOrAccum")
public R saveOrAccum(@RequestBody DeviceDataDto.SaveOrAccum saveOrAccum) {
return new SaveOrAccum().saveOrAccum(this, saveOrAccum);
}
/**
* 集合查询
*
* @param dto
* @return
*/
public List list(DeviceDataDto.ListDTO dto) {
LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(dto, DeviceData.class).build();
List list = list(lambdaQueryWrapper);
return copy(DeviceDataDto.Vo.class, list);
}
/**
* 指定查询商户某设备某天数据
*
* @param deviceId
* @param mercId
* @param dateValue
* @return
*/
public DeviceDataDto.Vo getByDay(Long deviceId, Long mercId, String dateValue) {
return getOneData(DictSonEnum.DEVICE_DATA_TYPE_DAY.getKey(), deviceId, mercId, dateValue);
}
/**
* 指定查询商户所有设备某天数据
*
* @param mercId
* @param dateValue
* @return
*/
public List getMercDataOneDay(Long mercId, String dateValue) {
return getMercListData(DictSonEnum.DEVICE_DATA_TYPE_DAY.getKey(), mercId, dateValue);
}
/**
* 指定查询商户所有设备某月数据
*
* @param mercId
* @param dateValue
* @return
*/
public List getMercDataOneMonth(Long mercId, String dateValue) {
return getMercListData(DictSonEnum.DEVICE_DATA_TYPE_MONTH.getKey(), mercId, dateValue);
}
/**
* 指定查询商户某设备某月数据
*
* @param deviceId
* @param mercId
* @param dateValue
* @return
*/
public DeviceDataDto.Vo getByMonth(Long deviceId, Long mercId, String dateValue) {
return getOneData(DictSonEnum.DEVICE_DATA_TYPE_MONTH.getKey(), deviceId, mercId, dateValue);
}
/**
* 指定查询商户某设备某年数据
*
* @param deviceId
* @param mercId
* @param dateValue
* @return
*/
public DeviceDataDto.Vo getByYear(Long deviceId, Long mercId, String dateValue) {
return getOneData(DictSonEnum.DEVICE_DATA_TYPE_YEAR.getKey(), deviceId, mercId, dateValue);
}
/**
* 指定查询商户某设备某年、月、日数据
*
* @param type
* @param deviceId
* @param mercId
* @param dateValue
* @return
*/
public DeviceDataDto.Vo getOneData(String type, Long deviceId, Long mercId, String dateValue) {
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(DeviceData::getType, type);
lambdaQueryWrapper.eq(DeviceData::getDeviceId, deviceId);
lambdaQueryWrapper.eq(DeviceData::getMercId, mercId);
lambdaQueryWrapper.eq(DeviceData::getDateValue, Integer.valueOf(dateValue));
DeviceData data = getOne(lambdaQueryWrapper);
return copy(DeviceDataDto.Vo.class, data);
}
/**
* 指定查询商户所有设备某年、月、日数据
*
* @param type
* @param mercId
* @param dateValue
* @return
*/
public List getMercListData(String type, Long mercId, String dateValue) {
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(DeviceData::getType, type);
lambdaQueryWrapper.eq(DeviceData::getMercId, mercId);
lambdaQueryWrapper.eq(DeviceData::getDateValue, Integer.valueOf(dateValue));
List list = list(lambdaQueryWrapper);
return BeanUtil.copyToList(list, DeviceDataDto.Vo.class);
}
/**
* 日范围内每天数据
*
* @param deviceId
* @param startDateValue
* @param endDateValue
* @return
*/
public List getListByDay(Long deviceId, Integer startDateValue, Integer endDateValue) {
return getListData(DictSonEnum.DEVICE_DATA_TYPE_DAY.getKey(), deviceId, startDateValue, endDateValue);
}
/**
* 日期范围查询
*
* @param type
* @param deviceId
* @param startDateValue
* @param endDateValue
* @return
*/
public List getListData(String type, Long deviceId, Integer startDateValue, Integer endDateValue) {
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(DeviceData::getType, type);
lambdaQueryWrapper.eq(DeviceData::getDeviceId, deviceId);
lambdaQueryWrapper.between(DeviceData::getDateValue, startDateValue, endDateValue);
lambdaQueryWrapper.orderBy(true, true, DeviceData::getDateValue);
List list = list(lambdaQueryWrapper);
return copy(DeviceDataDto.Vo.class, list);
}
public static class SaveOrAccum {
public R saveOrAccum(DeviceDataServiceImpl deviceDataService, DeviceDataDto.SaveOrAccum saveOrAccum) {
return new LockUtils()
.name("saveOrAccum.deviceId")
.prefix("data_save_accum_")
.build(SaveOrAccum.class)
.exec(deviceDataService, saveOrAccum);
}
@SneakyThrows
public R exec(DeviceDataServiceImpl deviceDataService, DeviceDataDto.SaveOrAccum saveOrAccum) {
LocalDateTime now = LocalDateTime.now();
String yyyyMMdd = DataTime.toString(now, "yyyyMMdd");
//获取字典
Map map = SysDictUtils.get(DictEnum.DEVICE_DATA_TYPE.getKey());
JMap jMap = new JHashMap<>(map.size());
map.forEach((type, sysDictRedis) -> {
Integer dateValue = Integer.valueOf(yyyyMMdd.substring(0, Integer.valueOf(sysDictRedis.getValue())));
jMap.put(type, dateValue);
});
//查询已存在数据
List list = deviceDataService.list(new LambdaQueryWrapper()
.eq(DeviceData::getDeviceId, saveOrAccum.getDeviceId())
.in(DeviceData::getDateValue, jMap.toList().value())
);
JMap typeMaps = new JArrayList<>(list).toMap(DeviceData::getType).cover();
//新增或修改的多线程桶map集合
JMap dbMaps = new JConcurrentHashMap<>(map.size());
//封装新增或修改对象
jMap.forEach((type, dateValue) -> {
DeviceData deviceData = typeMaps.get(type);
//添加
if (deviceData == null) {
DeviceData saveOrUpdateInfo = copy(DeviceData.class, saveOrAccum)
.setCreateTime(now)
.setUpdateTime(now)
.setType(type)
.setDateValue(dateValue);
dbMaps.put(type, saveOrUpdateInfo);
return;
}
//累加
DeviceData updateDeviceData = new DeviceData().setId(deviceData.getId()).setUpdateTime(now)
.setSalesMoney(saveOrAccum.getSalesMoney() != null ? saveOrAccum.getSalesMoney() + deviceData.getSalesMoney() : null)
.setSalesCount(saveOrAccum.getSalesCount() != null ? saveOrAccum.getSalesCount() + deviceData.getSalesCount() : null)
.setGoodsCount(saveOrAccum.getGoodsCount() != null ? saveOrAccum.getGoodsCount() + deviceData.getGoodsCount() : null)
.setRefundMoney(saveOrAccum.getRefundMoney() != null ? saveOrAccum.getRefundMoney() + deviceData.getRefundMoney() : null)
.setRefundCount(saveOrAccum.getRefundCount() != null ? saveOrAccum.getRefundCount() + deviceData.getRefundCount() : null)
.setZeroCount(saveOrAccum.getZeroCount() != null ? saveOrAccum.getZeroCount() + deviceData.getZeroCount() : null)
.setDeviceFaultCount(saveOrAccum.getDeviceFaultCount() != null ? saveOrAccum.getDeviceFaultCount() + deviceData.getDeviceFaultCount() : null);
dbMaps.put(type, updateDeviceData);
});
deviceDataService.saveOrUpdateBatch(dbMaps.toList().value());
return R.ok();
}
}
}