master:档口销售概览调整;

pull/1121/head
liujiang 2025-07-12 14:23:48 +08:00
parent ea52270f97
commit 4ee6f2b0af
11 changed files with 280 additions and 46 deletions

View File

@ -131,17 +131,31 @@ public class StoreController extends XktBaseController {
} }
@PreAuthorize("@ss.hasAnyRoles('admin,general_admin,store')") @PreAuthorize("@ss.hasAnyRoles('admin,general_admin,store')")
@ApiOperation(value = "获取档口首页 销售额 ", httpMethod = "POST", response = R.class) @ApiOperation(value = "获取档口首页 按月销售额 ", httpMethod = "POST", response = R.class)
@PostMapping(value = "/index/sale-revenue") @PostMapping(value = "/index/month/sale")
public R<List<StoreIndexSaleRevenueResVO>> indexSaleRevenue(@Validated @RequestBody StoreSaleRevenueVO revenueVO) { public R<List<StoreIndexSaleRevenueResVO>> indexSaleRevenue(@Validated @RequestBody StoreSaleRevenueVO revenueVO) {
return R.ok(BeanUtil.copyToList(storeService.indexSaleRevenue(BeanUtil.toBean(revenueVO, StoreSaleRevenueDTO.class)), StoreIndexSaleRevenueResVO.class)); return R.ok(BeanUtil.copyToList(storeService.indexSaleRevenue(BeanUtil.toBean(revenueVO, StoreSaleRevenueDTO.class)), StoreIndexSaleRevenueResVO.class));
} }
@PreAuthorize("@ss.hasAnyRoles('admin,general_admin,store')") @PreAuthorize("@ss.hasAnyRoles('admin,general_admin,store')")
@ApiOperation(value = "获取档口首页 今日销售额 ", httpMethod = "GET", response = R.class) @ApiOperation(value = "获取档口首页 今日商品销售额前5 ", httpMethod = "GET", response = R.class)
@GetMapping(value = "/index/today/sale-revenue/{storeId}") @GetMapping(value = "/index/today/prod/sale/top5/{storeId}")
public R<StoreIndexTodaySaleResVO> indexTodaySaleRevenue(@PathVariable Long storeId) { public R<StoreIndexTodaySaleTop5ResVO> indexTodayProdSaleRevenueTop5(@PathVariable Long storeId) {
return R.ok(BeanUtil.toBean(storeService.indexTodaySaleRevenue(storeId), StoreIndexTodaySaleResVO.class)); return R.ok(BeanUtil.toBean(storeService.indexTodayProdSaleRevenueTop5(storeId), StoreIndexTodaySaleTop5ResVO.class));
}
@PreAuthorize("@ss.hasAnyRoles('admin,general_admin,store')")
@ApiOperation(value = "获取档口首页 今日商品销售额 ", httpMethod = "GET", response = R.class)
@GetMapping(value = "/index/today/prod/sale/{storeId}")
public R<List<StoreIndexTodaySaleResVO>> indexTodayProdSaleRevenue(@PathVariable Long storeId) {
return R.ok(BeanUtil.copyToList(storeService.indexTodayProdSaleRevenue(storeId), StoreIndexTodaySaleResVO.class));
}
@PreAuthorize("@ss.hasAnyRoles('admin,general_admin,store')")
@ApiOperation(value = "获取档口首页 今日客户销售额 ", httpMethod = "GET", response = R.class)
@GetMapping(value = "/index/today/cus/sale/{storeId}")
public R<List<StoreIndexTodayCusSaleResVO>> indexTodayCusSaleRevenue(@PathVariable Long storeId) {
return R.ok(BeanUtil.copyToList(storeService.indexTodayCusSaleRevenue(storeId), StoreIndexTodayCusSaleResVO.class));
} }
@PreAuthorize("@ss.hasAnyRoles('admin,general_admin,store')") @PreAuthorize("@ss.hasAnyRoles('admin,general_admin,store')")

View File

