Merge #111 into master from cc_20260417_bonus
fix:工资奖金 * cc_20260417_bonus: (28 commits squashed) - feat:工资奖金发放 - fix:工资奖金发放 - fix:工资奖金发放 - fix:工资奖金发放 - fix:工资奖金发放 - fix:门店实收相关接口 - fix:新品销售门店级接口 - fix:新品销售菜品列表接口;规则新增返回id - fix:新品销售菜品详情接口 - fix:新品销售菜品接口补充 - fix:小程序接口补充 - fix - fix:新增实收、新品销售测试接口 - fix:新增实收、新品销售测试接口 - fix - fix:新增门店菜品列表接口 - fix:同规则下无法新增相同菜品规则;新增小程序门店列表接口 - fix - fix:小程序用户获取来源修改 - fix:实收规则新增上月日均实收字段 - fix:规则限制 - fix:小程序上月日均实收 - fix:查询异常 - fix:查询异常 - fix:菜品员工明细字段赋值异常 - fix:排序 - fix:排序 - fix:员工实收列表新增门店筛选条件 Signed-off-by: 王非凡 <accounts_67eba0c5fee9c49c80c8e2b4@mail.teambition.com> Merged-by: 正新 <accounts_6964c7bcd2a2c377c5bbd01b@mail.teambition.com> CR-link: https://codeup.aliyun.com/692ea314dec569489f6f167c/hangzhou/java/custom_zxjp/change/111
This commit is contained in:
@@ -3,6 +3,7 @@ package com.cool.store.service;
|
||||
import com.cool.store.dto.StoreDTO;
|
||||
import com.cool.store.dto.StoreNameDTO;
|
||||
import com.cool.store.dto.store.AuthStoreUserDTO;
|
||||
import com.cool.store.dto.store.StoreUserDTO;
|
||||
import com.cool.store.dto.store.StoreUserPositionDTO;
|
||||
import com.cool.store.request.store.StoreListRequest;
|
||||
import com.cool.store.response.MiniShopsResponse;
|
||||
@@ -38,6 +39,11 @@ public interface StoreService {
|
||||
|
||||
List<AuthStoreUserDTO> authStoreUser(List<String> storeIdList, String positionType);
|
||||
|
||||
/**
|
||||
* 同标品方法一致;authStoreUser方法会查询出运营顾问等角色
|
||||
*/
|
||||
List<AuthStoreUserDTO> authStoreUserV2(List<String> storeIdList, String positionType);
|
||||
|
||||
List<AuthStoreUserDTO> getStorePositionUserList(List<String> storeIds,
|
||||
List<String> positionIds,
|
||||
List<String> nodePersonList,
|
||||
@@ -51,4 +57,9 @@ public interface StoreService {
|
||||
|
||||
Boolean handleStoreLogLai(Integer flag,String specialStoreCode);
|
||||
|
||||
/**
|
||||
* 获取门店人员的店内职位信息
|
||||
*/
|
||||
List<StoreUserDTO> getStoreUserPositionList(String storeId, String userName);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.cool.store.service;
|
||||
|
||||
import com.cool.store.request.storeopen.StoreMonthRevenueRequest;
|
||||
import com.cool.store.request.storeopen.StoreRecipeDailySalesRequest;
|
||||
import com.cool.store.request.storeopen.StoreRecipesRequest;
|
||||
import com.cool.store.response.storeopen.StoreMonthRevenueResponse;
|
||||
import com.cool.store.response.storeopen.StoreRecipeDailySalesResponse;
|
||||
import com.cool.store.response.storeopen.StoreRecipesResponse;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 第三方门店开放数据服务接口
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2026/4/20
|
||||
*/
|
||||
public interface ThirdStoreOpenDataService {
|
||||
|
||||
/**
|
||||
* 查询门店月营收数据
|
||||
*
|
||||
* @param request 请求参数
|
||||
* @return 月营收数据列表
|
||||
*/
|
||||
List<StoreMonthRevenueResponse> getMonthRevenue(StoreMonthRevenueRequest request);
|
||||
|
||||
/**
|
||||
* 查询门店菜品日销量数据
|
||||
*
|
||||
* @param request 请求参数
|
||||
* @return 菜品日销量数据列表
|
||||
*/
|
||||
List<StoreRecipeDailySalesResponse> getRecipeDailySales(StoreRecipeDailySalesRequest request);
|
||||
|
||||
/**
|
||||
* 查询门店菜品种类
|
||||
*
|
||||
* @param request 请求参数
|
||||
* @return 菜品种类列表
|
||||
*/
|
||||
List<StoreRecipesResponse> getRecipes(StoreRecipesRequest request);
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package com.cool.store.service.bonus;
|
||||
|
||||
import com.cool.store.entity.bonus.BonusDistributionRuleDO;
|
||||
import com.cool.store.request.bonus.*;
|
||||
import com.cool.store.response.storeopen.StoreRecipesResponse;
|
||||
import com.cool.store.vo.bonus.*;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 奖金发放规则服务类
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2026/4/20
|
||||
*/
|
||||
public interface BonusService {
|
||||
|
||||
/**
|
||||
* 新增规则
|
||||
*/
|
||||
String addRule(BonusRuleAddRequest request, String createUserId);
|
||||
|
||||
/**
|
||||
* 编辑规则
|
||||
*/
|
||||
Boolean updateRule(BonusRuleUpdateRequest request, String updateUserId);
|
||||
|
||||
/**
|
||||
* 启用规则
|
||||
*/
|
||||
Boolean enableRule(BonusRuleEnableRequest request);
|
||||
|
||||
/**
|
||||
* 规则详情
|
||||
*/
|
||||
BonusRuleVO getRuleDetail(Long ruleId);
|
||||
|
||||
/**
|
||||
* 规则列表查询
|
||||
*/
|
||||
PageInfo<BonusRuleListVO> getList(BonusRuleQueryRequest request);
|
||||
|
||||
/**
|
||||
* 实收实算
|
||||
*/
|
||||
BonusReceivedComputeVO receivedCompute(BonusReceivedComputeRequest request);
|
||||
|
||||
/**
|
||||
* 新品销售实算
|
||||
*/
|
||||
BonusProductComputeVO productCompute(BonusProductComputeRequest request);
|
||||
|
||||
/**
|
||||
* 处理单个实收规则
|
||||
*/
|
||||
void processReceivedRule(BonusDistributionRuleDO rule, String payMonth);
|
||||
|
||||
/**
|
||||
* 处理单个新品销售规则
|
||||
*/
|
||||
void processNewProductRule(BonusDistributionRuleDO rule, String payDate);
|
||||
|
||||
/**
|
||||
* 处理员工奖励明细
|
||||
*/
|
||||
void processEmployeeDetail(String payMonth);
|
||||
|
||||
/**
|
||||
* 门店实收奖金发放列表
|
||||
*/
|
||||
PageInfo<BonusReceivedStoreListVO> getReceivedStoreList(BonusReceivedStoreQueryRequest request);
|
||||
|
||||
/**
|
||||
* 门店实收奖金详情
|
||||
*/
|
||||
BonusReceivedStoreDetailVO getReceivedStoreDetail(Long id);
|
||||
|
||||
/**
|
||||
* 员工实收奖金发放列表
|
||||
*/
|
||||
PageInfo<BonusReceivedEmployeeListVO> getReceivedEmployeeList(BonusReceivedEmployeeQueryRequest request);
|
||||
|
||||
/**
|
||||
* 员工实收奖金详情
|
||||
*/
|
||||
BonusReceivedStoreDetailVO getReceivedEmployeeDetail(Long id);
|
||||
|
||||
/**
|
||||
* 门店新品销售奖金发放列表-门店
|
||||
*/
|
||||
PageInfo<BonusProductStoreListVO> getNewProductStoreList(BonusProductQueryRequest request);
|
||||
|
||||
/**
|
||||
* 门店新品销售奖金详情
|
||||
*/
|
||||
BonusProductStoreDetailVO getNewProductStoreDetail(BonusProductMonthlyQueryRequest request);
|
||||
|
||||
/**
|
||||
* 门店新品销售奖金发放列表-菜品
|
||||
*/
|
||||
PageInfo<BonusProductRecipeListVO> getNewProductRecipeList(BonusProductQueryRequest request);
|
||||
|
||||
/**
|
||||
* 门店新品销售奖金发放详情-菜品
|
||||
*/
|
||||
PageInfo<BonusProductRecipeDetailVO> getNewProductRecipeDetail(BonusProductRecipeQueryRequest request);
|
||||
|
||||
/**
|
||||
* 门店新品销售奖金发放列表-员工
|
||||
*/
|
||||
PageInfo<BonusProductEmployeeListVO> getNewProductEmployeeList(BonusProductEmployeeQueryRequest request);
|
||||
|
||||
/**
|
||||
* 门店新品销售奖金发放详情-员工
|
||||
*/
|
||||
BonusProductStoreDetailVO getNewProductEmployeeDetail(BonusProductMonthlyQueryRequest request);
|
||||
|
||||
/**
|
||||
* 门店新品销售奖金方法列表-菜品+员工
|
||||
*/
|
||||
PageInfo<BonusProductRecipeEmployeeListVO> getNewProductRecipeEmployeeList(BonusProductEmployeeQueryRequest request);
|
||||
|
||||
/**
|
||||
* 门店新品销售奖金发放详情-菜品+员工
|
||||
*/
|
||||
PageInfo<BonusProductRecipeEmployeeDetailVO> getNewProductRecipeEmployeeDetail(BonusProductRecipeEmployeeQueryRequest request);
|
||||
|
||||
/**
|
||||
* 员工奖金明细
|
||||
*/
|
||||
PageInfo<BonusEmployeeDetailVO> getEmployeeMonthlyDetail(BonusProductEmployeeQueryRequest request);
|
||||
|
||||
/**
|
||||
* 删除月度实收数据
|
||||
*/
|
||||
void deleteMonthlyReceived(BonusDistributionRuleDO ruleDO, String payMonth);
|
||||
|
||||
/**
|
||||
* 删除每日新品销售数据
|
||||
*/
|
||||
void deleteMonthlyNewProduct(BonusDistributionRuleDO ruleDO, String payDate);
|
||||
|
||||
/**
|
||||
* 查询门店菜品种类
|
||||
*/
|
||||
List<StoreRecipesResponse> getRecipes(String storeId);
|
||||
|
||||
/**
|
||||
* 查询上月日均实收
|
||||
*/
|
||||
BigDecimal receivedDailyLast(String storeId);
|
||||
}
|
||||
@@ -0,0 +1,898 @@
|
||||
package com.cool.store.service.bonus.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollStreamUtil;
|
||||
import cn.hutool.core.lang.Pair;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.aliyun.core.utils.StringUtils;
|
||||
import com.cool.store.dao.StoreDao;
|
||||
import com.cool.store.dao.bonus.*;
|
||||
import com.cool.store.entity.StoreDO;
|
||||
import com.cool.store.entity.bonus.*;
|
||||
import com.cool.store.enums.ErrorCodeEnum;
|
||||
import com.cool.store.exception.ServiceException;
|
||||
import com.cool.store.request.bonus.*;
|
||||
import com.cool.store.request.storeopen.StoreMonthRevenueRequest;
|
||||
import com.cool.store.request.storeopen.StoreRecipeDailySalesRequest;
|
||||
import com.cool.store.request.storeopen.StoreRecipesRequest;
|
||||
import com.cool.store.response.storeopen.StoreMonthRevenueResponse;
|
||||
import com.cool.store.response.storeopen.StoreRecipeDailySalesResponse;
|
||||
import com.cool.store.response.storeopen.StoreRecipesResponse;
|
||||
import com.cool.store.service.ThirdStoreOpenDataService;
|
||||
import com.cool.store.service.bonus.BonusService;
|
||||
import com.cool.store.utils.BeanUtil;
|
||||
import com.cool.store.utils.poi.DateUtils;
|
||||
import com.cool.store.vo.bonus.*;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 奖金发放规则服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2026/4/20
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class BonusServiceImpl implements BonusService {
|
||||
private final BonusDistributionRuleDAO ruleDAO;
|
||||
private final ThirdStoreOpenDataService storeOpenDataService;
|
||||
private final BonusReceivedStoreDAO receivedStoreDAO;
|
||||
private final StoreDao storeDao;
|
||||
private final BonusEmployeeRewardDetailDAO rewardDetailDAO;
|
||||
private final BonusReceivedEmployeeDAO receivedEmployeeDAO;
|
||||
private final BonusNewProductEmployeeDAO newProductEmployeeDAO;
|
||||
private final BonusNewProductStoreDAO newProductStoreDAO;
|
||||
private final BonusNewProductRecipeDAO newProductRecipeDAO;
|
||||
private final BonusNewProductRecipeEmployeeDAO newProductRecipeEmployeeDAO;
|
||||
|
||||
|
||||
@Override
|
||||
public String addRule(BonusRuleAddRequest request, String createUserId) {
|
||||
if (ruleDAO.existOverlap(request.getStoreId(), request.getType(), request.getStartDate(), request.getEndDate())) {
|
||||
throw new ServiceException(ErrorCodeEnum.BONUS_EXIST_OVERLAP_RULE);
|
||||
}
|
||||
BonusDistributionRuleDO ruleDO = BeanUtil.toBean(request, BonusDistributionRuleDO.class);
|
||||
ruleDO.setCreateUserId(createUserId);
|
||||
ruleDAO.addRule(ruleDO);
|
||||
return ruleDO.getId().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateRule(BonusRuleUpdateRequest request, String updateUserId) {
|
||||
BonusDistributionRuleDO ruleDO = ruleDAO.getById(request.getId());
|
||||
if (Objects.isNull(ruleDO)) {
|
||||
throw new ServiceException(ErrorCodeEnum.BONUS_RULE_NOT_EXIST);
|
||||
}
|
||||
if (ruleDAO.existOverlap(ruleDO.getStoreId(), ruleDO.getType(), request.getStartDate(), request.getEndDate())) {
|
||||
throw new ServiceException(ErrorCodeEnum.BONUS_EXIST_OVERLAP_RULE);
|
||||
}
|
||||
BigDecimal rewardRatio = request.getDistributeConfigs().stream()
|
||||
.map(BonusRuleDistributeConfig::getRewardRatio)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
if (rewardRatio.compareTo(BigDecimal.valueOf(100)) > 0) {
|
||||
throw new ServiceException(ErrorCodeEnum.BONUS_DISTRIBUTE_RATIO_OVER_100);
|
||||
}
|
||||
JSONObject config = new JSONObject();
|
||||
if (ruleDO.getType().equals(1)) {
|
||||
for (BonusRuleReceivedConfig receivedConfig : request.getReceivedConfigs()) {
|
||||
if (receivedConfig.getGt().compareTo(receivedConfig.getLe()) >= 0) {
|
||||
throw new ServiceException(ErrorCodeEnum.BONUS_RULE_CONFIG_ERROR);
|
||||
}
|
||||
}
|
||||
config.put("receivedStart", request.getReceivedStart());
|
||||
config.put("receivedConfigs", request.getReceivedConfigs());
|
||||
} else {
|
||||
// 校验是否有相同菜品
|
||||
Map<String, List<BonusRuleProductConfig>> group = CollStreamUtil.groupByKey(request.getProductConfigs(), BonusRuleProductConfig::getRecipeNo);
|
||||
for (List<BonusRuleProductConfig> value : group.values()) {
|
||||
if (value.size() > 1) {
|
||||
throw new ServiceException(ErrorCodeEnum.BONUS_PRODUCT_CONFIG_DUPLICATE);
|
||||
}
|
||||
}
|
||||
config.put("productConfigs", request.getProductConfigs());
|
||||
}
|
||||
BonusDistributionRuleDO updateRule = BonusDistributionRuleDO.builder()
|
||||
.id(request.getId())
|
||||
.startDate(request.getStartDate())
|
||||
.endDate(request.getEndDate())
|
||||
.bonusConfig(config.toJSONString())
|
||||
.distributeConfig(JSONObject.toJSONString(request.getDistributeConfigs()))
|
||||
.updateUserId(updateUserId)
|
||||
.build();
|
||||
return ruleDAO.updateByPrimaryKeySelective(updateRule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean enableRule(BonusRuleEnableRequest request) {
|
||||
BonusDistributionRuleDO ruleDO = ruleDAO.getById(request.getId());
|
||||
if (Objects.isNull(ruleDO)) {
|
||||
throw new ServiceException(ErrorCodeEnum.BONUS_RULE_NOT_EXIST);
|
||||
}
|
||||
if (request.getEnable().equals(1) && ruleDAO.existOverlap(ruleDO.getStoreId(), ruleDO.getType(), ruleDO.getStartDate(), ruleDO.getEndDate())) {
|
||||
throw new ServiceException(ErrorCodeEnum.BONUS_EXIST_OVERLAP_RULE);
|
||||
}
|
||||
// 校验两个规则是否配置
|
||||
if (StringUtils.isBlank(ruleDO.getBonusConfig()) || StringUtils.isBlank(ruleDO.getDistributeConfig())) {
|
||||
throw new ServiceException(ErrorCodeEnum.BONUS_RULE_NOT_CONFIG);
|
||||
}
|
||||
BonusDistributionRuleDO updateRule = new BonusDistributionRuleDO();
|
||||
updateRule.setId(request.getId());
|
||||
updateRule.setEnable(request.getEnable());
|
||||
return ruleDAO.updateByPrimaryKeySelective(updateRule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BonusRuleVO getRuleDetail(Long ruleId) {
|
||||
BonusDistributionRuleDO ruleDO = ruleDAO.getById(ruleId);
|
||||
BonusRuleVO vo = BeanUtil.toBean(ruleDO, BonusRuleVO.class);
|
||||
if (Objects.nonNull(vo)) {
|
||||
JSONObject bonusConfig = JSONObject.parseObject(ruleDO.getBonusConfig());
|
||||
BeanUtil.copyPropertiesIgnoreId(bonusConfig, vo);
|
||||
vo.setDistributeConfigs(JSONObject.parseArray(ruleDO.getDistributeConfig(), BonusRuleDistributeConfig.class));
|
||||
StoreDO storeDO = storeDao.getEffectiveByStoreId(vo.getStoreId());
|
||||
if (Objects.nonNull(storeDO)) {
|
||||
vo.setStoreNum(storeDO.getStoreNum());
|
||||
vo.setStoreName(storeDO.getStoreName());
|
||||
}
|
||||
|
||||
if (ruleDO.getType().equals(1)) {
|
||||
// 查询上月日均实收
|
||||
String lastMonth = LocalDate.now().minusMonths(1).format(DateTimeFormatter.ofPattern("yyyy-MM"));
|
||||
StoreMonthRevenueRequest request = new StoreMonthRevenueRequest();
|
||||
request.setStoreNum(storeDO.getStoreNum());
|
||||
request.setStartDate(lastMonth);
|
||||
request.setEndDate(lastMonth);
|
||||
List<StoreMonthRevenueResponse> monthRevenue = storeOpenDataService.getMonthRevenue(request);
|
||||
if (CollectionUtils.isNotEmpty(monthRevenue)) {
|
||||
StoreMonthRevenueResponse storeMonthRevenueResponse = monthRevenue.get(0);
|
||||
vo.setReceivedDailyLast(Objects.nonNull(storeMonthRevenueResponse.getReceivedAmountDaily()) ? storeMonthRevenueResponse.getReceivedAmountDaily() : BigDecimal.ZERO);
|
||||
}
|
||||
}
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<BonusRuleListVO> getList(BonusRuleQueryRequest request) {
|
||||
PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
||||
List<BonusDistributionRuleDO> list = ruleDAO.getList(request.getStoreNumOrName(), request.getType(), request.getEnable(), request.getStoreId());
|
||||
PageInfo<BonusRuleListVO> page = BeanUtil.toPage(new PageInfo<>(list), BonusRuleListVO.class);
|
||||
fillBasicField(page.getList());
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BonusReceivedComputeVO receivedCompute(BonusReceivedComputeRequest request) {
|
||||
if (Objects.isNull(request.getBusinessDays()) || request.getBusinessDays().equals(0)) {
|
||||
List<BonusComputeUserVO> detail = CollStreamUtil.toList(request.getDistributeConfigs(), v -> new BonusComputeUserVO(BigDecimal.ZERO, v.getRewardUserId(), v.getRewardUserName()));
|
||||
log.info("日营业天数为0");
|
||||
return new BonusReceivedComputeVO(BigDecimal.ZERO, BigDecimal.ZERO, detail);
|
||||
}
|
||||
BigDecimal businessDays = BigDecimal.valueOf(request.getBusinessDays());
|
||||
BigDecimal receivedDaily = request.getReceivedMonthly().divide(businessDays, 2, RoundingMode.HALF_UP);
|
||||
if (receivedDaily.compareTo(request.getReceivedStart()) <= 0) {
|
||||
List<BonusComputeUserVO> detail = CollStreamUtil.toList(request.getDistributeConfigs(), v -> new BonusComputeUserVO(BigDecimal.ZERO, v.getRewardUserId(), v.getRewardUserName()));
|
||||
log.info("日均实收小于等于该值起始值");
|
||||
return new BonusReceivedComputeVO(receivedDaily, BigDecimal.ZERO, detail);
|
||||
}
|
||||
|
||||
BigDecimal amountTotal = BigDecimal.ZERO;
|
||||
for (BonusRuleReceivedConfig config : request.getReceivedConfigs()) {
|
||||
BigDecimal lowerBound = config.getGt();
|
||||
BigDecimal upperBound = config.getLe();
|
||||
|
||||
if (lowerBound.compareTo(upperBound) >= 0) {
|
||||
throw new ServiceException(ErrorCodeEnum.BONUS_RULE_CONFIG_ERROR);
|
||||
}
|
||||
|
||||
if (receivedDaily.compareTo(lowerBound) > 0) {
|
||||
BigDecimal intervalAmount;
|
||||
if (upperBound == null || receivedDaily.compareTo(upperBound) <= 0) {
|
||||
intervalAmount = receivedDaily.subtract(lowerBound);
|
||||
} else {
|
||||
intervalAmount = upperBound.subtract(lowerBound);
|
||||
}
|
||||
// 计算该区间的奖金:区间金额 × 奖励比例% × 月度营业天数
|
||||
BigDecimal intervalBonus = intervalAmount.multiply(config.getRewardRatio())
|
||||
.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP)
|
||||
.multiply(businessDays);
|
||||
amountTotal = amountTotal.add(intervalBonus);
|
||||
}
|
||||
}
|
||||
|
||||
BigDecimal finalAmountTotal = amountTotal;
|
||||
List<BonusComputeUserVO> detail = CollStreamUtil.toList(request.getDistributeConfigs(), d -> {
|
||||
BigDecimal userAmount = finalAmountTotal.multiply(d.getRewardRatio())
|
||||
.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
||||
return new BonusComputeUserVO(userAmount, d.getRewardUserId(), d.getRewardUserName());
|
||||
});
|
||||
return new BonusReceivedComputeVO(receivedDaily, amountTotal, detail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BonusProductComputeVO productCompute(BonusProductComputeRequest request) {
|
||||
if (CollectionUtils.isEmpty(request.getRecipeSales())
|
||||
|| CollectionUtils.isEmpty(request.getProductConfigs())
|
||||
|| CollectionUtils.isEmpty(request.getDistributeConfigs())) {
|
||||
log.info("参数为空");
|
||||
return null;
|
||||
}
|
||||
Map<String, Integer> recipeSaleMap = CollStreamUtil.toMap(request.getRecipeSales(), BonusProductRecipeCompute::getRecipeNo, BonusProductRecipeCompute::getSalesVolume);
|
||||
Map<String, BigDecimal> employeeAmount = new HashMap<>();
|
||||
|
||||
List<BonusProductRecipeComputeVO> resultRecipes = new ArrayList<>();
|
||||
for (BonusRuleProductConfig productConfig : request.getProductConfigs()) {
|
||||
BonusProductRecipeComputeVO recipeVO = BeanUtil.toBean(productConfig, BonusProductRecipeComputeVO.class);
|
||||
Integer salesVolume = recipeSaleMap.getOrDefault(productConfig.getRecipeNo(), 0);
|
||||
recipeVO.setSalesVolume(salesVolume);
|
||||
BigDecimal salesVolumeBig = BigDecimal.valueOf(salesVolume).setScale(2, RoundingMode.HALF_UP);
|
||||
BigDecimal basicRewardAmount = salesVolume.compareTo(productConfig.getMinStandardNum()) < 0
|
||||
? BigDecimal.ZERO
|
||||
: salesVolumeBig.multiply(productConfig.getRewardAmount());
|
||||
BigDecimal excessRewardAmount = salesVolume.compareTo(productConfig.getExcessStandardNum()) < 0
|
||||
? BigDecimal.ZERO
|
||||
: salesVolumeBig.subtract(BigDecimal.valueOf(productConfig.getExcessStandardNum()))
|
||||
.multiply(productConfig.getExcessAmount());
|
||||
recipeVO.setBasicRewardAmount(basicRewardAmount);
|
||||
recipeVO.setExcessRewardAmount(excessRewardAmount);
|
||||
List<BonusComputeUserVO> detail = CollStreamUtil.toList(request.getDistributeConfigs(), d -> {
|
||||
BigDecimal basic = basicRewardAmount.multiply(d.getRewardRatio())
|
||||
.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
||||
BigDecimal excess = excessRewardAmount.multiply(d.getRewardRatio())
|
||||
.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
||||
BigDecimal rewardAmount = basic.add(excess);
|
||||
employeeAmount.compute(d.getRewardUserId(), (k, v) -> {
|
||||
if (v == null) {
|
||||
v = BigDecimal.ZERO;
|
||||
}
|
||||
return v.add(rewardAmount);
|
||||
});
|
||||
return new BonusComputeUserVO(rewardAmount, d.getRewardUserId(), d.getRewardUserName(), basic, excess, d.getRewardRatio());
|
||||
});
|
||||
recipeVO.setDetail(detail);
|
||||
resultRecipes.add(recipeVO);
|
||||
}
|
||||
Map<String, String> userMap = CollStreamUtil.toMap(request.getDistributeConfigs(), BonusRuleDistributeConfig::getRewardUserId, BonusRuleDistributeConfig::getRewardUserName);
|
||||
List<BonusComputeUserVO> detail = CollStreamUtil.toList(employeeAmount.entrySet(), v -> new BonusComputeUserVO(v.getValue(), v.getKey(), userMap.get(v.getKey())));
|
||||
return new BonusProductComputeVO(resultRecipes, detail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processReceivedRule(BonusDistributionRuleDO rule, String payMonth) {
|
||||
String storeId = rule.getStoreId();
|
||||
|
||||
// 检查是否已统计过
|
||||
if (receivedStoreDAO.existsByRuleIdAndPayDate(rule.getId(), payMonth)) {
|
||||
log.info("规则已统计过, ruleId: {}, payMonth: {}", rule.getId(), payMonth);
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取门店编号
|
||||
StoreDO store = storeDao.getEffectiveByStoreId(storeId);
|
||||
if (store == null) {
|
||||
log.warn("门店不存在, storeId: {}", storeId);
|
||||
return;
|
||||
}
|
||||
String storeNum = store.getStoreNum();
|
||||
|
||||
// 解析规则配置
|
||||
JSONObject bonusConfig = JSONObject.parseObject(rule.getBonusConfig());
|
||||
BigDecimal receivedStart = bonusConfig.getBigDecimal("receivedStart");
|
||||
List<BonusRuleReceivedConfig> receivedConfigs = bonusConfig.getJSONArray("receivedConfigs")
|
||||
.toJavaList(BonusRuleReceivedConfig.class);
|
||||
List<BonusRuleDistributeConfig> distributeConfigs = JSONObject.parseArray(rule.getDistributeConfig(), BonusRuleDistributeConfig.class);
|
||||
|
||||
// 调用API获取门店月营收数据
|
||||
StoreMonthRevenueRequest request = new StoreMonthRevenueRequest();
|
||||
request.setStoreNum(storeNum);
|
||||
request.setStartDate(payMonth);
|
||||
request.setEndDate(payMonth);
|
||||
|
||||
List<StoreMonthRevenueResponse> revenueList = storeOpenDataService.getMonthRevenue(request);
|
||||
if (org.apache.commons.collections4.CollectionUtils.isEmpty(revenueList)) {
|
||||
log.warn("门店月营收数据为空, storeNum: {}", storeNum);
|
||||
return;
|
||||
}
|
||||
|
||||
StoreMonthRevenueResponse revenue = revenueList.get(0);
|
||||
|
||||
// 计算奖金
|
||||
BonusReceivedComputeRequest computeRequest = new BonusReceivedComputeRequest();
|
||||
computeRequest.setReceivedMonthly(revenue.getReceivedAmount());
|
||||
computeRequest.setBusinessDays(revenue.getBusinessDays());
|
||||
computeRequest.setReceivedStart(receivedStart);
|
||||
computeRequest.setReceivedConfigs(receivedConfigs);
|
||||
computeRequest.setDistributeConfigs(distributeConfigs);
|
||||
|
||||
BonusReceivedComputeVO computeVO = receivedCompute(computeRequest);
|
||||
|
||||
// 处理门店实收数据
|
||||
saveReceivedData(rule, payMonth, revenue, computeVO, distributeConfigs);
|
||||
|
||||
// 处理员工奖金明细
|
||||
processEmployeeDetail(payMonth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processNewProductRule(BonusDistributionRuleDO rule, String payDate) {
|
||||
String storeId = rule.getStoreId();
|
||||
|
||||
// 检查是否已统计过
|
||||
if (newProductStoreDAO.existsByRuleIdAndPayDate(rule.getId(), payDate)) {
|
||||
log.info("规则已统计过, ruleId: {}, payDate: {}", rule.getId(), payDate);
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取门店编号
|
||||
StoreDO store = storeDao.getEffectiveByStoreId(storeId);
|
||||
if (store == null) {
|
||||
log.warn("门店不存在, storeId: {}", storeId);
|
||||
return;
|
||||
}
|
||||
String storeNum = store.getStoreNum();
|
||||
|
||||
// 解析规则配置
|
||||
JSONObject bonusConfig = JSONObject.parseObject(rule.getBonusConfig());
|
||||
List<BonusRuleProductConfig> productConfigs = bonusConfig.getJSONArray("productConfigs")
|
||||
.toJavaList(BonusRuleProductConfig.class);
|
||||
List<BonusRuleDistributeConfig> distributeConfigs = JSONObject.parseArray(rule.getDistributeConfig(), BonusRuleDistributeConfig.class);
|
||||
|
||||
// 调用API获取门店菜品日销量数据
|
||||
StoreRecipeDailySalesRequest request = new StoreRecipeDailySalesRequest();
|
||||
request.setStoreNum(storeNum);
|
||||
request.setStartDate(payDate);
|
||||
request.setEndDate(payDate);
|
||||
|
||||
List<StoreRecipeDailySalesResponse> salesList = storeOpenDataService.getRecipeDailySales(request);
|
||||
if (CollectionUtils.isEmpty(salesList)) {
|
||||
log.warn("门店菜品日销量数据为空, storeNum: {}", storeNum);
|
||||
return;
|
||||
}
|
||||
|
||||
// 构建销量请求
|
||||
List<BonusProductRecipeCompute> recipeSales = CollStreamUtil.toList(salesList, v -> new BonusProductRecipeCompute(v.getRecipeNo(), v.getSales()));
|
||||
|
||||
// 计算奖金
|
||||
BonusProductComputeRequest computeRequest = new BonusProductComputeRequest();
|
||||
computeRequest.setRecipeSales(recipeSales);
|
||||
computeRequest.setProductConfigs(productConfigs);
|
||||
computeRequest.setDistributeConfigs(distributeConfigs);
|
||||
|
||||
BonusProductComputeVO computeVO = productCompute(computeRequest);
|
||||
|
||||
// 入库
|
||||
saveNewProductData(rule, payDate, computeVO, productConfigs, distributeConfigs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processEmployeeDetail(String payMonth) {
|
||||
// 查询门店员工实收数据
|
||||
List<BonusReceivedEmployeeDO> receiveList = receivedEmployeeDAO.getMonthlyStatisticsGroupByStore(payMonth);
|
||||
// 查询门店员工新品销售数据
|
||||
List<BonusNewProductEmployeeDO> productList = newProductEmployeeDAO.getMonthlyStatisticsGroupByStore(payMonth);
|
||||
|
||||
// 将实收数据转为 Map<storeId, Map<rewardUserId, BonusReceivedEmployeeDO>>
|
||||
Map<String, Map<String, BonusReceivedEmployeeDO>> receiveMap = receiveList.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
BonusReceivedEmployeeDO::getStoreId,
|
||||
Collectors.toMap(
|
||||
BonusReceivedEmployeeDO::getRewardUserId,
|
||||
v -> v,
|
||||
(v1, v2) -> v1
|
||||
)
|
||||
));
|
||||
|
||||
// 将新品数据转为 Map<storeId, Map<rewardUserId, BonusNewProductEmployeeDO>>
|
||||
Map<String, Map<String, BonusNewProductEmployeeDO>> productMap = productList.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
BonusNewProductEmployeeDO::getStoreId,
|
||||
Collectors.toMap(
|
||||
BonusNewProductEmployeeDO::getRewardUserId,
|
||||
v -> v,
|
||||
(v1, v2) -> v1
|
||||
)
|
||||
));
|
||||
|
||||
Set<Pair<String, String>> allStoreUser = new HashSet<>();
|
||||
allStoreUser.addAll(CollStreamUtil.toList(receiveList, v -> Pair.of(v.getStoreId(), v.getRewardUserId())));
|
||||
allStoreUser.addAll(CollStreamUtil.toList(productList, v -> Pair.of(v.getStoreId(), v.getRewardUserId())));
|
||||
|
||||
Date payDate = DateUtils.strToDate(payMonth, "yyyy-MM");
|
||||
List<BonusEmployeeRewardDetailDO> detailList = CollStreamUtil.toList(allStoreUser, v -> {
|
||||
String storeId = v.getKey();
|
||||
String rewardUserId = v.getValue();
|
||||
BonusEmployeeRewardDetailDO detailDO = new BonusEmployeeRewardDetailDO();
|
||||
detailDO.setStoreId(storeId);
|
||||
detailDO.setPayDate(payDate);
|
||||
detailDO.setRewardUserId(rewardUserId);
|
||||
BonusReceivedEmployeeDO receive = receiveMap.getOrDefault(storeId, Collections.emptyMap()).get(rewardUserId);
|
||||
BonusNewProductEmployeeDO product = productMap.getOrDefault(storeId, Collections.emptyMap()).get(rewardUserId);
|
||||
detailDO.setReceivedAmount(Objects.nonNull(receive) ? receive.getReceivedAmount() : BigDecimal.ZERO);
|
||||
detailDO.setNewProjectAmount(Objects.nonNull(product) ? product.getRewardAmount() : BigDecimal.ZERO);
|
||||
if (Objects.nonNull(receive)) {
|
||||
detailDO.setRewardUserName(receive.getRewardUserName());
|
||||
}
|
||||
if (Objects.nonNull(product)) {
|
||||
detailDO.setRewardUserName(product.getRewardUserName());
|
||||
}
|
||||
return detailDO;
|
||||
});
|
||||
if (CollectionUtils.isNotEmpty(detailList)) {
|
||||
rewardDetailDAO.insertOrUpdateBatch(detailList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 入库实收奖金数据
|
||||
*/
|
||||
private void saveReceivedData(BonusDistributionRuleDO rule, String payMonth,
|
||||
StoreMonthRevenueResponse revenue, BonusReceivedComputeVO computeVO,
|
||||
List<BonusRuleDistributeConfig> distributeConfigs) {
|
||||
Date payDate = DateUtils.strToDate(payMonth, "yyyy-MM");
|
||||
|
||||
// 实收门店数据
|
||||
BonusReceivedStoreDO receivedStoreDO = new BonusReceivedStoreDO();
|
||||
receivedStoreDO.setRuleId(rule.getId());
|
||||
receivedStoreDO.setStoreId(rule.getStoreId());
|
||||
receivedStoreDO.setPayDate(payDate);
|
||||
receivedStoreDO.setReceivedMonthly(revenue.getReceivedAmount());
|
||||
receivedStoreDO.setBusinessDays(revenue.getBusinessDays());
|
||||
receivedStoreDO.setReceivedDaily(revenue.getReceivedAmountDaily());
|
||||
receivedStoreDO.setReceivedDailyLast(revenue.getReceivedAmountDailyLastMonth());
|
||||
receivedStoreDO.setAmountTotal(computeVO.getAmountTotal());
|
||||
receivedStoreDAO.insert(receivedStoreDO);
|
||||
|
||||
// 实收门店员工数据
|
||||
List<BonusReceivedEmployeeDO> employeeList = new ArrayList<>();
|
||||
for (BonusComputeUserVO userVO : computeVO.getDetail()) {
|
||||
BonusReceivedEmployeeDO employeeDO = new BonusReceivedEmployeeDO();
|
||||
employeeDO.setReceivedStoreId(receivedStoreDO.getId());
|
||||
employeeDO.setRuleId(rule.getId());
|
||||
employeeDO.setStoreId(rule.getStoreId());
|
||||
employeeDO.setPayDate(payDate);
|
||||
|
||||
// 查找分配比例
|
||||
BonusRuleDistributeConfig config = findDistributeConfigByName(distributeConfigs, userVO.getRewardUserId());
|
||||
if (config != null) {
|
||||
employeeDO.setRewardRatio(config.getRewardRatio());
|
||||
employeeDO.setRewardUserId(config.getRewardUserId());
|
||||
}
|
||||
employeeDO.setReceivedAmount(userVO.getRewardAmount());
|
||||
employeeDO.setRewardUserName(userVO.getRewardUserName());
|
||||
employeeDO.setRewardUserId(userVO.getRewardUserId());
|
||||
employeeList.add(employeeDO);
|
||||
}
|
||||
receivedEmployeeDAO.insertBatch(employeeList);
|
||||
}
|
||||
|
||||
private BonusRuleDistributeConfig findDistributeConfigByName(List<BonusRuleDistributeConfig> distributeConfigs, String userId) {
|
||||
if (org.apache.commons.collections4.CollectionUtils.isEmpty(distributeConfigs) || userId == null) {
|
||||
return null;
|
||||
}
|
||||
return distributeConfigs.stream()
|
||||
.filter(c -> c.getRewardUserId().equals(userId))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理新品销售奖金数据
|
||||
*/
|
||||
private void saveNewProductData(BonusDistributionRuleDO rule, String payDate,
|
||||
BonusProductComputeVO computeVO,
|
||||
List<BonusRuleProductConfig> productConfigs,
|
||||
List<BonusRuleDistributeConfig> distributeConfigs) {
|
||||
Date payDateObj = DateUtils.strToDate(payDate, "yyyy-MM-dd");
|
||||
|
||||
// 计算总金额
|
||||
BigDecimal amountTotal = computeVO.getDetail().stream()
|
||||
.map(BonusComputeUserVO::getRewardAmount)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
// 1. 新品销售奖金-门店
|
||||
BonusNewProductStoreDO productStoreDO = new BonusNewProductStoreDO();
|
||||
productStoreDO.setRuleId(rule.getId());
|
||||
productStoreDO.setStoreId(rule.getStoreId());
|
||||
productStoreDO.setPayDate(payDateObj);
|
||||
productStoreDO.setAmountTotal(amountTotal);
|
||||
newProductStoreDAO.insert(productStoreDO);
|
||||
|
||||
// 2. 入库新品销售奖金-员工
|
||||
List<BonusNewProductEmployeeDO> employeeList = new ArrayList<>();
|
||||
for (BonusComputeUserVO userVO : computeVO.getDetail()) {
|
||||
BonusNewProductEmployeeDO employeeDO = new BonusNewProductEmployeeDO();
|
||||
employeeDO.setProductStoreId(productStoreDO.getId());
|
||||
employeeDO.setRuleId(rule.getId());
|
||||
employeeDO.setStoreId(rule.getStoreId());
|
||||
employeeDO.setPayDate(payDateObj);
|
||||
|
||||
BonusRuleDistributeConfig config = findDistributeConfigByName(distributeConfigs, userVO.getRewardUserId());
|
||||
if (config != null) {
|
||||
employeeDO.setRewardRatio(config.getRewardRatio());
|
||||
employeeDO.setRewardUserId(config.getRewardUserId());
|
||||
}
|
||||
employeeDO.setRewardAmount(userVO.getRewardAmount());
|
||||
employeeDO.setRewardUserName(userVO.getRewardUserName());
|
||||
employeeList.add(employeeDO);
|
||||
}
|
||||
newProductEmployeeDAO.insertBatch(employeeList);
|
||||
|
||||
// 3. 新品销售奖金-菜品
|
||||
List<BonusNewProductRecipeDO> recipeList = new ArrayList<>();
|
||||
for (BonusProductRecipeComputeVO recipeVO : computeVO.getRecipes()) {
|
||||
BonusNewProductRecipeDO recipeDO = new BonusNewProductRecipeDO();
|
||||
recipeDO.setRuleId(rule.getId());
|
||||
recipeDO.setStoreId(rule.getStoreId());
|
||||
recipeDO.setPayDate(payDateObj);
|
||||
recipeDO.setRecipeNo(recipeVO.getRecipeNo());
|
||||
recipeDO.setRecipeName(recipeVO.getRecipeName());
|
||||
|
||||
// 查找对应的配置
|
||||
BonusRuleProductConfig config = productConfigs.stream()
|
||||
.filter(c -> c.getRecipeNo().equals(recipeVO.getRecipeNo()))
|
||||
.findFirst().orElse(null);
|
||||
if (config != null) {
|
||||
recipeDO.setMinStandardNum(config.getMinStandardNum());
|
||||
recipeDO.setRewardAmount(config.getRewardAmount());
|
||||
recipeDO.setExcessStandardNum(config.getExcessStandardNum());
|
||||
recipeDO.setExcessAmount(config.getExcessAmount());
|
||||
}
|
||||
|
||||
recipeDO.setSalesVolume(recipeVO.getSalesVolume());
|
||||
recipeDO.setBasicRewardAmount(recipeVO.getBasicRewardAmount());
|
||||
recipeDO.setExcessRewardAmount(recipeVO.getExcessRewardAmount());
|
||||
recipeList.add(recipeDO);
|
||||
}
|
||||
newProductRecipeDAO.insertBatch(recipeList);
|
||||
|
||||
// 4. 新品销售奖金-菜品-员工
|
||||
List<BonusNewProductRecipeEmployeeDO> recipeEmployeeList = new ArrayList<>();
|
||||
for (BonusProductRecipeComputeVO recipeVO : computeVO.getRecipes()) {
|
||||
BonusNewProductRecipeDO savedRecipe = recipeList.stream()
|
||||
.filter(r -> r.getRecipeNo().equals(recipeVO.getRecipeNo()))
|
||||
.findFirst().orElse(null);
|
||||
|
||||
if (savedRecipe != null && CollectionUtils.isNotEmpty(recipeVO.getDetail())) {
|
||||
for (BonusComputeUserVO userVO : recipeVO.getDetail()) {
|
||||
BonusNewProductRecipeEmployeeDO recipeEmployeeDO = new BonusNewProductRecipeEmployeeDO();
|
||||
recipeEmployeeDO.setProductRecipeId(savedRecipe.getId());
|
||||
recipeEmployeeDO.setRuleId(rule.getId());
|
||||
recipeEmployeeDO.setStoreId(rule.getStoreId());
|
||||
recipeEmployeeDO.setPayDate(payDateObj);
|
||||
recipeEmployeeDO.setRecipeNo(recipeVO.getRecipeNo());
|
||||
recipeEmployeeDO.setRecipeName(recipeVO.getRecipeName());
|
||||
recipeEmployeeDO.setSalesVolume(recipeVO.getSalesVolume());
|
||||
|
||||
// 计算基础和超额奖金
|
||||
BigDecimal basicReward = userVO.getBasicRewardAmount();
|
||||
BigDecimal excessReward = userVO.getExcessRewardAmount();
|
||||
recipeEmployeeDO.setBasicRewardAmount(basicReward != null ? basicReward : BigDecimal.ZERO);
|
||||
recipeEmployeeDO.setExcessRewardAmount(excessReward != null ? excessReward : BigDecimal.ZERO);
|
||||
recipeEmployeeDO.setRewardRatio(userVO.getRewardRatio());
|
||||
recipeEmployeeDO.setRewardUserName(userVO.getRewardUserName());
|
||||
recipeEmployeeDO.setRewardUserId(userVO.getRewardUserId());
|
||||
recipeEmployeeList.add(recipeEmployeeDO);
|
||||
}
|
||||
}
|
||||
}
|
||||
newProductRecipeEmployeeDAO.insertBatch(recipeEmployeeList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<BonusReceivedStoreListVO> getReceivedStoreList(BonusReceivedStoreQueryRequest request) {
|
||||
PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
||||
List<BonusReceivedStoreDO> list = receivedStoreDAO.selectListByCondition(
|
||||
request.getStoreNumOrName(), request.getStartMonth(), request.getEndMonth(), request.getStoreId());
|
||||
PageInfo<BonusReceivedStoreListVO> page = BeanUtil.toPage(new PageInfo<>(list), BonusReceivedStoreListVO.class);
|
||||
fillBasicField(page.getList());
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BonusReceivedStoreDetailVO getReceivedStoreDetail(Long id) {
|
||||
BonusReceivedStoreDO storeDO = receivedStoreDAO.getById(id);
|
||||
if (Objects.isNull(storeDO)) {
|
||||
return null;
|
||||
}
|
||||
BonusReceivedStoreDetailVO vo = BeanUtil.toBean(storeDO, BonusReceivedStoreDetailVO.class);
|
||||
// 获取门店信息
|
||||
StoreDO store = storeDao.getEffectiveByStoreId(storeDO.getStoreId());
|
||||
if (Objects.nonNull(store)) {
|
||||
vo.setStoreNum(store.getStoreNum());
|
||||
vo.setStoreName(store.getStoreName());
|
||||
}
|
||||
// 获取奖金规则配置
|
||||
BonusDistributionRuleDO ruleDO = ruleDAO.getById(storeDO.getRuleId());
|
||||
if (Objects.nonNull(ruleDO)) {
|
||||
JSONObject bonusConfig = JSONObject.parseObject(ruleDO.getBonusConfig());
|
||||
BeanUtil.copyPropertiesIgnoreId(bonusConfig, vo);
|
||||
}
|
||||
// 获取员工本月奖金发放列表
|
||||
List<BonusReceivedEmployeeDO> employeeList = receivedEmployeeDAO.selectByReceivedStoreId(id);
|
||||
List<EmployeeBonusVO> employeeVOList = CollStreamUtil.toList(employeeList, e ->
|
||||
new EmployeeBonusVO(e.getRewardUserId(), e.getRewardUserName(), e.getRewardRatio(), e.getReceivedAmount()));
|
||||
vo.setEmployeeList(employeeVOList);
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<BonusReceivedEmployeeListVO> getReceivedEmployeeList(BonusReceivedEmployeeQueryRequest request) {
|
||||
PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
||||
List<BonusReceivedEmployeeDO> list = receivedEmployeeDAO.selectEmployeeListByCondition(
|
||||
request.getStoreNumOrName(), request.getStartMonth(), request.getEndMonth(), request.getRewardUserName(), request.getStoreId());
|
||||
PageInfo<BonusReceivedEmployeeListVO> page = BeanUtil.toPage(new PageInfo<>(list), BonusReceivedEmployeeListVO.class);
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return page;
|
||||
}
|
||||
// 获取门店实收信息
|
||||
Set<Long> receivedStoreIds = CollStreamUtil.toSet(list, BonusReceivedEmployeeDO::getReceivedStoreId);
|
||||
Map<Long, BonusReceivedStoreDO> storeDOMap = receivedStoreDAO.getMapByIds(new ArrayList<>(receivedStoreIds));
|
||||
// 获取门店信息
|
||||
fillBasicField(page.getList());
|
||||
page.getList().forEach(v -> {
|
||||
// 填充门店实收信息
|
||||
BonusReceivedStoreDO receivedStoreDO = storeDOMap.get(v.getReceivedStoreId());
|
||||
if (Objects.nonNull(receivedStoreDO)) {
|
||||
v.setReceivedMonthly(receivedStoreDO.getReceivedMonthly());
|
||||
v.setBusinessDays(receivedStoreDO.getBusinessDays());
|
||||
v.setReceivedDaily(receivedStoreDO.getReceivedDaily());
|
||||
v.setReceivedDailyLast(receivedStoreDO.getReceivedDailyLast());
|
||||
v.setAmountTotal(receivedStoreDO.getAmountTotal());
|
||||
}
|
||||
});
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BonusReceivedStoreDetailVO getReceivedEmployeeDetail(Long id) {
|
||||
BonusReceivedEmployeeDO employeeDO = receivedEmployeeDAO.getById(id);
|
||||
if (Objects.isNull(employeeDO)) {
|
||||
return null;
|
||||
}
|
||||
BonusReceivedStoreDO storeDO = receivedStoreDAO.getById(employeeDO.getReceivedStoreId());
|
||||
if (Objects.isNull(storeDO)) {
|
||||
return null;
|
||||
}
|
||||
BonusReceivedStoreDetailVO vo = BeanUtil.toBean(storeDO, BonusReceivedStoreDetailVO.class);
|
||||
// 获取门店信息
|
||||
StoreDO store = storeDao.getEffectiveByStoreId(storeDO.getStoreId());
|
||||
if (Objects.nonNull(store)) {
|
||||
vo.setStoreNum(store.getStoreNum());
|
||||
vo.setStoreName(store.getStoreName());
|
||||
}
|
||||
// 获取奖金规则配置
|
||||
BonusDistributionRuleDO ruleDO = ruleDAO.getById(storeDO.getRuleId());
|
||||
if (Objects.nonNull(ruleDO)) {
|
||||
JSONObject bonusConfig = JSONObject.parseObject(ruleDO.getBonusConfig());
|
||||
BeanUtil.copyPropertiesIgnoreId(bonusConfig, vo);
|
||||
}
|
||||
// 获取员工本月奖金发放列表
|
||||
EmployeeBonusVO employeeVO = new EmployeeBonusVO(employeeDO.getRewardUserId(), employeeDO.getRewardUserName(), employeeDO.getRewardRatio(), employeeDO.getReceivedAmount());
|
||||
vo.setEmployeeList(Collections.singletonList(employeeVO));
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<BonusProductStoreListVO> getNewProductStoreList(BonusProductQueryRequest request) {
|
||||
PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
||||
List<BonusNewProductStoreDO> list = newProductStoreDAO.monthlyStatistics(request.getStoreNumOrName(), request.getStartDate(), request.getEndDate(), null, null);
|
||||
|
||||
PageInfo<BonusProductStoreListVO> page = BeanUtil.toPage(new PageInfo<>(list), BonusProductStoreListVO.class);
|
||||
fillBasicField(page.getList());
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BonusProductStoreDetailVO getNewProductStoreDetail(BonusProductMonthlyQueryRequest request) {
|
||||
if (Objects.isNull(request.getRuleId())) {
|
||||
throw new ServiceException(ErrorCodeEnum.ERROR_MESSAGE, "规则id不能为空");
|
||||
}
|
||||
List<BonusNewProductStoreDO> list = newProductStoreDAO.monthlyStatistics(null, request.getPayDate(), request.getPayDate(), request.getStoreId(), request.getRuleId());
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return null;
|
||||
}
|
||||
BonusNewProductStoreDO productStoreDO = list.get(0);
|
||||
BonusProductStoreDetailVO vo = new BonusProductStoreDetailVO();
|
||||
|
||||
BonusDistributionRuleDO ruleDO = ruleDAO.getById(productStoreDO.getRuleId());
|
||||
if (Objects.nonNull(ruleDO)) {
|
||||
JSONObject bonusConfig = JSONObject.parseObject(ruleDO.getBonusConfig());
|
||||
BeanUtil.copyPropertiesIgnoreId(bonusConfig, vo);
|
||||
}
|
||||
vo.setPayDate(productStoreDO.getPayDate());
|
||||
// 获取门店信息
|
||||
StoreDO store = storeDao.getEffectiveByStoreId(productStoreDO.getStoreId());
|
||||
if (Objects.nonNull(store)) {
|
||||
vo.setStoreNum(store.getStoreNum());
|
||||
vo.setStoreName(store.getStoreName());
|
||||
}
|
||||
// 获取发放明细列表
|
||||
List<BonusNewProductEmployeeDO> employeeList = newProductEmployeeDAO.monthlyStatistics(request.getRuleId(), request.getStoreId(), request.getPayDate(), null);
|
||||
List<EmployeeBonusVO> employeeVOList = CollStreamUtil.toList(employeeList, e ->
|
||||
new EmployeeBonusVO(e.getRewardUserId(), e.getRewardUserName(), null, e.getRewardAmount()));
|
||||
vo.setEmployeeList(employeeVOList);
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<BonusProductRecipeListVO> getNewProductRecipeList(BonusProductQueryRequest request) {
|
||||
PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
||||
List<BonusNewProductRecipeDO> list = newProductRecipeDAO.monthlyStatistics(request.getStoreNumOrName(), request.getStartDate(), request.getEndDate(), request.getRecipeNoOrName());
|
||||
PageInfo<BonusProductRecipeListVO> page = BeanUtil.toPage(new PageInfo<>(list), BonusProductRecipeListVO.class);
|
||||
fillBasicField(page.getList());
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<BonusProductRecipeDetailVO> getNewProductRecipeDetail(BonusProductRecipeQueryRequest request) {
|
||||
PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
||||
List<BonusNewProductRecipeDO> list = newProductRecipeDAO.selectListByCondition(request.getStoreId(), request.getRecipeNo(), request.getStartDate(), request.getEndDate());
|
||||
PageInfo<BonusProductRecipeDetailVO> page = BeanUtil.toPage(new PageInfo<>(list), BonusProductRecipeDetailVO.class);
|
||||
fillBasicField(page.getList());
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<BonusProductEmployeeListVO> getNewProductEmployeeList(BonusProductEmployeeQueryRequest request) {
|
||||
PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
||||
List<BonusNewProductEmployeeDO> list = newProductEmployeeDAO.employeeMonthlyStatistics(request.getStartDate(),
|
||||
request.getEndDate(), request.getStoreNumOrName(), request.getRewardUserName(), request.getStoreId());
|
||||
List<BonusProductEmployeeListVO> result = CollStreamUtil.toList(list, v -> {
|
||||
BonusProductEmployeeListVO vo = BeanUtil.toBean(v, BonusProductEmployeeListVO.class);
|
||||
vo.setReceivedAmount(v.getRewardAmount());
|
||||
return vo;
|
||||
});
|
||||
PageInfo<BonusProductEmployeeListVO> page = BeanUtil.toPage(new PageInfo<>(list), result);
|
||||
fillBasicField(page.getList());
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BonusProductStoreDetailVO getNewProductEmployeeDetail(BonusProductMonthlyQueryRequest request) {
|
||||
if (Objects.isNull(request.getRewardUserId())) {
|
||||
throw new ServiceException(ErrorCodeEnum.ERROR_MESSAGE, "奖励人id不能为空");
|
||||
}
|
||||
List<BonusNewProductEmployeeDO> list = newProductEmployeeDAO.monthlyStatistics(null, request.getStoreId(), request.getPayDate(), request.getRewardUserId());
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return null;
|
||||
}
|
||||
BonusNewProductEmployeeDO employeeDO = list.get(0);
|
||||
|
||||
BonusProductStoreDetailVO vo = new BonusProductStoreDetailVO();
|
||||
vo.setPayDate(request.getPayDate());
|
||||
|
||||
BonusDistributionRuleDO ruleDO = ruleDAO.getById(employeeDO.getRuleId());
|
||||
if (Objects.nonNull(ruleDO)) {
|
||||
JSONObject bonusConfig = JSONObject.parseObject(ruleDO.getBonusConfig());
|
||||
BeanUtil.copyPropertiesIgnoreId(bonusConfig, vo);
|
||||
}
|
||||
vo.setPayDate(employeeDO.getPayDate());
|
||||
// 获取门店信息
|
||||
StoreDO store = storeDao.getEffectiveByStoreId(request.getStoreId());
|
||||
if (Objects.nonNull(store)) {
|
||||
vo.setStoreNum(store.getStoreNum());
|
||||
vo.setStoreName(store.getStoreName());
|
||||
}
|
||||
List<EmployeeBonusVO> employeeVOList = Collections.singletonList(new EmployeeBonusVO(employeeDO.getRewardUserId(), employeeDO.getRewardUserName(), null, employeeDO.getRewardAmount()));
|
||||
vo.setEmployeeList(employeeVOList);
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<BonusProductRecipeEmployeeListVO> getNewProductRecipeEmployeeList(BonusProductEmployeeQueryRequest request) {
|
||||
PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
||||
List<BonusNewProductRecipeEmployeeDO> list = newProductRecipeEmployeeDAO.monthlyStatistics(request.getStoreNumOrName(), request.getStartDate(), request.getEndDate(), request.getRewardUserName(), request.getRecipeNoOrName());
|
||||
PageInfo<BonusProductRecipeEmployeeListVO> page = BeanUtil.toPage(new PageInfo<>(list), BonusProductRecipeEmployeeListVO.class);
|
||||
fillBasicField(page.getList());
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<BonusProductRecipeEmployeeDetailVO> getNewProductRecipeEmployeeDetail(BonusProductRecipeEmployeeQueryRequest request) {
|
||||
PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
||||
List<BonusNewProductRecipeEmployeeDO> list = newProductRecipeEmployeeDAO.selectListByCondition(request.getStoreId(), request.getRecipeNo(), request.getRewardUserId(), request.getStartDate(), request.getEndDate());
|
||||
Set<Long> productRecipeIds = CollStreamUtil.toSet(list, BonusNewProductRecipeEmployeeDO::getProductRecipeId);
|
||||
Map<Long, BonusNewProductRecipeDO> productRecipeMap = newProductRecipeDAO.getMapByIds(new ArrayList<>(productRecipeIds));
|
||||
List<BonusProductRecipeEmployeeDetailVO> result = CollStreamUtil.toList(list, v -> {
|
||||
BonusProductRecipeEmployeeDetailVO vo = BeanUtil.toBean(v, BonusProductRecipeEmployeeDetailVO.class);
|
||||
BonusNewProductRecipeDO recipeDO = productRecipeMap.get(v.getProductRecipeId());
|
||||
if (Objects.nonNull(recipeDO)) {
|
||||
vo.setMinStandardNum(recipeDO.getMinStandardNum());
|
||||
vo.setRewardAmount(recipeDO.getRewardAmount());
|
||||
vo.setExcessStandardNum(recipeDO.getExcessStandardNum());
|
||||
vo.setExcessAmount(recipeDO.getExcessAmount());
|
||||
}
|
||||
return vo;
|
||||
});
|
||||
PageInfo<BonusProductRecipeEmployeeDetailVO> page = BeanUtil.toPage(new PageInfo<>(list), result);
|
||||
fillBasicField(page.getList());
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<BonusEmployeeDetailVO> getEmployeeMonthlyDetail(BonusProductEmployeeQueryRequest request) {
|
||||
PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
||||
List<BonusEmployeeRewardDetailDO> list = rewardDetailDAO.selectListByCondition(request.getStoreNumOrName(),
|
||||
request.getStartDate(), request.getEndDate(), request.getRewardUserName(), request.getStoreId());
|
||||
PageInfo<BonusEmployeeDetailVO> page = BeanUtil.toPage(new PageInfo<>(list), BonusEmployeeDetailVO.class);
|
||||
fillBasicField(page.getList());
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void deleteMonthlyReceived(BonusDistributionRuleDO ruleDO, String payMonth) {
|
||||
Date payDate = DateUtils.strToDate(payMonth, "yyyy-MM");
|
||||
// 门店实收
|
||||
receivedStoreDAO.deleteMonthlyReceived(ruleDO.getId(), ruleDO.getStoreId(), payDate);
|
||||
// 员工
|
||||
receivedEmployeeDAO.deleteMonthlyReceived(ruleDO.getId(), ruleDO.getStoreId(), payDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void deleteMonthlyNewProduct(BonusDistributionRuleDO ruleDO, String payDate) {
|
||||
Date payDateObj = DateUtils.strToDate(payDate, "yyyy-MM-dd");
|
||||
newProductRecipeDAO.deleteDailyNewProduct(ruleDO.getId(), ruleDO.getStoreId(), payDateObj);
|
||||
newProductRecipeEmployeeDAO.deleteDailyNewProduct(ruleDO.getId(), ruleDO.getStoreId(), payDateObj);
|
||||
newProductEmployeeDAO.deleteDailyNewProduct(ruleDO.getId(), ruleDO.getStoreId(), payDateObj);
|
||||
newProductStoreDAO.deleteDailyNewProduct(ruleDO.getId(), ruleDO.getStoreId(), payDateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoreRecipesResponse> getRecipes(String storeId) {
|
||||
StoreDO storeDO = storeDao.getEffectiveByStoreId(storeId);
|
||||
if (Objects.isNull(storeDO)) {
|
||||
throw new ServiceException(ErrorCodeEnum.STORE_NOT_FIND);
|
||||
}
|
||||
StoreRecipesRequest request = new StoreRecipesRequest();
|
||||
request.setStoreNum(storeDO.getStoreNum());
|
||||
return storeOpenDataService.getRecipes(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal receivedDailyLast(String storeId) {
|
||||
StoreDO storeDO = storeDao.getEffectiveByStoreId(storeId);
|
||||
if (Objects.isNull(storeDO)) {
|
||||
throw new ServiceException(ErrorCodeEnum.STORE_NOT_FIND);
|
||||
}
|
||||
String lastMonth = LocalDate.now().minusMonths(1).format(DateTimeFormatter.ofPattern("yyyy-MM"));
|
||||
StoreMonthRevenueRequest request = new StoreMonthRevenueRequest();
|
||||
request.setStoreNum(storeDO.getStoreNum());
|
||||
request.setStartDate(lastMonth);
|
||||
request.setEndDate(lastMonth);
|
||||
List<StoreMonthRevenueResponse> monthRevenue = storeOpenDataService.getMonthRevenue(request);
|
||||
if (CollectionUtils.isNotEmpty(monthRevenue)) {
|
||||
StoreMonthRevenueResponse storeMonthRevenueResponse = monthRevenue.get(0);
|
||||
return Objects.nonNull(storeMonthRevenueResponse.getReceivedAmountDaily()) ? storeMonthRevenueResponse.getReceivedAmountDaily() : BigDecimal.ZERO;
|
||||
}
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
private void fillBasicField(List<? extends BonusBasicVO> list) {
|
||||
Set<String> storeIds = CollStreamUtil.toSet(list, BonusBasicVO::getStoreId);
|
||||
Map<String, StoreDO> storeMap = storeDao.getStoreMapByStoreIds(new ArrayList<>(storeIds));
|
||||
list.forEach(v -> {
|
||||
StoreDO storeDO = storeMap.get(v.getStoreId());
|
||||
if (Objects.nonNull(storeDO)) {
|
||||
v.setStoreNum(storeDO.getStoreNum());
|
||||
v.setStoreName(storeDO.getStoreName());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -353,6 +353,51 @@ public class StoreServiceImpl implements StoreService {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoreUserDTO> getStoreUserPositionList(String storeId, String userName) {
|
||||
if (StrUtil.isBlank(storeId)) {
|
||||
throw new ServiceException(ErrorCodeEnum.PARAMS_VALIDATE_ERROR.getCode(), "请选择门店后查询");
|
||||
}
|
||||
List<AuthStoreUserDTO> authStoreUserDTOList = this.authStoreUserV2(
|
||||
Collections.singletonList(storeId), "store_inside");
|
||||
|
||||
if (CollectionUtils.isEmpty(authStoreUserDTOList)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<String> userIdList = ListUtils.emptyIfNull(authStoreUserDTOList)
|
||||
.stream()
|
||||
.map(AuthStoreUserDTO::getUserIdList)
|
||||
.flatMap(Collection::stream)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (CollUtil.isEmpty(userIdList)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<StoreUserDTO> list = sysRoleMapper.userAndPositionList( userIdList, userName, "store_inside");
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
//先去重
|
||||
list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
|
||||
new TreeSet<>(Comparator.comparing(StoreUserDTO::getUserId))), ArrayList::new));
|
||||
}
|
||||
|
||||
Map<String, List<StoreUserDTO>> storeUserDTOMap = ListUtils.emptyIfNull(list).stream().collect(Collectors.groupingBy(k -> k.getUserId()));
|
||||
List<StoreUserDTO> result = Lists.newArrayList();
|
||||
for (String userId : storeUserDTOMap.keySet()) {
|
||||
List<StoreUserDTO> singleUserDTOList = storeUserDTOMap.get(userId);
|
||||
if (CollectionUtils.isEmpty(singleUserDTOList)) {
|
||||
continue;
|
||||
}
|
||||
StoreUserDTO storeUserDTO = singleUserDTOList.get(0);
|
||||
List<String> positionNameList = ListUtils.emptyIfNull(singleUserDTOList)
|
||||
.stream().map(StoreUserDTO::getPositionName).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(positionNameList)) {
|
||||
storeUserDTO.setPositionName(String.join(Constants.COMMA, positionNameList));
|
||||
}
|
||||
result.add(storeUserDTO);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<AuthStoreUserDTO> authStoreUser(List<String> storeIdList, String positionType) {
|
||||
@@ -402,6 +447,55 @@ public class StoreServiceImpl implements StoreService {
|
||||
.map(data -> mapAuthStoreUserDTO(regionUserAuthMappingList, allStoreUserIdList, storeUserAuthMappingList, notIncludeRegionUserAuthMappingList, data))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
@Override
|
||||
public List<AuthStoreUserDTO> authStoreUserV2(List<String> storeIdList, String positionType) {
|
||||
List<AuthStoreUserDTO> result = new ArrayList<>();
|
||||
if (CollectionUtils.isEmpty(storeIdList)) {
|
||||
return result;
|
||||
}
|
||||
//将拥有管理员角色、角色属性为全企业数据的人查询出来
|
||||
List<SysRoleVO> roleUserByRoleId = sysRoleMapper.getRoleUserByRoleEnum(Role.MASTER.getRoleEnum(),positionType);
|
||||
List<SysRoleVO> roleUserByRoleAuth = sysRoleMapper.getRoleUserByRoleAuth(AuthRoleEnum.ALL.getCode(),positionType);
|
||||
//组合出拥有所有门店信息的人
|
||||
List<String> allStoreUserIdList = getAllStoreUserIdList(roleUserByRoleId, roleUserByRoleAuth);
|
||||
//查询出有门店权限配置的的人员
|
||||
// 1.将门店区域切分出门店所属于的区域ID
|
||||
// 2.将配置了区域的人 查询出来
|
||||
// 3.将配置了门店的人 查询出来
|
||||
List<StoreAreaDTO> storeAreaList = storeMapper.getStoreAreaList(storeIdList);
|
||||
if (CollectionUtils.isEmpty(storeAreaList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<String> fullAreaIdList = ListUtils.emptyIfNull(storeAreaList)
|
||||
.stream()
|
||||
.map(StoreAreaDTO::getAreaIdList)
|
||||
.flatMap(Collection::stream)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
||||
List<String> lastAreaIdList = ListUtils.emptyIfNull(storeAreaList)
|
||||
.stream()
|
||||
.map(StoreAreaDTO::getAreaId)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
//除不包含子区域的可视化范围的区域配置。
|
||||
List<UserAuthMappingDO> regionUserAuthMappingList = userAuthMappingMapper.listUserAuthMappingByAuthV2(
|
||||
UserAuthMappingTypeEnum.REGION.getCode(), fullAreaIdList, positionType, AuthRoleEnum.NOT_INCLUDE_SUBORDINATE.getCode());
|
||||
//不包含子区域的的直属连接门店的区域下的配置(会重复一些选择了上面数据)
|
||||
List<UserAuthMappingDO> notIncludeRegionUserAuthMappingList = userAuthMappingMapper.listUserAuthMappingByAuthV2(
|
||||
UserAuthMappingTypeEnum.REGION.getCode(), lastAreaIdList, positionType, null);
|
||||
//配置了门店的的配置
|
||||
List<UserAuthMappingDO> storeUserAuthMappingList = userAuthMappingMapper.listUserAuthMappingByMappingList(
|
||||
storeIdList, UserAuthMappingTypeEnum.STORE.getCode());
|
||||
return ListUtils.emptyIfNull(storeAreaList)
|
||||
.stream()
|
||||
.map(data -> mapAuthStoreUserDTO(regionUserAuthMappingList, allStoreUserIdList, storeUserAuthMappingList, notIncludeRegionUserAuthMappingList, data))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
private List<String> getAllStoreUserIdList(List<SysRoleVO> roleUserByRoleId, List<SysRoleVO> roleUserByRoleAuth) {
|
||||
List<String> allUserIdList= new ArrayList<>();
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
package com.cool.store.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.cool.store.enums.ErrorCodeEnum;
|
||||
import com.cool.store.exception.ServiceException;
|
||||
import com.cool.store.request.storeopen.StoreMonthRevenueRequest;
|
||||
import com.cool.store.request.storeopen.StoreRecipeDailySalesRequest;
|
||||
import com.cool.store.request.storeopen.StoreRecipesRequest;
|
||||
import com.cool.store.response.storeopen.StoreMonthRevenueResponse;
|
||||
import com.cool.store.response.storeopen.StoreOpenApiResponse;
|
||||
import com.cool.store.response.storeopen.StoreRecipeDailySalesResponse;
|
||||
import com.cool.store.response.storeopen.StoreRecipesResponse;
|
||||
import com.cool.store.service.ThirdStoreOpenDataService;
|
||||
import com.cool.store.utils.StoreOpenSigner;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 第三方门店开放数据服务实现类
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2026/4/20
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ThirdStoreOpenDataServiceImpl implements ThirdStoreOpenDataService {
|
||||
|
||||
@Value("${store.open.url}")
|
||||
private String apiUrl;
|
||||
|
||||
@Value("${store.open.appId}")
|
||||
private String appId;
|
||||
|
||||
@Value("${store.open.secret}")
|
||||
private String secret;
|
||||
|
||||
@Resource
|
||||
private OkHttpClient okHttpClient;
|
||||
|
||||
@Resource
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private static final String METHOD_POST = "POST";
|
||||
|
||||
@Override
|
||||
public List<StoreMonthRevenueResponse> getMonthRevenue(StoreMonthRevenueRequest request) {
|
||||
String path = "/open/v1/store/monthRevenue";
|
||||
String url = apiUrl + path;
|
||||
return executeApiCall(url, path, request, StoreMonthRevenueResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoreRecipeDailySalesResponse> getRecipeDailySales(StoreRecipeDailySalesRequest request) {
|
||||
String path = "/open/v1/store/recipeDailySales";
|
||||
String url = apiUrl + path;
|
||||
return executeApiCall(url, path, request, StoreRecipeDailySalesResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoreRecipesResponse> getRecipes(StoreRecipesRequest request) {
|
||||
String path = "/open/v1/store/recipes";
|
||||
String url = apiUrl + path;
|
||||
return executeApiCall(url, path, request, StoreRecipesResponse.class);
|
||||
}
|
||||
|
||||
private <T> List<T> executeApiCall(String url, String path, Object request, Class<T> responseType) {
|
||||
logRequest(url, request);
|
||||
|
||||
try {
|
||||
String rawJsonBody = JSONObject.toJSONString(request);
|
||||
Request httpRequest = buildRequest(url, path, rawJsonBody);
|
||||
|
||||
try (Response response = okHttpClient.newCall(httpRequest).execute()) {
|
||||
String responseBody = response.body().string();
|
||||
logResponse(url, response.code(), responseBody);
|
||||
|
||||
if (!response.isSuccessful()) {
|
||||
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,
|
||||
"HTTP请求失败,状态码: " + response.code());
|
||||
}
|
||||
|
||||
JavaType javaType = objectMapper.getTypeFactory()
|
||||
.constructParametricType(StoreOpenApiResponse.class,
|
||||
objectMapper.getTypeFactory().constructCollectionType(List.class, responseType));
|
||||
|
||||
StoreOpenApiResponse<List<T>> apiResponse = objectMapper.readValue(responseBody, javaType);
|
||||
|
||||
if (apiResponse.getCode() != 200) {
|
||||
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR, apiResponse.getMsg());
|
||||
}
|
||||
|
||||
return apiResponse.getData();
|
||||
}
|
||||
} catch (ServiceException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("API调用异常 - URL: {}, 错误: {}", url, e.getMessage(), e);
|
||||
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR, "接口调用异常: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private Request buildRequest(String url, String path, String rawJsonBody) {
|
||||
String signTime = StoreOpenSigner.generateSignTime();
|
||||
String signRandom = StoreOpenSigner.generateRandom(16);
|
||||
String signingString = StoreOpenSigner.buildSigningString(METHOD_POST, path, rawJsonBody, signTime, signRandom);
|
||||
String sign = StoreOpenSigner.sign(signingString, secret);
|
||||
|
||||
log.debug("签名生成 - 原始字符串: {}, 签名结果: {}", signingString, sign);
|
||||
|
||||
RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json"), rawJsonBody);
|
||||
|
||||
return new Request.Builder()
|
||||
.url(url)
|
||||
.post(body)
|
||||
.addHeader("Content-Type", "application/json")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("App-Id", appId)
|
||||
.addHeader("X-ZhengXin-Sign", sign)
|
||||
.addHeader("X-ZhengXin-SignTime", signTime)
|
||||
.addHeader("X-ZhengXin-SignRandom", signRandom)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void logRequest(String url, Object requestBody) {
|
||||
if (log.isInfoEnabled()) {
|
||||
try {
|
||||
log.info("\n======= 请求开始 =======\n" +
|
||||
"API地址: {}\n" +
|
||||
"请求参数: {}\n" +
|
||||
"======= 请求结束 =======",
|
||||
url,
|
||||
objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(requestBody));
|
||||
} catch (JsonProcessingException e) {
|
||||
log.warn("日志JSON序列化失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void logResponse(String url, int statusCode, String responseBody) {
|
||||
if (log.isInfoEnabled()) {
|
||||
try {
|
||||
Object json = objectMapper.readValue(responseBody, Object.class);
|
||||
String prettyResponse = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);
|
||||
|
||||
log.info("\n======= 响应开始 =======\n" +
|
||||
"API地址: {}\n" +
|
||||
"HTTP状态码: {}\n" +
|
||||
"响应内容: {}\n" +
|
||||
"======= 响应结束 =======",
|
||||
url, statusCode, prettyResponse);
|
||||
} catch (Exception e) {
|
||||
log.info("\n======= 响应开始 =======\n" +
|
||||
"API地址: {}\n" +
|
||||
"HTTP状态码: {}\n" +
|
||||
"原始响应: {}\n" +
|
||||
"======= 响应结束 =======",
|
||||
url, statusCode, responseBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user