@ -0,0 +1,25 @@
package com.ruoyi.web.controller.xkt.vo.store;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author liujiang
* @version v1.0
* @date 2025/3/27 15:12
*/
@ApiModel("档口首页今日销售额")
@Data
public class StoreIndexTodayCusSaleResVO {
@ApiModelProperty(value = "档口客户ID")
private Long storeCusId;
@ApiModelProperty(value = "档口客户名称")
private String storeCusName;
@ApiModelProperty(value = "销售数量")
private Integer saleNum;
@ApiModelProperty(value = "销售额")
private Long saleAmount;
}

View File

@ -5,7 +5,6 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List;
/** /**
* @author liujiang * @author liujiang
@ -16,19 +15,11 @@ import java.util.List;
@Data @Data
public class StoreIndexTodaySaleResVO { public class StoreIndexTodaySaleResVO {
@ApiModelProperty(value = "档口ID") @ApiModelProperty(value = "货号")
private Long storeId; private String prodArtNum;
@ApiModelProperty(value = "其它销售额") @ApiModelProperty(value = "销售数量")
private BigDecimal otherAmount; private Integer saleNum;
@ApiModelProperty(value = "档口商品销售额列表") @ApiModelProperty(value = "销售金额")
List<SITSProdSaleVO> saleList; private BigDecimal saleAmount;
@Data
public static class SITSProdSaleVO {
@ApiModelProperty(value = "货号")
private String prodArtNum;
@ApiModelProperty(value = "销售额")
private Long saleAmount;
}
} }

View File

@ -0,0 +1,34 @@
package com.ruoyi.web.controller.xkt.vo.store;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
* @author liujiang
* @version v1.0
* @date 2025/3/27 15:12
*/
@ApiModel("档口首页今日销售额")
@Data
public class StoreIndexTodaySaleTop5ResVO {
@ApiModelProperty(value = "档口ID")
private Long storeId;
@ApiModelProperty(value = "其它销售额")
private BigDecimal otherAmount;
@ApiModelProperty(value = "档口商品销售额列表")
List<SITSProdSaleVO> saleList;
@Data
public static class SITSProdSaleVO {
@ApiModelProperty(value = "货号")
private String prodArtNum;
@ApiModelProperty(value = "销售额")
private Long saleAmount;
}
}

View File

@ -0,0 +1,24 @@
package com.ruoyi.web.controller.xkt.vo.store;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* @author liujiang
* @version v1.0
* @date 2025/3/27 15:12
*/
@ApiModel("档口首页今日销售额入参model")
@Data
public class StoreIndexTodaySaleVO {
@NotNull(message = "档口ID不能为空!")
@ApiModelProperty(value = "档口ID", required = true)
private Long storeId;
@ApiModelProperty(value = "查询数量")
private Integer limit;
}

View File

@ -0,0 +1,27 @@
package com.ruoyi.xkt.dto.store;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author liujiang
* @version v1.0
* @date 2025/3/27 15:12
*/
@ApiModel("档口首页今日销售额")
@Data
@Accessors(chain = true)
public class StoreIndexTodayCusSaleResDTO {
@ApiModelProperty(value = "档口客户ID")
private Long storeCusId;
@ApiModelProperty(value = "档口客户名称")
private String storeCusName;
@ApiModelProperty(value = "销售数量")
private Integer saleNum;
@ApiModelProperty(value = "销售额")
private Long saleAmount;
}

View File

@ -0,0 +1,21 @@
package com.ruoyi.xkt.dto.store;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author liujiang
* @version v1.0
* @date 2025/3/27 15:12
*/
@ApiModel("档口首页今日销售额入参model")
@Data
public class StoreIndexTodaySaleDTO {
@ApiModelProperty(value = "档口ID")
private Long storeId;
@ApiModelProperty(value = "查询数量")
private Integer limit;
}

View File

@ -6,7 +6,6 @@ import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List;
/** /**
* @author liujiang * @author liujiang
@ -18,20 +17,11 @@ import java.util.List;
@Accessors(chain = true) @Accessors(chain = true)
public class StoreIndexTodaySaleResDTO { public class StoreIndexTodaySaleResDTO {
@ApiModelProperty(value = "档口ID") @ApiModelProperty(value = "货号")
private Long storeId; private String prodArtNum;
@ApiModelProperty(value = "其它销售额") @ApiModelProperty(value = "销售数量")
private BigDecimal otherAmount; private Integer saleNum;
@ApiModelProperty(value = "档口商品销售额列表") @ApiModelProperty(value = "销售金额")
List<SITSProdSaleDTO> saleList; private BigDecimal saleAmount;
@Data
@Accessors(chain = true)
public static class SITSProdSaleDTO {
@ApiModelProperty(value = "货号")
private String prodArtNum;
@ApiModelProperty(value = "销售额")
private BigDecimal saleAmount;
}
} }

View File

@ -0,0 +1,37 @@
package com.ruoyi.xkt.dto.store;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.util.List;
/**
* @author liujiang
* @version v1.0
* @date 2025/3/27 15:12
*/
@ApiModel("档口首页今日销售额")
@Data
@Accessors(chain = true)
public class StoreIndexTodaySaleTop5ResDTO {
@ApiModelProperty(value = "档口ID")
private Long storeId;
@ApiModelProperty(value = "其它销售额")
private BigDecimal otherAmount;
@ApiModelProperty(value = "档口商品销售额列表")
List<SITSProdSaleDTO> saleList;
@Data
@Accessors(chain = true)
public static class SITSProdSaleDTO {
@ApiModelProperty(value = "货号")
private String prodArtNum;
@ApiModelProperty(value = "销售额")
private BigDecimal saleAmount;
}
}

View File

@ -108,7 +108,7 @@ public interface IStoreService {
* @param storeId ID * @param storeId ID
* @return StoreIndexTodaySaleResDTO * @return StoreIndexTodaySaleResDTO
*/ */
StoreIndexTodaySaleResDTO indexTodaySaleRevenue(Long storeId); List<StoreIndexTodaySaleResDTO> indexTodayProdSaleRevenue(Long storeId);
/** /**
* 10 * 10
@ -157,4 +157,19 @@ public interface IStoreService {
* @return Integer * @return Integer
*/ */
Integer updateStoreWeight(StoreWeightUpdateDTO storeWeightUpdateDTO); Integer updateStoreWeight(StoreWeightUpdateDTO storeWeightUpdateDTO);
/**
*
*
* @param storeId ID
* @return StoreIndexTodayCusSaleResDTO
*/
List<StoreIndexTodayCusSaleResDTO> indexTodayCusSaleRevenue(Long storeId);
/**
* 5
* @param storeId ID
* @return StoreIndexTodaySaleResDTO
*/
StoreIndexTodaySaleTop5ResDTO indexTodayProdSaleRevenueTop5(Long storeId);
} }

View File

@ -301,19 +301,19 @@ public class StoreServiceImpl implements IStoreService {
} }
/** /**
* * 5
* *
* @param storeId ID * @param storeId ID
* @return StoreIndexTodaySaleResDTO * @return StoreIndexTodaySaleResDTO
*/ */
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public StoreIndexTodaySaleResDTO indexTodaySaleRevenue(Long storeId) { public StoreIndexTodaySaleTop5ResDTO indexTodayProdSaleRevenueTop5(Long storeId) {
List<StoreSaleDetail> detailList = this.saleDetailMapper.selectList(new LambdaQueryWrapper<StoreSaleDetail>() List<StoreSaleDetail> detailList = this.saleDetailMapper.selectList(new LambdaQueryWrapper<StoreSaleDetail>()
.eq(StoreSaleDetail::getStoreId, storeId).eq(StoreSaleDetail::getDelFlag, Constants.UNDELETED) .eq(StoreSaleDetail::getStoreId, storeId).eq(StoreSaleDetail::getDelFlag, Constants.UNDELETED)
.eq(StoreSaleDetail::getVoucherDate, java.sql.Date.valueOf(LocalDate.now()))); .eq(StoreSaleDetail::getVoucherDate, java.sql.Date.valueOf(LocalDate.now())));
if (CollectionUtils.isEmpty(detailList)) { if (CollectionUtils.isEmpty(detailList)) {
return new StoreIndexTodaySaleResDTO(); return new StoreIndexTodaySaleTop5ResDTO();
} }
List<StoreProduct> storeProdList = storeProdMapper.selectList(new LambdaQueryWrapper<StoreProduct>() List<StoreProduct> storeProdList = storeProdMapper.selectList(new LambdaQueryWrapper<StoreProduct>()
.in(StoreProduct::getId, detailList.stream().map(StoreSaleDetail::getStoreProdId).collect(Collectors.toList())) .in(StoreProduct::getId, detailList.stream().map(StoreSaleDetail::getStoreProdId).collect(Collectors.toList()))
@ -321,9 +321,9 @@ public class StoreServiceImpl implements IStoreService {
Map<Long, StoreProduct> storeProdMap = storeProdList.stream().collect(Collectors.toMap(StoreProduct::getId, x -> x)); Map<Long, StoreProduct> storeProdMap = storeProdList.stream().collect(Collectors.toMap(StoreProduct::getId, x -> x));
Map<Long, BigDecimal> saleMap = detailList.stream().collect(Collectors Map<Long, BigDecimal> saleMap = detailList.stream().collect(Collectors
.groupingBy(StoreSaleDetail::getStoreProdId, CollectorsUtil.summingBigDecimal(StoreSaleDetail::getAmount))); .groupingBy(StoreSaleDetail::getStoreProdId, CollectorsUtil.summingBigDecimal(StoreSaleDetail::getAmount)));
List<StoreIndexTodaySaleResDTO.SITSProdSaleDTO> saleList = new ArrayList<>(); List<StoreIndexTodaySaleTop5ResDTO.SITSProdSaleDTO> saleList = new ArrayList<>();
saleMap.forEach((storeProdId, amount) -> { saleMap.forEach((storeProdId, amount) -> {
StoreIndexTodaySaleResDTO.SITSProdSaleDTO saleDTO = new StoreIndexTodaySaleResDTO.SITSProdSaleDTO(); StoreIndexTodaySaleTop5ResDTO.SITSProdSaleDTO saleDTO = new StoreIndexTodaySaleTop5ResDTO.SITSProdSaleDTO();
saleDTO.setProdArtNum(ObjectUtils.isNotEmpty(storeProdMap.get(storeProdId)) ? storeProdMap.get(storeProdId).getProdArtNum() : "") saleDTO.setProdArtNum(ObjectUtils.isNotEmpty(storeProdMap.get(storeProdId)) ? storeProdMap.get(storeProdId).getProdArtNum() : "")
.setSaleAmount(amount); .setSaleAmount(amount);
saleList.add(saleDTO); saleList.add(saleDTO);
@ -331,12 +331,67 @@ public class StoreServiceImpl implements IStoreService {
// 总的金额 // 总的金额
final BigDecimal totalAmount = detailList.stream().map(StoreSaleDetail::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add); final BigDecimal totalAmount = detailList.stream().map(StoreSaleDetail::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
// 销售额排名前5的列表 // 销售额排名前5的列表
List<StoreIndexTodaySaleResDTO.SITSProdSaleDTO> top5List = saleList.stream().sorted(Comparator.comparing(StoreIndexTodaySaleResDTO.SITSProdSaleDTO::getSaleAmount).reversed()).limit(5).collect(Collectors.toList()); List<StoreIndexTodaySaleTop5ResDTO.SITSProdSaleDTO> top5List = saleList.stream().sorted(Comparator.comparing(StoreIndexTodaySaleTop5ResDTO.SITSProdSaleDTO::getSaleAmount).reversed()).limit(5).collect(Collectors.toList());
// 其它款式的销售额 // 其它款式的销售额
final BigDecimal otherAmount = totalAmount.subtract(top5List.stream().map(StoreIndexTodaySaleResDTO.SITSProdSaleDTO::getSaleAmount).reduce(BigDecimal.ZERO, BigDecimal::add)); final BigDecimal otherAmount = totalAmount.subtract(top5List.stream().map(StoreIndexTodaySaleTop5ResDTO.SITSProdSaleDTO::getSaleAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
return new StoreIndexTodaySaleResDTO().setStoreId(storeId).setOtherAmount(otherAmount).setSaleList(top5List); return new StoreIndexTodaySaleTop5ResDTO().setStoreId(storeId).setOtherAmount(otherAmount).setSaleList(top5List);
} }
/**
*
*
* @param storeId ID
* @return StoreIndexTodaySaleResDTO
*/
@Override
@Transactional(readOnly = true)
public List<StoreIndexTodaySaleResDTO> indexTodayProdSaleRevenue(Long storeId) {
List<StoreSaleDetail> detailList = this.saleDetailMapper.selectList(new LambdaQueryWrapper<StoreSaleDetail>()
.eq(StoreSaleDetail::getStoreId, storeId).eq(StoreSaleDetail::getDelFlag, Constants.UNDELETED)
.eq(StoreSaleDetail::getVoucherDate, java.sql.Date.valueOf(LocalDate.now())));
if (CollectionUtils.isEmpty(detailList)) {
return new ArrayList<>();
}
Map<String, List<StoreSaleDetail>> todaySaleMap = detailList.stream().collect(Collectors.groupingBy(StoreSaleDetail::getProdArtNum));
List<StoreIndexTodaySaleResDTO> saleList = new ArrayList<>();
todaySaleMap.forEach((prodArtNum, list) -> {
final Integer saleNum = list.stream().map(x -> ObjectUtils.defaultIfNull(x.getQuantity(), 0)).reduce(0, Integer::sum);
final BigDecimal saleAmount = list.stream().map(x -> ObjectUtils.defaultIfNull(x.getAmount(), BigDecimal.ZERO)).reduce(BigDecimal.ZERO, BigDecimal::add);
saleList.add(new StoreIndexTodaySaleResDTO().setProdArtNum(prodArtNum).setSaleNum(saleNum).setSaleAmount(saleAmount));
});
// 按照销售金额倒序排
saleList.sort(Comparator.comparing(StoreIndexTodaySaleResDTO::getSaleAmount).reversed());
return saleList;
}
/**
*
*
* @param storeId ID
* @return StoreIndexTodayCusSaleResDTO
*/
@Override
@Transactional(readOnly = true)
public List<StoreIndexTodayCusSaleResDTO> indexTodayCusSaleRevenue(Long storeId) {
List<StoreSaleDetail> detailList = this.saleDetailMapper.selectList(new LambdaQueryWrapper<StoreSaleDetail>()
.eq(StoreSaleDetail::getStoreId, storeId).eq(StoreSaleDetail::getDelFlag, Constants.UNDELETED)
.eq(StoreSaleDetail::getVoucherDate, java.sql.Date.valueOf(LocalDate.now())));
if (CollectionUtils.isEmpty(detailList)) {
return new ArrayList<>();
}
Map<Long, String> storeCusMap = detailList.stream().collect(Collectors.toMap(StoreSaleDetail::getStoreCusId, StoreSaleDetail::getStoreCusName, (s1, s2) -> s2));
Map<Long, List<StoreSaleDetail>> cusSaleMap = detailList.stream().collect(Collectors.groupingBy(StoreSaleDetail::getStoreCusId));
List<StoreIndexTodayCusSaleResDTO> saleList = new ArrayList<>();
cusSaleMap.forEach((storeCusId, list) -> {
final Integer saleNum = list.stream().map(x -> ObjectUtils.defaultIfNull(x.getQuantity(), 0)).reduce(0, Integer::sum);
final Long saleAmount = list.stream().map(x -> ObjectUtils.defaultIfNull(x.getAmount(), BigDecimal.ZERO)).reduce(BigDecimal.ZERO, BigDecimal::add).longValue();
saleList.add(new StoreIndexTodayCusSaleResDTO().setStoreCusId(storeCusId).setSaleNum(saleNum).setSaleAmount(saleAmount)
.setStoreCusName(ObjectUtils.defaultIfNull(storeCusMap.get(storeCusId), "")));
});
return saleList;
}
/** /**
* 10 * 10
* *
@ -423,4 +478,5 @@ public class StoreServiceImpl implements IStoreService {
return this.storeMapper.updateById(store); return this.storeMapper.updateById(store);
} }
} }