From 22fcfc6a9093c906d81a2ff5f10423d5d95534ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=9D=9E=E5=87=A1?= Date: Mon, 27 Apr 2026 10:41:08 +0000 Subject: [PATCH] Merge #111 into master from cc_20260417_bonus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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: 王非凡 Merged-by: 正新 CR-link: https://codeup.aliyun.com/692ea314dec569489f6f167c/hangzhou/java/custom_zxjp/change/111 --- .../com/cool/store/enums/ErrorCodeEnum.java | 7 + .../com/cool/store/utils/StoreOpenSigner.java | 78 ++ .../dao/bonus/BonusDistributionRuleDAO.java | 61 ++ .../bonus/BonusEmployeeRewardDetailDAO.java | 37 + .../dao/bonus/BonusNewProductEmployeeDAO.java | 82 ++ .../dao/bonus/BonusNewProductRecipeDAO.java | 64 ++ .../BonusNewProductRecipeEmployeeDAO.java | 74 ++ .../dao/bonus/BonusNewProductStoreDAO.java | 51 + .../dao/bonus/BonusReceivedEmployeeDAO.java | 62 ++ .../dao/bonus/BonusReceivedStoreDAO.java | 62 ++ .../store/mapper/UserAuthMappingMapper.java | 8 + .../bonus/BonusDistributionRuleMapper.java | 34 + .../BonusEmployeeRewardDetailMapper.java | 28 + .../bonus/BonusNewProductEmployeeMapper.java | 46 + .../BonusNewProductRecipeEmployeeMapper.java | 22 + .../bonus/BonusNewProductRecipeMapper.java | 23 + .../bonus/BonusNewProductStoreMapper.java | 20 + .../bonus/BonusReceivedEmployeeMapper.java | 25 + .../bonus/BonusReceivedStoreMapper.java | 18 + .../mapper/UserAuthMappingMapper.xml | 30 + .../bonus/BonusDistributionRuleMapper.xml | 66 ++ .../bonus/BonusEmployeeRewardDetailMapper.xml | 78 ++ .../bonus/BonusNewProductEmployeeMapper.xml | 96 ++ .../BonusNewProductRecipeEmployeeMapper.xml | 58 ++ .../bonus/BonusNewProductRecipeMapper.xml | 78 ++ .../bonus/BonusNewProductStoreMapper.xml | 47 + .../bonus/BonusReceivedEmployeeMapper.xml | 67 ++ .../mapper/bonus/BonusReceivedStoreMapper.xml | 47 + .../entity/bonus/BonusDistributionRuleDO.java | 90 ++ .../bonus/BonusEmployeeRewardDetailDO.java | 63 ++ .../bonus/BonusNewProductEmployeeDO.java | 75 ++ .../entity/bonus/BonusNewProductRecipeDO.java | 99 ++ .../BonusNewProductRecipeEmployeeDO.java | 99 ++ .../entity/bonus/BonusNewProductStoreDO.java | 51 + .../entity/bonus/BonusReceivedEmployeeDO.java | 75 ++ .../entity/bonus/BonusReceivedStoreDO.java | 75 ++ .../bonus/BonusProductComputeRequest.java | 33 + .../BonusProductEmployeeQueryRequest.java | 36 + .../BonusProductMonthlyQueryRequest.java | 33 + .../bonus/BonusProductQueryRequest.java | 29 + .../bonus/BonusProductRecipeCompute.java | 29 + ...onusProductRecipeEmployeeQueryRequest.java | 37 + .../bonus/BonusProductRecipeQueryRequest.java | 34 + .../bonus/BonusReceivedComputeRequest.java | 43 + .../BonusReceivedEmployeeQueryRequest.java | 32 + .../bonus/BonusReceivedStoreQueryRequest.java | 29 + .../request/bonus/BonusRuleAddRequest.java | 35 + .../bonus/BonusRuleDistributeConfig.java | 26 + .../request/bonus/BonusRuleEnableRequest.java | 25 + .../request/bonus/BonusRuleProductConfig.java | 35 + .../request/bonus/BonusRuleQueryRequest.java | 29 + .../bonus/BonusRuleReceivedConfig.java | 30 + .../request/bonus/BonusRuleUpdateRequest.java | 47 + .../storeopen/StoreMonthRevenueRequest.java | 27 + .../StoreRecipeDailySalesRequest.java | 27 + .../storeopen/StoreRecipesRequest.java | 19 + .../storeopen/StoreMonthRevenueResponse.java | 41 + .../storeopen/StoreOpenApiResponse.java | 18 + .../StoreRecipeDailySalesResponse.java | 34 + .../storeopen/StoreRecipesResponse.java | 24 + .../com/cool/store/vo/bonus/BonusBasicVO.java | 24 + .../store/vo/bonus/BonusComputeUserVO.java | 45 + .../store/vo/bonus/BonusEmployeeDetailVO.java | 33 + .../store/vo/bonus/BonusProductComputeVO.java | 27 + .../vo/bonus/BonusProductEmployeeListVO.java | 30 + .../vo/bonus/BonusProductRecipeComputeVO.java | 48 + .../vo/bonus/BonusProductRecipeDetailVO.java | 49 + .../BonusProductRecipeEmployeeDetailVO.java | 64 ++ .../BonusProductRecipeEmployeeListVO.java | 49 + .../vo/bonus/BonusProductRecipeListVO.java | 41 + .../vo/bonus/BonusProductStoreDetailVO.java | 32 + .../vo/bonus/BonusProductStoreListVO.java | 25 + .../vo/bonus/BonusReceivedComputeVO.java | 31 + .../vo/bonus/BonusReceivedEmployeeListVO.java | 49 + .../vo/bonus/BonusReceivedStoreDetailVO.java | 57 ++ .../vo/bonus/BonusReceivedStoreListVO.java | 38 + .../cool/store/vo/bonus/BonusRuleListVO.java | 35 + .../com/cool/store/vo/bonus/BonusRuleVO.java | 61 ++ .../cool/store/vo/bonus/EmployeeBonusVO.java | 33 + .../com/cool/store/service/StoreService.java | 11 + .../service/ThirdStoreOpenDataService.java | 43 + .../store/service/bonus/BonusService.java | 156 +++ .../service/bonus/impl/BonusServiceImpl.java | 898 ++++++++++++++++++ .../store/service/impl/StoreServiceImpl.java | 94 ++ .../impl/ThirdStoreOpenDataServiceImpl.java | 172 ++++ .../controller/webb/BonusController.java | 164 ++++ .../controller/webb/PCStoreController.java | 8 + .../controller/webb/PCTestController.java | 74 +- .../controller/webc/MiniBonusController.java | 174 ++++ .../controller/webc/MiniStoreController.java | 35 + .../com/cool/store/job/XxlJobHandler.java | 98 ++ .../main/resources/application-ab.properties | 7 +- .../resources/application-local.properties | 7 +- .../resources/application-online.properties | 7 +- .../resources/application-test.properties | 7 +- 95 files changed, 5466 insertions(+), 8 deletions(-) create mode 100644 coolstore-partner-common/src/main/java/com/cool/store/utils/StoreOpenSigner.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusDistributionRuleDAO.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusEmployeeRewardDetailDAO.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductEmployeeDAO.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductRecipeDAO.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductRecipeEmployeeDAO.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductStoreDAO.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusReceivedEmployeeDAO.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusReceivedStoreDAO.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusDistributionRuleMapper.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusEmployeeRewardDetailMapper.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductEmployeeMapper.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductRecipeEmployeeMapper.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductRecipeMapper.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductStoreMapper.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusReceivedEmployeeMapper.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusReceivedStoreMapper.java create mode 100644 coolstore-partner-dao/src/main/resources/mapper/bonus/BonusDistributionRuleMapper.xml create mode 100644 coolstore-partner-dao/src/main/resources/mapper/bonus/BonusEmployeeRewardDetailMapper.xml create mode 100644 coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductEmployeeMapper.xml create mode 100644 coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductRecipeEmployeeMapper.xml create mode 100644 coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductRecipeMapper.xml create mode 100644 coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductStoreMapper.xml create mode 100644 coolstore-partner-dao/src/main/resources/mapper/bonus/BonusReceivedEmployeeMapper.xml create mode 100644 coolstore-partner-dao/src/main/resources/mapper/bonus/BonusReceivedStoreMapper.xml create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusDistributionRuleDO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusEmployeeRewardDetailDO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductEmployeeDO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductRecipeDO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductRecipeEmployeeDO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductStoreDO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusReceivedEmployeeDO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusReceivedStoreDO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductComputeRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductEmployeeQueryRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductMonthlyQueryRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductQueryRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductRecipeCompute.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductRecipeEmployeeQueryRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductRecipeQueryRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusReceivedComputeRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusReceivedEmployeeQueryRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusReceivedStoreQueryRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleAddRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleDistributeConfig.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleEnableRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleProductConfig.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleQueryRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleReceivedConfig.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleUpdateRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/storeopen/StoreMonthRevenueRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/storeopen/StoreRecipeDailySalesRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/storeopen/StoreRecipesRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreMonthRevenueResponse.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreOpenApiResponse.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreRecipeDailySalesResponse.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreRecipesResponse.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusBasicVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusComputeUserVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusEmployeeDetailVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductComputeVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductEmployeeListVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeComputeVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeDetailVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeEmployeeDetailVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeEmployeeListVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeListVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductStoreDetailVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductStoreListVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedComputeVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedEmployeeListVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedStoreDetailVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedStoreListVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusRuleListVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusRuleVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/EmployeeBonusVO.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/service/ThirdStoreOpenDataService.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/service/bonus/BonusService.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/service/bonus/impl/BonusServiceImpl.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/service/impl/ThirdStoreOpenDataServiceImpl.java create mode 100644 coolstore-partner-web/src/main/java/com/cool/store/controller/webb/BonusController.java create mode 100644 coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniBonusController.java create mode 100644 coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniStoreController.java diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java index b3d42bd84..0c9b00c83 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java @@ -493,6 +493,13 @@ public enum ErrorCodeEnum { CLOSE_UP_CLOSED_AUDIT_NOT_PASS(1840008, "歇业申请未通过", null), CLOSE_UP_EXIST_OPEN_APPLY(1840009, "该歇业申请单已存在开业申请", null), CLOSE_UP_APPROVED(1840010, "该申请单已审批", null), + + BONUS_EXIST_OVERLAP_RULE(1850000, "门店该有效期范围内存在相同类型的启用规则", null), + BONUS_RULE_NOT_EXIST(1850001, "不存在该奖金发放规则", null), + BONUS_RULE_NOT_CONFIG(1850002, "奖金规则或分配规则未配置", null), + BONUS_DISTRIBUTE_RATIO_OVER_100(1850003, "分配规则员工比例之和大于100", null), + BONUS_PRODUCT_CONFIG_DUPLICATE(1850004, "奖金规则配置存在重复菜品", null), + BONUS_RULE_CONFIG_ERROR(1850005, "规则配置异常", null), ; diff --git a/coolstore-partner-common/src/main/java/com/cool/store/utils/StoreOpenSigner.java b/coolstore-partner-common/src/main/java/com/cool/store/utils/StoreOpenSigner.java new file mode 100644 index 000000000..da08476f9 --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/utils/StoreOpenSigner.java @@ -0,0 +1,78 @@ +package com.cool.store.utils; + +import java.nio.charset.StandardCharsets; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.security.SecureRandom; + +/** + * 门店开放数据签名工具类 + * + * @author wangff + * @since 2026/4/20 + */ +public class StoreOpenSigner { + + private static final SecureRandom RANDOM = new SecureRandom(); + + /** + * 构建签名串 + * + * @param method HTTP方法,如POST + * @param requestPath 请求路径,如/open/v1/store/monthRevenue + * @param rawJsonBody 原始JSON请求体 + * @param signTime 签名时间戳 + * @param signRandom 随机串 + * @return 签名串 + */ + public static String buildSigningString(String method, String requestPath, String rawJsonBody, + String signTime, String signRandom) { + return method + "&" + requestPath + "&" + rawJsonBody + "&" + signTime + "&" + signRandom; + } + + /** + * HMAC-SHA256签名,返回小写十六进制字符串 + * + * @param signingString 签名串 + * @param secret 密钥 + * @return 签名结果 + */ + public static String sign(String signingString, String secret) { + try { + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); + byte[] digest = mac.doFinal(signingString.getBytes(StandardCharsets.UTF_8)); + StringBuilder sb = new StringBuilder(digest.length * 2); + for (byte b : digest) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } catch (Exception e) { + throw new RuntimeException("签名失败", e); + } + } + + /** + * 生成随机串 + * + * @param length 随机串长度 + * @return 随机串 + */ + public static String generateRandom(int length) { + String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + StringBuilder sb = new StringBuilder(length); + for (int i = 0; i < length; i++) { + sb.append(chars.charAt(RANDOM.nextInt(chars.length()))); + } + return sb.toString(); + } + + /** + * 生成签名时间戳(秒) + * + * @return Unix秒时间戳字符串 + */ + public static String generateSignTime() { + return String.valueOf(System.currentTimeMillis() / 1000); + } +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusDistributionRuleDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusDistributionRuleDAO.java new file mode 100644 index 000000000..cb7b484e7 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusDistributionRuleDAO.java @@ -0,0 +1,61 @@ +package com.cool.store.dao.bonus; + +import com.cool.store.entity.bonus.BonusDistributionRuleDO; +import com.cool.store.mapper.bonus.BonusDistributionRuleMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import java.util.Date; +import java.util.List; + +/** + *

+ * 奖金发放规则DAO + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Repository +@RequiredArgsConstructor +public class BonusDistributionRuleDAO { + private final BonusDistributionRuleMapper bonusDistributionRuleMapper; + + public boolean addRule(BonusDistributionRuleDO ruleDO) { + return bonusDistributionRuleMapper.insertSelective(ruleDO) > 0; + } + + /** + * 门店下相同规则类型的启用规则生效期间有无交集 + * @param storeId 门店id + * @param type 规则类型 + * @param startDate 开始有效日期 + * @param endDate 结束有效日期 + * @return 是否存在 + */ + public boolean existOverlap(String storeId, Integer type, Date startDate, Date endDate) { + return bonusDistributionRuleMapper.existOverlap(storeId, type, startDate, endDate) > 0; + } + + public BonusDistributionRuleDO getById(Long id) { + return bonusDistributionRuleMapper.selectByPrimaryKey(id); + } + + public boolean updateByPrimaryKeySelective(BonusDistributionRuleDO ruleDO) { + return bonusDistributionRuleMapper.updateByPrimaryKeySelective(ruleDO) > 0; + } + + public List getList(String storeNumOrName, Integer type, Integer enable, String storeId) { + return bonusDistributionRuleMapper.getList(storeNumOrName, type, enable, storeId); + } + + /** + * 获取指定类型和生效月份的启用规则列表 + * @param type 规则类型 + * @param payMonth 发放月份 yyyy-MM + * @return 规则列表 + */ + public List getEnabledRulesByTypeAndMonth(Integer type, String payMonth) { + return bonusDistributionRuleMapper.selectEnabledRulesByTypeAndMonth(type, payMonth); + } +} diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusEmployeeRewardDetailDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusEmployeeRewardDetailDAO.java new file mode 100644 index 000000000..d62e0e695 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusEmployeeRewardDetailDAO.java @@ -0,0 +1,37 @@ +package com.cool.store.dao.bonus; + +import com.alibaba.excel.util.CollectionUtils; +import com.cool.store.entity.bonus.BonusEmployeeRewardDetailDO; +import com.cool.store.mapper.bonus.BonusEmployeeRewardDetailMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import java.util.Date; +import java.util.List; + +/** + * 员工奖励明细DAO + * + * @author wangff + * @since 2026/4/21 + */ +@Repository +@RequiredArgsConstructor +public class BonusEmployeeRewardDetailDAO { + private final BonusEmployeeRewardDetailMapper mapper; + + public int insert(BonusEmployeeRewardDetailDO entity) { + return mapper.insertSelective(entity); + } + + public int insertOrUpdateBatch(List list) { + if (CollectionUtils.isEmpty(list)) { + return 0; + } + return mapper.insertOrUpdateBatch(list); + } + + public List selectListByCondition(String storeNumOrName, Date startDate, Date endDate, String rewardUserName, String storeId) { + return mapper.selectListByCondition(storeNumOrName, startDate, endDate, rewardUserName, storeId); + } +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductEmployeeDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductEmployeeDAO.java new file mode 100644 index 000000000..4c3e4fce4 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductEmployeeDAO.java @@ -0,0 +1,82 @@ +package com.cool.store.dao.bonus; + +import cn.hutool.core.collection.CollStreamUtil; +import com.cool.store.entity.bonus.BonusNewProductEmployeeDO; +import com.cool.store.mapper.bonus.BonusNewProductEmployeeMapper; +import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.springframework.stereotype.Repository; +import tk.mybatis.mapper.entity.Example; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * 新品销售奖金-员工DAO + * + * @author wangff + * @since 2026/4/21 + */ +@Repository +@RequiredArgsConstructor +public class BonusNewProductEmployeeDAO { + private final BonusNewProductEmployeeMapper mapper; + + public int insert(BonusNewProductEmployeeDO entity) { + return mapper.insertSelective(entity); + } + + public int insertBatch(List list) { + if (CollectionUtils.isEmpty(list)) { + return 0; + } + return mapper.insertBatch(list); + } + + /** + * 月度奖金统计 + * @param storeId 门店id + * @param payDate 发放年月 + * @param userIds 用户id列表 + * @return 实体列表 + */ + public Map getMonthlyStatistics(String storeId, String payDate, List userIds) { + List> list = mapper.getMonthlyStatistics(storeId, payDate, userIds); + return CollStreamUtil.toMap(list, v -> MapUtils.getString(v, "reward_user_id"), v -> new BigDecimal(MapUtils.getString(v, "total_amount"))); + } + + /** + * 月度统计 + */ + public List monthlyStatistics(Long ruleId, String storeId, Date payDate, String userId) { + return mapper.monthlyStatistics(ruleId, storeId, payDate, userId); + } + + /** + * 员工列表月度统计 + */ + public List employeeMonthlyStatistics(Date startDate, + Date endDate, + String storeNumOrName, + String rewardUserName, + String storeId) { + return mapper.employeeMonthlyStatistics(startDate, endDate, storeNumOrName, rewardUserName, storeId); + } + + public List getMonthlyStatisticsGroupByStore(String payMonth) { + return mapper.getMonthlyStatisticsGroupByStore(payMonth); + } + + public void deleteDailyNewProduct(Long ruleId, String storeId, Date payDate) { + Example example = new Example(BonusNewProductEmployeeDO.class); + example.createCriteria() + .andEqualTo("ruleId", ruleId) + .andEqualTo("storeId", storeId) + .andEqualTo("payDate", payDate); + mapper.deleteByExample(example); + } +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductRecipeDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductRecipeDAO.java new file mode 100644 index 000000000..6e8899765 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductRecipeDAO.java @@ -0,0 +1,64 @@ +package com.cool.store.dao.bonus; + +import cn.hutool.core.collection.CollStreamUtil; +import com.alibaba.excel.util.CollectionUtils; +import com.cool.store.entity.bonus.BonusNewProductRecipeDO; +import com.cool.store.mapper.bonus.BonusNewProductRecipeMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; +import tk.mybatis.mapper.entity.Example; + +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 新品销售奖金-菜品DAO + * + * @author wangff + * @since 2026/4/21 + */ +@Repository +@RequiredArgsConstructor +public class BonusNewProductRecipeDAO { + private final BonusNewProductRecipeMapper mapper; + + public int insert(BonusNewProductRecipeDO entity) { + return mapper.insertSelective(entity); + } + + public int insertBatch(List list) { + if (CollectionUtils.isEmpty(list)) { + return 0; + } + return mapper.insertBatch(list); + } + + public List monthlyStatistics(String storeNumOrName, Date startDate, Date endDate, String recipeNoOrName) { + return mapper.monthlyStatistics(storeNumOrName, startDate, endDate, recipeNoOrName); + } + + public List selectListByCondition(String storeId, String recipeNo, Date startDate, Date endDate) { + return mapper.selectListByCondition(storeId, recipeNo, startDate, endDate); + } + + public Map getMapByIds(List ids) { + if (CollectionUtils.isEmpty(ids)) { + return Collections.emptyMap(); + } + Example example = new Example(BonusNewProductRecipeDO.class); + example.createCriteria().andIn("id", ids); + List list = mapper.selectByExample(example); + return CollStreamUtil.toMap(list, BonusNewProductRecipeDO::getId, v -> v); + } + + public void deleteDailyNewProduct(Long ruleId, String storeId, Date payDate) { + Example example = new Example(BonusNewProductRecipeDO.class); + example.createCriteria() + .andEqualTo("ruleId", ruleId) + .andEqualTo("storeId", storeId) + .andEqualTo("payDate", payDate); + mapper.deleteByExample(example); + } +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductRecipeEmployeeDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductRecipeEmployeeDAO.java new file mode 100644 index 000000000..b380569b2 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductRecipeEmployeeDAO.java @@ -0,0 +1,74 @@ +package com.cool.store.dao.bonus; + +import com.alibaba.excel.util.CollectionUtils; +import com.cool.store.entity.bonus.BonusNewProductRecipeEmployeeDO; +import com.cool.store.mapper.bonus.BonusNewProductRecipeEmployeeMapper; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Repository; +import tk.mybatis.mapper.entity.Example; + +import java.util.Date; +import java.util.List; +import java.util.Objects; + +/** + * 新品销售奖金-菜品-员工DAO + * + * @author wangff + * @since 2026/4/21 + */ +@Repository +@RequiredArgsConstructor +public class BonusNewProductRecipeEmployeeDAO { + private final BonusNewProductRecipeEmployeeMapper mapper; + + public int insert(BonusNewProductRecipeEmployeeDO entity) { + return mapper.insertSelective(entity); + } + + public int insertBatch(List list) { + if (CollectionUtils.isEmpty(list)) { + return 0; + } + return mapper.insertBatch(list); + } + + /** + * 月度统计 + */ + public List monthlyStatistics(String storeNumOrName, Date startDate, Date endDate, String rewardUserName, String recipeNoOrName) { + return mapper.monthlyStatistics(storeNumOrName, startDate, endDate, rewardUserName, recipeNoOrName); + } + + public List selectListByCondition(String storeId, String recipeNo, String rewardUserId, Date startDate, Date endDate) { + Example example = new Example(BonusNewProductRecipeEmployeeDO.class); + Example.Criteria criteria = example.createCriteria(); + if (StringUtils.isNotBlank(storeId)) { + criteria.andEqualTo("storeId", storeId); + } + if (StringUtils.isNotBlank(recipeNo)) { + criteria.andEqualTo("recipeNo", recipeNo); + } + if (StringUtils.isNotBlank(rewardUserId)) { + criteria.andEqualTo("rewardUserId", rewardUserId); + } + if (Objects.nonNull(startDate)) { + criteria.andGreaterThanOrEqualTo("payDate", startDate); + } + if (Objects.nonNull(endDate)) { + criteria.andLessThanOrEqualTo("payDate", endDate); + } + example.setOrderByClause("create_time DESC"); + return mapper.selectByExample(example); + } + + public void deleteDailyNewProduct(Long ruleId, String storeId, Date payDate) { + Example example = new Example(BonusNewProductRecipeEmployeeDO.class); + example.createCriteria() + .andEqualTo("ruleId", ruleId) + .andEqualTo("storeId", storeId) + .andEqualTo("payDate", payDate); + mapper.deleteByExample(example); + } +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductStoreDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductStoreDAO.java new file mode 100644 index 000000000..bd8151b13 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusNewProductStoreDAO.java @@ -0,0 +1,51 @@ +package com.cool.store.dao.bonus; + +import cn.hutool.core.collection.CollStreamUtil; +import com.cool.store.entity.bonus.BonusNewProductStoreDO; +import com.cool.store.mapper.bonus.BonusNewProductStoreMapper; +import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Repository; +import tk.mybatis.mapper.entity.Example; + +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 新品销售奖金-门店DAO + * + * @author wangff + * @since 2026/4/21 + */ +@Repository +@RequiredArgsConstructor +public class BonusNewProductStoreDAO { + private final BonusNewProductStoreMapper mapper; + + public int insert(BonusNewProductStoreDO entity) { + return mapper.insertSelective(entity); + } + + public boolean existsByRuleIdAndPayDate(Long ruleId, String payDate) { + return mapper.selectCountByRuleIdAndPayDate(ruleId, payDate) > 0; + } + + public BonusNewProductStoreDO getById(Long id) { + return mapper.selectByPrimaryKey(id); + } + + public List monthlyStatistics(String storeNumOrName, Date startDate, Date endDate, String storeId, Long ruleId) { + return mapper.monthlyStatistics(storeNumOrName, startDate, endDate, storeId, ruleId); + } + + public void deleteDailyNewProduct(Long ruleId, String storeId, Date payDate) { + Example example = new Example(BonusNewProductStoreDO.class); + example.createCriteria() + .andEqualTo("ruleId", ruleId) + .andEqualTo("storeId", storeId) + .andEqualTo("payDate", payDate); + mapper.deleteByExample(example); + } +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusReceivedEmployeeDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusReceivedEmployeeDAO.java new file mode 100644 index 000000000..50f99f0c3 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusReceivedEmployeeDAO.java @@ -0,0 +1,62 @@ +package com.cool.store.dao.bonus; + +import com.cool.store.entity.bonus.BonusReceivedEmployeeDO; +import com.cool.store.mapper.bonus.BonusReceivedEmployeeMapper; +import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Repository; +import tk.mybatis.mapper.entity.Example; + +import java.util.Date; +import java.util.List; + +/** + * 实收奖金发放-员工DAO + * + * @author wangff + * @since 2026/4/21 + */ +@Repository +@RequiredArgsConstructor +public class BonusReceivedEmployeeDAO { + private final BonusReceivedEmployeeMapper mapper; + + public int insert(BonusReceivedEmployeeDO entity) { + return mapper.insertSelective(entity); + } + + public int insertBatch(List list) { + if (CollectionUtils.isEmpty(list)) { + return 0; + } + return mapper.insertBatch(list); + } + + public List selectByReceivedStoreId(Long receivedStoreId) { + return mapper.selectByReceivedStoreId(receivedStoreId); + } + + public BonusReceivedEmployeeDO getById(Long id) { + return mapper.selectByPrimaryKey(id); + } + + public List selectEmployeeListByCondition(String storeNumOrName, Date startMonth, Date endMonth, String rewardUserName, String storeId) { + return mapper.selectEmployeeListByCondition(storeNumOrName, startMonth, endMonth, rewardUserName, storeId); + } + + /** + * 按门店分组统计员工月度实收 + */ + public List getMonthlyStatisticsGroupByStore(String payMonth) { + return mapper.getMonthlyStatisticsGroupByStore(payMonth); + } + + public void deleteMonthlyReceived(Long ruleId, String storeId, Date payDate) { + Example example = new Example(BonusReceivedEmployeeDO.class); + example.createCriteria() + .andEqualTo("ruleId", ruleId) + .andEqualTo("storeId", storeId) + .andEqualTo("payDate", payDate); + mapper.deleteByExample(example); + } +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusReceivedStoreDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusReceivedStoreDAO.java new file mode 100644 index 000000000..1b0e8f3b9 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/bonus/BonusReceivedStoreDAO.java @@ -0,0 +1,62 @@ +package com.cool.store.dao.bonus; + +import cn.hutool.core.collection.CollStreamUtil; +import com.cool.store.entity.bonus.BonusReceivedStoreDO; +import com.cool.store.mapper.bonus.BonusReceivedStoreMapper; +import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Repository; +import tk.mybatis.mapper.entity.Example; + +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 实收奖金发放-门店DAO + * + * @author wangff + * @since 2026/4/21 + */ +@Repository +@RequiredArgsConstructor +public class BonusReceivedStoreDAO { + private final BonusReceivedStoreMapper mapper; + + public int insert(BonusReceivedStoreDO entity) { + return mapper.insertSelective(entity); + } + + public boolean existsByRuleIdAndPayDate(Long ruleId, String payDate) { + return mapper.selectCountByRuleIdAndPayDate(ruleId, payDate) > 0; + } + + public BonusReceivedStoreDO getById(Long id) { + return mapper.selectByPrimaryKey(id); + } + + public List selectListByCondition(String storeNumOrName, Date startMonth, Date endMonth, String storeId) { + return mapper.selectListByCondition(storeNumOrName, startMonth, endMonth, storeId); + } + + public Map getMapByIds(List ids) { + if (CollectionUtils.isEmpty(ids)) { + return Collections.emptyMap(); + } + Example example = new Example(BonusReceivedStoreDO.class); + example.createCriteria() + .andIn("id", ids); + List list = mapper.selectByExample(example); + return CollStreamUtil.toMap(list, BonusReceivedStoreDO::getId, v -> v); + } + + public void deleteMonthlyReceived(Long ruleId, String storeId, Date payDate) { + Example example = new Example(BonusReceivedStoreDO.class); + example.createCriteria() + .andEqualTo("ruleId", ruleId) + .andEqualTo("storeId", storeId) + .andEqualTo("payDate", payDate); + mapper.deleteByExample(example); + } +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/UserAuthMappingMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/UserAuthMappingMapper.java index bd16eeeef..a39b75a94 100644 --- a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/UserAuthMappingMapper.java +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/UserAuthMappingMapper.java @@ -52,6 +52,14 @@ public interface UserAuthMappingMapper { @Param("positionType")String positionType, @Param("notRoleAuth")String notRoleAuth); + /** + * 与标品一致;listUserAuthMappingByAuth方法会查询出运营顾问等角色 + */ + List listUserAuthMappingByAuthV2(@Param("type") String type, + @Param("mappingIdList") List mappingIdList, + @Param("positionType")String positionType, + @Param("notRoleAuth")String notRoleAuth); + List listUserAuthMappingByUserList(@Param("userIdList") List userIdList); diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusDistributionRuleMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusDistributionRuleMapper.java new file mode 100644 index 000000000..45e76f87d --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusDistributionRuleMapper.java @@ -0,0 +1,34 @@ +package com.cool.store.mapper.bonus; + +import com.cool.store.entity.bonus.BonusDistributionRuleDO; +import org.apache.ibatis.annotations.Param; +import tk.mybatis.mapper.common.Mapper; + +import java.util.Date; +import java.util.List; + +public interface BonusDistributionRuleMapper extends Mapper { + + /** + * 门店下相同规则类型的启用规则生效期间有无交集 + * @param storeId 门店id + * @param type 规则类型 + * @param startDate 开始有效日期 + * @param endDate 结束有效日期 + * @return 是否存在 + */ + int existOverlap(@Param("storeId") String storeId, @Param("type") Integer type, @Param("startDate") Date startDate, @Param("endDate") Date endDate); + + /** + * 列表查询 + */ + List getList(@Param("storeNumOrName") String storeNumOrName, + @Param("type") Integer type, + @Param("enable") Integer enable, + @Param("storeId") String storeId); + + /** + * 获取指定类型和生效月份的启用规则列表 + */ + List selectEnabledRulesByTypeAndMonth(@Param("type") Integer type, @Param("payMonth") String payMonth); +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusEmployeeRewardDetailMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusEmployeeRewardDetailMapper.java new file mode 100644 index 000000000..55aebae89 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusEmployeeRewardDetailMapper.java @@ -0,0 +1,28 @@ +package com.cool.store.mapper.bonus; + +import com.cool.store.entity.bonus.BonusEmployeeRewardDetailDO; +import org.apache.ibatis.annotations.Param; +import tk.mybatis.mapper.common.Mapper; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +public interface BonusEmployeeRewardDetailMapper extends Mapper { + + List selectByStoreIdAndPayDate(@Param("storeId") String storeId, + @Param("payDate") String payDate, + @Param("userIds") List userIds); + + int updateReceivedAmountById(@Param("id") Long id, @Param("receivedAmount") BigDecimal receivedAmount); + + int updateNewProjectAmountById(@Param("id") Long id, @Param("newProjectAmount") BigDecimal newProjectAmount); + + int insertOrUpdateBatch(@Param("list") List list); + + List selectListByCondition(@Param("storeNumOrName") String storeNumOrName, + @Param("startDate") Date startDate, + @Param("endDate") Date endDate, + @Param("rewardUserName") String rewardUserName, + @Param("storeId") String storeId); +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductEmployeeMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductEmployeeMapper.java new file mode 100644 index 000000000..dd9c40737 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductEmployeeMapper.java @@ -0,0 +1,46 @@ +package com.cool.store.mapper.bonus; + +import com.cool.store.entity.bonus.BonusNewProductEmployeeDO; +import org.apache.ibatis.annotations.Param; +import tk.mybatis.mapper.common.Mapper; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public interface BonusNewProductEmployeeMapper extends Mapper { + + /** + * 月度统计 + * + * @param storeId 门店id + * @param payDate 发放年月 + * @param userIds 用户id列表 + * @return 实体列表 + */ + List> getMonthlyStatistics(@Param("storeId") String storeId, + @Param("payDate") String payDate, + @Param("userIds") List userIds); + + int insertBatch(@Param("list") List list); + + List monthlyStatistics(@Param("ruleId") Long ruleId, + @Param("storeId") String storeId, + @Param("payDate") Date payDate, + @Param("userId") String userId); + + /** + * 员工列表月度统计 + */ + List employeeMonthlyStatistics(@Param("startDate") Date startDate, + @Param("endDate") Date endDate, + @Param("storeNumOrName") String storeNumOrName, + @Param("rewardUserName") String rewardUserName, + @Param("storeId") String storeId); + + /** + * 按门店分组统计员工月度新品销售 + */ + List getMonthlyStatisticsGroupByStore(@Param("payMonth") String payMonth); +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductRecipeEmployeeMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductRecipeEmployeeMapper.java new file mode 100644 index 000000000..a412648b7 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductRecipeEmployeeMapper.java @@ -0,0 +1,22 @@ +package com.cool.store.mapper.bonus; + +import com.cool.store.entity.bonus.BonusNewProductRecipeEmployeeDO; +import org.apache.ibatis.annotations.Param; +import tk.mybatis.mapper.common.Mapper; + +import java.util.Date; +import java.util.List; + +public interface BonusNewProductRecipeEmployeeMapper extends Mapper { + + int insertBatch(@Param("list") List list); + + /** + * 月度统计 + */ + List monthlyStatistics(@Param("storeNumOrName") String storeNumOrName, + @Param("startDate") Date startDate, + @Param("endDate") Date endDate, + @Param("rewardUserName") String rewardUserName, + @Param("recipeNoOrName") String recipeNoOrName); +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductRecipeMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductRecipeMapper.java new file mode 100644 index 000000000..04ce2e781 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductRecipeMapper.java @@ -0,0 +1,23 @@ +package com.cool.store.mapper.bonus; + +import com.cool.store.entity.bonus.BonusNewProductRecipeDO; +import org.apache.ibatis.annotations.Param; +import tk.mybatis.mapper.common.Mapper; + +import java.util.Date; +import java.util.List; + +public interface BonusNewProductRecipeMapper extends Mapper { + + int insertBatch(@Param("list") List list); + + List monthlyStatistics(@Param("storeNumOrName") String storeNumOrName, + @Param("startDate") Date startDate, + @Param("endDate") Date endDate, + @Param("recipeNoOrName") String recipeNoOrName); + + List selectListByCondition(@Param("storeId") String storeId, + @Param("recipeNo") String recipeNo, + @Param("startDate") Date startDate, + @Param("endDate") Date endDate); +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductStoreMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductStoreMapper.java new file mode 100644 index 000000000..d1cea419d --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusNewProductStoreMapper.java @@ -0,0 +1,20 @@ +package com.cool.store.mapper.bonus; + +import com.cool.store.entity.bonus.BonusNewProductStoreDO; +import org.apache.ibatis.annotations.Param; +import tk.mybatis.mapper.common.Mapper; + +import java.util.Date; +import java.util.List; + +public interface BonusNewProductStoreMapper extends Mapper { + + int selectCountByRuleIdAndPayDate(@Param("ruleId") Long ruleId, @Param("payDate") String payDate); + + List monthlyStatistics(@Param("storeNumOrName") String storeNumOrName, + @Param("startDate") Date startDate, + @Param("endDate") Date endDate, + @Param("storeId") String storeId, + @Param("ruleId") Long ruleId); + +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusReceivedEmployeeMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusReceivedEmployeeMapper.java new file mode 100644 index 000000000..636bdee67 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusReceivedEmployeeMapper.java @@ -0,0 +1,25 @@ +package com.cool.store.mapper.bonus; + +import com.cool.store.entity.bonus.BonusReceivedEmployeeDO; +import org.apache.ibatis.annotations.Param; +import tk.mybatis.mapper.common.Mapper; + +import java.util.Date; +import java.util.List; + +public interface BonusReceivedEmployeeMapper extends Mapper { + int insertBatch(@Param("list") List list); + + List selectByReceivedStoreId(@Param("receivedStoreId") Long receivedStoreId); + + List selectEmployeeListByCondition(@Param("storeNumOrName") String storeNumOrName, + @Param("startMonth") Date startMonth, + @Param("endMonth") Date endMonth, + @Param("rewardUserName") String rewardUserName, + @Param("storeId") String storeId); + + /** + * 按门店分组统计员工月度实收 + */ + List getMonthlyStatisticsGroupByStore(@Param("payMonth") String payMonth); +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusReceivedStoreMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusReceivedStoreMapper.java new file mode 100644 index 000000000..38c4dd3a2 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/bonus/BonusReceivedStoreMapper.java @@ -0,0 +1,18 @@ +package com.cool.store.mapper.bonus; + +import com.cool.store.entity.bonus.BonusReceivedStoreDO; +import org.apache.ibatis.annotations.Param; +import tk.mybatis.mapper.common.Mapper; + +import java.util.Date; +import java.util.List; + +public interface BonusReceivedStoreMapper extends Mapper { + + int selectCountByRuleIdAndPayDate(@Param("ruleId") Long ruleId, @Param("payDate") String payDate); + + List selectListByCondition(@Param("storeNumOrName") String storeNumOrName, + @Param("startMonth") Date startMonth, + @Param("endMonth") Date endMonth, + @Param("storeId") String storeId); +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/resources/mapper/UserAuthMappingMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/UserAuthMappingMapper.xml index c9feb2c04..cd1909ba9 100644 --- a/coolstore-partner-dao/src/main/resources/mapper/UserAuthMappingMapper.xml +++ b/coolstore-partner-dao/src/main/resources/mapper/UserAuthMappingMapper.xml @@ -67,6 +67,36 @@ + + SELECT COUNT(1) FROM bonus_distribution_rule + WHERE store_id = #{storeId} + AND type = #{type} + AND enable = 1 + AND start_date <= #{endDate} + AND end_date >= #{startDate} + + + + + + \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusEmployeeRewardDetailMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusEmployeeRewardDetailMapper.xml new file mode 100644 index 000000000..e5e17a30b --- /dev/null +++ b/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusEmployeeRewardDetailMapper.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + id, store_id, pay_date, reward_user_name, reward_user_id, received_amount, new_project_amount, create_time + + + a.id, a.store_id, a.pay_date, a.reward_user_name, a.reward_user_id, a.received_amount, a.new_project_amount, a.create_time + + + + + + UPDATE bonus_employee_reward_detail SET received_amount = #{receivedAmount} WHERE id = #{id} + + + + UPDATE bonus_employee_reward_detail SET new_project_amount = #{newProjectAmount} WHERE id = #{id} + + + + INSERT INTO bonus_employee_reward_detail (store_id, pay_date, reward_user_name, reward_user_id, received_amount, new_project_amount) VALUES + + (#{item.storeId}, #{item.payDate}, #{item.rewardUserName}, #{item.rewardUserId}, #{item.receivedAmount}, #{item.newProjectAmount}) + + ON DUPLICATE KEY UPDATE + received_amount = VALUES(received_amount), + new_project_amount = VALUES(new_project_amount) + + + + \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductEmployeeMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductEmployeeMapper.xml new file mode 100644 index 000000000..d416db290 --- /dev/null +++ b/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductEmployeeMapper.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + INSERT INTO bonus_new_product_employee (product_store_id, rule_id, store_id, pay_date, reward_ratio, reward_amount, reward_user_name, reward_user_id) VALUES + + (#{item.productStoreId}, #{item.ruleId}, #{item.storeId}, #{item.payDate}, #{item.rewardRatio}, #{item.rewardAmount}, #{item.rewardUserName}, #{item.rewardUserId}) + + + + + + + + + \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductRecipeEmployeeMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductRecipeEmployeeMapper.xml new file mode 100644 index 000000000..c7344865a --- /dev/null +++ b/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductRecipeEmployeeMapper.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + insert into bonus_new_product_recipe_employee (id, product_recipe_id, rule_id, store_id, pay_date, recipe_no, recipe_name, basic_reward_amount, excess_reward_amount, reward_ratio, reward_user_name, reward_user_id, sales_volume) + values + + (#{item.id}, #{item.productRecipeId}, #{item.ruleId}, #{item.storeId}, #{item.payDate}, #{item.recipeNo}, #{item.recipeName}, #{item.basicRewardAmount}, #{item.excessRewardAmount}, #{item.rewardRatio}, #{item.rewardUserName}, #{item.rewardUserId}, #{item.salesVolume}) + + + + + \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductRecipeMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductRecipeMapper.xml new file mode 100644 index 000000000..1fa903709 --- /dev/null +++ b/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductRecipeMapper.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + id, rule_id, store_id, pay_date, recipe_no, recipe_name, min_standard_num, reward_amount, excess_standard_num, excess_amount, sales_volume, basic_reward_amount, excess_reward_amount, create_time + + + + INSERT INTO bonus_new_product_recipe (rule_id, store_id, pay_date, recipe_no, recipe_name, min_standard_num, reward_amount, excess_standard_num, excess_amount, sales_volume, basic_reward_amount, excess_reward_amount) VALUES + + (#{item.ruleId}, #{item.storeId}, #{item.payDate}, #{item.recipeNo}, #{item.recipeName}, #{item.minStandardNum}, #{item.rewardAmount}, #{item.excessStandardNum}, #{item.excessAmount}, #{item.salesVolume}, #{item.basicRewardAmount}, #{item.excessRewardAmount}) + + + + + + + \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductStoreMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductStoreMapper.xml new file mode 100644 index 000000000..15636b336 --- /dev/null +++ b/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusNewProductStoreMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusReceivedEmployeeMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusReceivedEmployeeMapper.xml new file mode 100644 index 000000000..3bb9a63ec --- /dev/null +++ b/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusReceivedEmployeeMapper.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + INSERT INTO bonus_received_employee(received_store_id, rule_id, store_id, pay_date, reward_ratio, received_amount, reward_user_name, reward_user_id) + VALUES + + (#{item.receivedStoreId}, #{item.ruleId}, #{item.storeId}, #{item.payDate}, #{item.rewardRatio}, #{item.receivedAmount}, #{item.rewardUserName}, #{item.rewardUserId}) + + + + + + + + + \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusReceivedStoreMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusReceivedStoreMapper.xml new file mode 100644 index 000000000..f191aa23a --- /dev/null +++ b/coolstore-partner-dao/src/main/resources/mapper/bonus/BonusReceivedStoreMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusDistributionRuleDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusDistributionRuleDO.java new file mode 100644 index 000000000..9b4adbc19 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusDistributionRuleDO.java @@ -0,0 +1,90 @@ +package com.cool.store.entity.bonus; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; +import javax.persistence.*; + +/** + * 奖金发放规则 + */ +@Data +@Table(name = "bonus_distribution_rule") +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BonusDistributionRuleDO { + /** + * id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** + * 规则类型,1-实收 2-新品销售 + */ + private Integer type; + + /** + * 门店id + */ + @Column(name = "store_id") + private String storeId; + + /** + * 生效开始年月 + */ + @Column(name = "start_date") + private Date startDate; + + /** + * 生效结束年月 + */ + @Column(name = "end_date") + private Date endDate; + + /** + * 创建时间 + */ + @Column(name = "create_time") + private Date createTime; + + /** + * 创建人id + */ + @Column(name = "create_user_id") + private String createUserId; + + /** + * 更新时间 + */ + @Column(name = "update_time") + private Date updateTime; + + /** + * 更新人id + */ + @Column(name = "update_user_id") + private String updateUserId; + + /** + * 奖金规则配置 + */ + @Column(name = "bonus_config") + private String bonusConfig; + + /** + * 分配规则配置 + */ + @Column(name = "distribute_config") + private String distributeConfig; + + /** + * 是否启用,0否1是 + */ + private Integer enable; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusEmployeeRewardDetailDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusEmployeeRewardDetailDO.java new file mode 100644 index 000000000..2fb4d61b3 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusEmployeeRewardDetailDO.java @@ -0,0 +1,63 @@ +package com.cool.store.entity.bonus; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import javax.persistence.*; + +/** + * 员工奖励明细 + */ +@Data +@Table(name = "bonus_employee_reward_detail") +public class BonusEmployeeRewardDetailDO { + /** + * id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** + * 门店id + */ + @Column(name = "store_id") + private String storeId; + + /** + * 发放年月 + */ + @Column(name = "pay_date") + private Date payDate; + + /** + * 奖励人姓名 + */ + @Column(name = "reward_user_name") + private String rewardUserName; + + /** + * 奖励人id + */ + @Column(name = "reward_user_id") + private String rewardUserId; + + /** + * 实收奖励金额 + */ + @Column(name = "received_amount") + private BigDecimal receivedAmount; + + /** + * 新品销售奖励金额 + */ + @Column(name = "new_project_amount") + private BigDecimal newProjectAmount; + + /** + * 创建时间 + */ + @Column(name = "create_time") + private Date createTime; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductEmployeeDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductEmployeeDO.java new file mode 100644 index 000000000..7ca13ac16 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductEmployeeDO.java @@ -0,0 +1,75 @@ +package com.cool.store.entity.bonus; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import javax.persistence.*; + +/** + * 新品销售奖金-员工 + */ +@Data +@Table(name = "bonus_new_product_employee") +public class BonusNewProductEmployeeDO { + /** + * id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** + * bonus_new_product_store.id + */ + @Column(name = "product_store_id") + private Long productStoreId; + + /** + * 规则id + */ + @Column(name = "rule_id") + private Long ruleId; + + /** + * 门店id + */ + @Column(name = "store_id") + private String storeId; + + /** + * 发放年月日 + */ + @Column(name = "pay_date") + private Date payDate; + + /** + * 奖励比例(%) + */ + @Column(name = "reward_ratio") + private BigDecimal rewardRatio; + + /** + * 奖励金额 + */ + @Column(name = "reward_amount") + private BigDecimal rewardAmount; + + /** + * 奖励人姓名 + */ + @Column(name = "reward_user_name") + private String rewardUserName; + + /** + * 奖励人id + */ + @Column(name = "reward_user_id") + private String rewardUserId; + + /** + * 创建时间 + */ + @Column(name = "create_time") + private Date createTime; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductRecipeDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductRecipeDO.java new file mode 100644 index 000000000..f6a9bc902 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductRecipeDO.java @@ -0,0 +1,99 @@ +package com.cool.store.entity.bonus; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import javax.persistence.*; + +/** + * 新品销售奖金-菜品 + */ +@Data +@Table(name = "bonus_new_product_recipe") +public class BonusNewProductRecipeDO { + /** + * id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** + * 规则id + */ + @Column(name = "rule_id") + private Long ruleId; + + /** + * 门店id + */ + @Column(name = "store_id") + private String storeId; + + /** + * 发放年月日 + */ + @Column(name = "pay_date") + private Date payDate; + + /** + * 菜品编码 + */ + @Column(name = "recipe_no") + private String recipeNo; + + /** + * 菜品名称 + */ + @Column(name = "recipe_name") + private String recipeName; + + /** + * 日销量奖励最低达标数量 + */ + @Column(name = "min_standard_num") + private Integer minStandardNum; + + /** + * 销售奖励(元/个) + */ + @Column(name = "reward_amount") + private BigDecimal rewardAmount; + + /** + * 日销量超额奖励基数 + */ + @Column(name = "excess_standard_num") + private Integer excessStandardNum; + + /** + * 超额后额外销售奖励(元/个) + */ + @Column(name = "excess_amount") + private BigDecimal excessAmount; + + /** + * 销量 + */ + @Column(name = "sales_volume") + private Integer salesVolume; + + /** + * 基础奖金 + */ + @Column(name = "basic_reward_amount") + private BigDecimal basicRewardAmount; + + /** + * 超额奖金 + */ + @Column(name = "excess_reward_amount") + private BigDecimal excessRewardAmount; + + /** + * 创建时间 + */ + @Column(name = "create_time") + private Date createTime; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductRecipeEmployeeDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductRecipeEmployeeDO.java new file mode 100644 index 000000000..a8ea0d1ae --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductRecipeEmployeeDO.java @@ -0,0 +1,99 @@ +package com.cool.store.entity.bonus; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import javax.persistence.*; + +/** + * 新品销售奖金-菜品-员工 + */ +@Data +@Table(name = "bonus_new_product_recipe_employee") +public class BonusNewProductRecipeEmployeeDO { + /** + * id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** + * bonus_new_product_recipe.id + */ + @Column(name = "product_recipe_id") + private Long productRecipeId; + + /** + * 规则id + */ + @Column(name = "rule_id") + private Long ruleId; + + /** + * 门店id + */ + @Column(name = "store_id") + private String storeId; + + /** + * 发放年月日 + */ + @Column(name = "pay_date") + private Date payDate; + + /** + * 菜品编码 + */ + @Column(name = "recipe_no") + private String recipeNo; + + /** + * 菜品名称 + */ + @Column(name = "recipe_name") + private String recipeName; + + /** + * 销量 + */ + @Column(name = "sales_volume") + private Integer salesVolume; + + /** + * 基础奖金 + */ + @Column(name = "basic_reward_amount") + private BigDecimal basicRewardAmount; + + /** + * 超额奖金 + */ + @Column(name = "excess_reward_amount") + private BigDecimal excessRewardAmount; + + /** + * 奖励比例(%) + */ + @Column(name = "reward_ratio") + private BigDecimal rewardRatio; + + /** + * 奖励人姓名 + */ + @Column(name = "reward_user_name") + private String rewardUserName; + + /** + * 奖励人id + */ + @Column(name = "reward_user_id") + private String rewardUserId; + + /** + * 创建时间 + */ + @Column(name = "create_time") + private Date createTime; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductStoreDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductStoreDO.java new file mode 100644 index 000000000..1161e1863 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusNewProductStoreDO.java @@ -0,0 +1,51 @@ +package com.cool.store.entity.bonus; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import javax.persistence.*; + +/** + * 新品销售奖金-门店 + */ +@Data +@Table(name = "bonus_new_product_store") +public class BonusNewProductStoreDO { + /** + * id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** + * 规则id + */ + @Column(name = "rule_id") + private Long ruleId; + + /** + * 门店id + */ + @Column(name = "store_id") + private String storeId; + + /** + * 发放月份 + */ + @Column(name = "pay_date") + private Date payDate; + + /** + * 奖金总计 + */ + @Column(name = "amount_total") + private BigDecimal amountTotal; + + /** + * 创建时间 + */ + @Column(name = "create_time") + private Date createTime; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusReceivedEmployeeDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusReceivedEmployeeDO.java new file mode 100644 index 000000000..523f2724c --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusReceivedEmployeeDO.java @@ -0,0 +1,75 @@ +package com.cool.store.entity.bonus; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import javax.persistence.*; + +/** + * 实收奖金发放-员工 + */ +@Data +@Table(name = "bonus_received_employee") +public class BonusReceivedEmployeeDO { + /** + * id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** + * bonus_received_store.id + */ + @Column(name = "received_store_id") + private Long receivedStoreId; + + /** + * 规则id + */ + @Column(name = "rule_id") + private Long ruleId; + + /** + * 门店id + */ + @Column(name = "store_id") + private String storeId; + + /** + * 发放月份 + */ + @Column(name = "pay_date") + private Date payDate; + + /** + * 奖励比例(%) + */ + @Column(name = "reward_ratio") + private BigDecimal rewardRatio; + + /** + * 实收奖励金额 + */ + @Column(name = "received_amount") + private BigDecimal receivedAmount; + + /** + * 奖励人姓名 + */ + @Column(name = "reward_user_name") + private String rewardUserName; + + /** + * 奖励人id + */ + @Column(name = "reward_user_id") + private String rewardUserId; + + /** + * 创建时间 + */ + @Column(name = "create_time") + private Date createTime; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusReceivedStoreDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusReceivedStoreDO.java new file mode 100644 index 000000000..30a04d64b --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/bonus/BonusReceivedStoreDO.java @@ -0,0 +1,75 @@ +package com.cool.store.entity.bonus; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import javax.persistence.*; + +/** + * 实收奖金发放-门店 + */ +@Data +@Table(name = "bonus_received_store") +public class BonusReceivedStoreDO { + /** + * id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** + * 规则id + */ + @Column(name = "rule_id") + private Long ruleId; + + /** + * 门店id + */ + @Column(name = "store_id") + private String storeId; + + /** + * 发放月份 + */ + @Column(name = "pay_date") + private Date payDate; + + /** + * 月度实收 + */ + @Column(name = "received_monthly") + private BigDecimal receivedMonthly; + + /** + * 月度营业天数 + */ + @Column(name = "business_days") + private Integer businessDays; + + /** + * 日均实收 + */ + @Column(name = "received_daily") + private BigDecimal receivedDaily; + + /** + * 上月日均实收 + */ + @Column(name = "received_daily_last") + private BigDecimal receivedDailyLast; + + /** + * 奖金总计 + */ + @Column(name = "amount_total") + private BigDecimal amountTotal; + + /** + * 创建时间 + */ + @Column(name = "create_time") + private Date createTime; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductComputeRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductComputeRequest.java new file mode 100644 index 000000000..6aafa20c1 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductComputeRequest.java @@ -0,0 +1,33 @@ +package com.cool.store.request.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; +import java.util.List; + +/** + *

+ * 新品销售试算 + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class BonusProductComputeRequest { + @ApiModelProperty("菜品销量") + @NotEmpty(message = "菜品销量不能为空") + private List recipeSales; + + @ApiModelProperty("新品销售奖金规则配置(新品销售必填)") + @NotEmpty(message = "新品销售奖金规则配置不能为空") + @Valid + private List productConfigs; + + @ApiModelProperty("分配规则") + @NotEmpty(message = "分配规则不能为空") + @Valid + private List distributeConfigs; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductEmployeeQueryRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductEmployeeQueryRequest.java new file mode 100644 index 000000000..a9dde9b24 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductEmployeeQueryRequest.java @@ -0,0 +1,36 @@ +package com.cool.store.request.bonus; + +import com.cool.store.common.PageBasicInfo; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + *

+ * 员工新品查询Request + *

+ * + * @author wangff + * @since 2026/4/23 + */ +@Data +public class BonusProductEmployeeQueryRequest extends PageBasicInfo { + @ApiModelProperty("门店编码/名称") + private String storeNumOrName; + + @ApiModelProperty("开始日期") + private Date startDate; + + @ApiModelProperty("结束日期") + private Date endDate; + + @ApiModelProperty("奖励人姓名") + private String rewardUserName; + + @ApiModelProperty("菜品编码或名称") + private String recipeNoOrName; + + @ApiModelProperty("门店id") + private String storeId; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductMonthlyQueryRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductMonthlyQueryRequest.java new file mode 100644 index 000000000..3fd8a1cfc --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductMonthlyQueryRequest.java @@ -0,0 +1,33 @@ +package com.cool.store.request.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + *

+ * 新品销售月度查询Request + *

+ * + * @author wangff + * @since 2026/4/22 + */ +@Data +public class BonusProductMonthlyQueryRequest { + @ApiModelProperty("规则id") + private Long ruleId; + + @ApiModelProperty("门店id") + @NotBlank(message = "门店id不能为空") + private String storeId; + + @ApiModelProperty("发放月份") + @NotNull(message = "发放月份不能为空") + private Date payDate; + + @ApiModelProperty("奖励人id") + private String rewardUserId; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductQueryRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductQueryRequest.java new file mode 100644 index 000000000..262c4e3c2 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductQueryRequest.java @@ -0,0 +1,29 @@ +package com.cool.store.request.bonus; + +import com.cool.store.common.PageBasicInfo; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * 门店新品销售奖金发放列表查询请求 + * + * @author wangff + * @since 2026/4/22 + */ +@Data +public class BonusProductQueryRequest extends PageBasicInfo { + + @ApiModelProperty("门店编码/名称") + private String storeNumOrName; + + @ApiModelProperty("开始日期") + private Date startDate; + + @ApiModelProperty("结束日期") + private Date endDate; + + @ApiModelProperty("菜品编码或名称") + private String recipeNoOrName; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductRecipeCompute.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductRecipeCompute.java new file mode 100644 index 000000000..44db47aee --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductRecipeCompute.java @@ -0,0 +1,29 @@ +package com.cool.store.request.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + *

+ * 新品销售试算菜品 + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BonusProductRecipeCompute { + @ApiModelProperty("菜品编码") + @NotNull(message = "菜品编码不能为空") + private String recipeNo; + + @ApiModelProperty("销量") + @NotNull(message = "销量不能为空") + private Integer salesVolume; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductRecipeEmployeeQueryRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductRecipeEmployeeQueryRequest.java new file mode 100644 index 000000000..b461326ab --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductRecipeEmployeeQueryRequest.java @@ -0,0 +1,37 @@ +package com.cool.store.request.bonus; + +import com.cool.store.common.PageBasicInfo; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + *

+ * 门店菜品员工查询Request + *

+ * + * @author wangff + * @since 2026/4/23 + */ +@Data +public class BonusProductRecipeEmployeeQueryRequest extends PageBasicInfo { + @ApiModelProperty("门店id") + @NotBlank(message = "门店id不能为空") + private String storeId; + + @ApiModelProperty("菜品编码") + private String recipeNo; + + @ApiModelProperty("奖励人id") + @NotNull(message = "奖励人id不能为空") + private String rewardUserId; + + @ApiModelProperty("开始日期") + private Date startDate; + + @ApiModelProperty("结束日期") + private Date endDate; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductRecipeQueryRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductRecipeQueryRequest.java new file mode 100644 index 000000000..609fa5f9f --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusProductRecipeQueryRequest.java @@ -0,0 +1,34 @@ +package com.cool.store.request.bonus; + +import com.cool.store.common.PageBasicInfo; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + *

+ * 门店菜品查询Request + *

+ * + * @author wangff + * @since 2026/4/22 + */ +@Data +public class BonusProductRecipeQueryRequest extends PageBasicInfo { + @ApiModelProperty("门店id") + @NotBlank(message = "门店id不能为空") + private String storeId; + + @ApiModelProperty("菜品编码") + @NotNull(message = "菜品编码不能为空") + private String recipeNo; + + @ApiModelProperty("开始日期") + private Date startDate; + + @ApiModelProperty("结束日期") + private Date endDate; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusReceivedComputeRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusReceivedComputeRequest.java new file mode 100644 index 000000000..61cfe2152 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusReceivedComputeRequest.java @@ -0,0 +1,43 @@ +package com.cool.store.request.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.util.List; + +/** + *

+ * 月度实收试算 + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class BonusReceivedComputeRequest { + @ApiModelProperty("月度实收") + @NotNull(message = "月度实收不能为空") + private BigDecimal receivedMonthly; + + @ApiModelProperty("月度营业天数") + @NotNull(message = "月度营业天数不能为空") + private Integer businessDays; + + @ApiModelProperty("日均实收小于等于该值不发放奖金(实收必填)") + @NotNull(message = "日均实收小于等于该值不发放奖金(实收必填)不能为空") + private BigDecimal receivedStart; + + @ApiModelProperty("实收奖励规则配置(实收必填)") + @NotNull(message = "实收奖励规则配置(实收必填)不能为空") + @Valid + private List receivedConfigs; + + @ApiModelProperty("分配规则") + @NotNull(message = "分配规则不能为空") + @Valid + private List distributeConfigs; + +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusReceivedEmployeeQueryRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusReceivedEmployeeQueryRequest.java new file mode 100644 index 000000000..b666ddb96 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusReceivedEmployeeQueryRequest.java @@ -0,0 +1,32 @@ +package com.cool.store.request.bonus; + +import com.cool.store.common.PageBasicInfo; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * 员工实收奖金发放列表查询请求 + * + * @author wangff + * @since 2026/4/22 + */ +@Data +public class BonusReceivedEmployeeQueryRequest extends PageBasicInfo { + + @ApiModelProperty("门店编码/名称") + private String storeNumOrName; + + @ApiModelProperty("开始年月") + private Date startMonth; + + @ApiModelProperty("结束年月") + private Date endMonth; + + @ApiModelProperty("奖励人姓名") + private String rewardUserName; + + @ApiModelProperty("门店id") + private String storeId; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusReceivedStoreQueryRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusReceivedStoreQueryRequest.java new file mode 100644 index 000000000..6794621c5 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusReceivedStoreQueryRequest.java @@ -0,0 +1,29 @@ +package com.cool.store.request.bonus; + +import com.cool.store.common.PageBasicInfo; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * 门店实收奖金发放列表查询请求 + * + * @author wangff + * @since 2026/4/22 + */ +@Data +public class BonusReceivedStoreQueryRequest extends PageBasicInfo { + + @ApiModelProperty("门店编码/名称") + private String storeNumOrName; + + @ApiModelProperty("开始年月") + private Date startMonth; + + @ApiModelProperty("结束年月") + private Date endMonth; + + @ApiModelProperty("门店id") + private String storeId; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleAddRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleAddRequest.java new file mode 100644 index 000000000..d002aa905 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleAddRequest.java @@ -0,0 +1,35 @@ +package com.cool.store.request.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + *

+ * 奖金发放规则新增Request + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class BonusRuleAddRequest { + @ApiModelProperty("门店id") + @NotBlank(message = "门店id不能为空") + private String storeId; + + @ApiModelProperty("规则类型,1-实收 2-新品销售") + @NotNull(message = "规则类型不能为空") + private Integer type; + + @ApiModelProperty("生效开始年月") + @NotNull(message = "生效开始年月不能为空") + private Date startDate; + + @ApiModelProperty("生效结束年月") + @NotNull(message = "生效结束年月不能为空") + private Date endDate; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleDistributeConfig.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleDistributeConfig.java new file mode 100644 index 000000000..abfbb3058 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleDistributeConfig.java @@ -0,0 +1,26 @@ +package com.cool.store.request.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + *

+ * 分配规则 + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class BonusRuleDistributeConfig { + @ApiModelProperty("奖励人id") + private String rewardUserId; + + @ApiModelProperty("奖励人姓名") + private String rewardUserName; + + @ApiModelProperty("奖励比例(%)") + private BigDecimal rewardRatio; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleEnableRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleEnableRequest.java new file mode 100644 index 000000000..7f26da885 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleEnableRequest.java @@ -0,0 +1,25 @@ +package com.cool.store.request.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + *

+ * 奖金发放规则启用Request + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class BonusRuleEnableRequest { + @ApiModelProperty("规则id") + @NotNull(message = "规则id不能为空") + private Long id; + + @ApiModelProperty("是否启用,0否1是") + @NotNull(message = "是否启用不能为空") + private Integer enable; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleProductConfig.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleProductConfig.java new file mode 100644 index 000000000..bdbae7242 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleProductConfig.java @@ -0,0 +1,35 @@ +package com.cool.store.request.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + *

+ * 新品销售规则配置 + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class BonusRuleProductConfig { + @ApiModelProperty("菜品编码") + private String recipeNo; + + @ApiModelProperty("菜品名称") + private String recipeName; + + @ApiModelProperty("日销量奖励最低达标数量") + private Integer minStandardNum; + + @ApiModelProperty("销售奖励(元/个)") + private BigDecimal rewardAmount; + + @ApiModelProperty("日销量超额奖励基数") + private Integer excessStandardNum; + + @ApiModelProperty("超额后额外销售奖励(元/个)") + private BigDecimal excessAmount; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleQueryRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleQueryRequest.java new file mode 100644 index 000000000..f5c5849cd --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleQueryRequest.java @@ -0,0 +1,29 @@ +package com.cool.store.request.bonus; + +import com.cool.store.common.PageBasicInfo; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + *

+ * 规则查询Request + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class BonusRuleQueryRequest extends PageBasicInfo { + @ApiModelProperty("门店编码或名称") + private String storeNumOrName; + + @ApiModelProperty("规则类型,1-实收 2-新品销售") + private Integer type; + + @ApiModelProperty("是否启用,0否1是") + private Integer enable; + + @ApiModelProperty("门店id") + private String storeId; + +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleReceivedConfig.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleReceivedConfig.java new file mode 100644 index 000000000..c05f5313b --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleReceivedConfig.java @@ -0,0 +1,30 @@ +package com.cool.store.request.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +/** + *

+ * 实收规则 + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class BonusRuleReceivedConfig { + @ApiModelProperty("实收小于等于") + @NotNull(message = "实收小于等于不能为空") + private BigDecimal le; + + @ApiModelProperty("实收大于") + @NotNull(message = "实收大于不能为空") + private BigDecimal gt; + + @ApiModelProperty("奖励比例(%)") + @NotNull(message = "奖励比例不能为空") + private BigDecimal rewardRatio; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleUpdateRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleUpdateRequest.java new file mode 100644 index 000000000..2e7fd4f07 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/bonus/BonusRuleUpdateRequest.java @@ -0,0 +1,47 @@ +package com.cool.store.request.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + *

+ * 奖金发放规则编辑Request + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class BonusRuleUpdateRequest { + + @ApiModelProperty("id") + @NotNull(message = "id不能为空") + private Long id; + + @ApiModelProperty("生效开始年月") + @NotNull(message = "生效开始年月不能为空") + private Date startDate; + + @ApiModelProperty("生效结束年月") + @NotNull(message = "生效结束年月不能为空") + private Date endDate; + + @ApiModelProperty("日均实收小于等于该值不发放奖金(实收必填)") + private BigDecimal receivedStart; + + @ApiModelProperty("实收奖励规则配置(实收必填)") + private List receivedConfigs; + + @ApiModelProperty("新品销售奖金规则配置(新品销售必填)") + private List productConfigs; + + @ApiModelProperty("分配规则") + @NotEmpty(message = "分配规则不能为空") + private List distributeConfigs; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/storeopen/StoreMonthRevenueRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/storeopen/StoreMonthRevenueRequest.java new file mode 100644 index 000000000..8d3f75874 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/storeopen/StoreMonthRevenueRequest.java @@ -0,0 +1,27 @@ +package com.cool.store.request.storeopen; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 门店月营收请求 + * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class StoreMonthRevenueRequest { + @ApiModelProperty("门店编码") + @NotBlank(message = "门店编码不能为空") + private String storeNum; + + @ApiModelProperty("开始月份,格式yyyy-MM") + @NotBlank(message = "开始月份不能为空") + private String startDate; + + @ApiModelProperty("结束月份,格式yyyy-MM") + @NotBlank(message = "结束月份不能为空") + private String endDate; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/storeopen/StoreRecipeDailySalesRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/storeopen/StoreRecipeDailySalesRequest.java new file mode 100644 index 000000000..abc0a269b --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/storeopen/StoreRecipeDailySalesRequest.java @@ -0,0 +1,27 @@ +package com.cool.store.request.storeopen; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 门店菜品日销量请求 + * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class StoreRecipeDailySalesRequest { + @ApiModelProperty("门店编码") + @NotBlank(message = "门店编码不能为空") + private String storeNum; + + @ApiModelProperty("开始日期,格式yyyy-MM-dd") + @NotBlank(message = "开始日期不能为空") + private String startDate; + + @ApiModelProperty("结束日期,格式yyyy-MM-dd") + @NotBlank(message = "结束日期不能为空") + private String endDate; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/storeopen/StoreRecipesRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/storeopen/StoreRecipesRequest.java new file mode 100644 index 000000000..3062d2ed5 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/storeopen/StoreRecipesRequest.java @@ -0,0 +1,19 @@ +package com.cool.store.request.storeopen; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 门店菜品种类请求 + * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class StoreRecipesRequest { + @ApiModelProperty("门店编码") + @NotBlank(message = "门店编码不能为空") + private String storeNum; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreMonthRevenueResponse.java b/coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreMonthRevenueResponse.java new file mode 100644 index 000000000..70ae1e44b --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreMonthRevenueResponse.java @@ -0,0 +1,41 @@ +package com.cool.store.response.storeopen; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 门店月营收响应 + * + * @author wangff + * @since 2026/4/20 + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class StoreMonthRevenueResponse { + /** + * 月份,格式yyyy-MM + */ + private String date; + + /** + * 月度实收 + */ + private BigDecimal receivedAmount; + + /** + * 月度营业天数 + */ + private Integer businessDays; + + /** + * 当月日均实收 + */ + private BigDecimal receivedAmountDaily; + + /** + * 上月日均实收 + */ + private BigDecimal receivedAmountDailyLastMonth; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreOpenApiResponse.java b/coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreOpenApiResponse.java new file mode 100644 index 000000000..98a2028be --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreOpenApiResponse.java @@ -0,0 +1,18 @@ +package com.cool.store.response.storeopen; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +/** + * 门店开放数据API通用响应 + * + * @author wangff + * @since 2026/4/20 + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class StoreOpenApiResponse { + private Integer code; + private String msg; + private T data; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreRecipeDailySalesResponse.java b/coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreRecipeDailySalesResponse.java new file mode 100644 index 000000000..c5c45657d --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreRecipeDailySalesResponse.java @@ -0,0 +1,34 @@ +package com.cool.store.response.storeopen; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +/** + * 门店菜品日销量响应 + * + * @author wangff + * @since 2026/4/20 + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class StoreRecipeDailySalesResponse { + /** + * 日期,格式yyyy-MM-dd + */ + private String date; + + /** + * 日销售量 + */ + private Integer sales; + + /** + * 菜品编码 + */ + private String recipeNo; + + /** + * 菜品名称 + */ + private String recipeName; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreRecipesResponse.java b/coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreRecipesResponse.java new file mode 100644 index 000000000..cda68f0a3 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/response/storeopen/StoreRecipesResponse.java @@ -0,0 +1,24 @@ +package com.cool.store.response.storeopen; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +/** + * 门店菜品种类响应 + * + * @author wangff + * @since 2026/4/20 + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class StoreRecipesResponse { + /** + * 菜品编码 + */ + private String recipeNo; + + /** + * 菜品名称 + */ + private String recipeName; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusBasicVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusBasicVO.java new file mode 100644 index 000000000..2f2751af3 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusBasicVO.java @@ -0,0 +1,24 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + *

+ * 基础信息VO + *

+ * + * @author wangff + * @since 2026/4/23 + */ +@Data +public class BonusBasicVO { + @ApiModelProperty("门店id") + private String storeId; + + @ApiModelProperty("门店编码") + private String storeNum; + + @ApiModelProperty("门店名称") + private String storeName; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusComputeUserVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusComputeUserVO.java new file mode 100644 index 000000000..ec5de9fa4 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusComputeUserVO.java @@ -0,0 +1,45 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + *

+ * 实算用户金额VO + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BonusComputeUserVO { + @ApiModelProperty("奖励金额") + private BigDecimal rewardAmount; + + @ApiModelProperty("奖励人id") + private String rewardUserId; + + @ApiModelProperty("奖励人姓名") + private String rewardUserName; + + @ApiModelProperty("基础奖金") + private BigDecimal basicRewardAmount; + + @ApiModelProperty("超额奖金") + private BigDecimal excessRewardAmount; + + @ApiModelProperty("奖励比例(%)") + private BigDecimal rewardRatio; + + public BonusComputeUserVO(BigDecimal rewardAmount, String rewardUserId, String rewardUserName) { + this.rewardAmount = rewardAmount; + this.rewardUserName = rewardUserName; + this.rewardUserId = rewardUserId; + } +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusEmployeeDetailVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusEmployeeDetailVO.java new file mode 100644 index 000000000..6997bdd44 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusEmployeeDetailVO.java @@ -0,0 +1,33 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 员工奖金明细 + *

+ * + * @author wangff + * @since 2026/4/23 + */ +@Data +public class BonusEmployeeDetailVO extends BonusBasicVO { + @ApiModelProperty("发放年月") + private Date payDate; + + @ApiModelProperty("奖励人姓名") + private String rewardUserName; + + @ApiModelProperty("奖励人id") + private String rewardUserId; + + @ApiModelProperty("实收奖励金额") + private BigDecimal receivedAmount; + + @ApiModelProperty("新品销售奖励金额") + private BigDecimal newProjectAmount; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductComputeVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductComputeVO.java new file mode 100644 index 000000000..f147afdf2 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductComputeVO.java @@ -0,0 +1,27 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + *

+ * 新品销售实算VO + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BonusProductComputeVO { + @ApiModelProperty("菜品信息") + private List recipes; + + @ApiModelProperty("明细(员工级)") + private List detail; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductEmployeeListVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductEmployeeListVO.java new file mode 100644 index 000000000..5c1e7a44f --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductEmployeeListVO.java @@ -0,0 +1,30 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 门店新品销售奖金方法列表-员工 + *

+ * + * @author wangff + * @since 2026/4/23 + */ +@Data +public class BonusProductEmployeeListVO extends BonusBasicVO { + @ApiModelProperty("发放年月") + private Date payDate; + + @ApiModelProperty("奖励金额") + private BigDecimal receivedAmount; + + @ApiModelProperty("奖励人id") + private String rewardUserId; + + @ApiModelProperty("奖励人姓名") + private String rewardUserName; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeComputeVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeComputeVO.java new file mode 100644 index 000000000..4328c4e25 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeComputeVO.java @@ -0,0 +1,48 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + *

+ * 新品销售菜品实算VO + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class BonusProductRecipeComputeVO { + @ApiModelProperty("菜品编码") + private String recipeNo; + + @ApiModelProperty("菜品名称") + private String recipeName; + + @ApiModelProperty("日销量奖励最低达标数量") + private Integer minStandardNum; + + @ApiModelProperty("销售奖励(元/个)") + private BigDecimal rewardAmount; + + @ApiModelProperty("日销量超额奖励基数") + private Integer excessStandardNum; + + @ApiModelProperty("超额后额外销售奖励(元/个)") + private BigDecimal excessAmount; + + @ApiModelProperty("销量") + private Integer salesVolume; + + @ApiModelProperty("基础奖金") + private BigDecimal basicRewardAmount; + + @ApiModelProperty("超额奖金") + private BigDecimal excessRewardAmount; + + @ApiModelProperty("明细(员工-菜品级)") + private List detail; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeDetailVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeDetailVO.java new file mode 100644 index 000000000..f0437198a --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeDetailVO.java @@ -0,0 +1,49 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 门店新品销售奖金发放详情-菜品 + *

+ * + * @author wangff + * @since 2026/4/22 + */ +@Data +public class BonusProductRecipeDetailVO extends BonusBasicVO { + + @ApiModelProperty("菜品编码") + private String recipeNo; + + @ApiModelProperty("菜品名称") + private String recipeName; + + @ApiModelProperty("发放日期") + private Date payDate; + + @ApiModelProperty("日销量奖励最低达标数量") + private Integer minStandardNum; + + @ApiModelProperty("销售奖励(元/个)") + private BigDecimal rewardAmount; + + @ApiModelProperty("日销量超额奖励基数") + private Integer excessStandardNum; + + @ApiModelProperty("超额后额外销售奖励(元/个)") + private BigDecimal excessAmount; + + @ApiModelProperty("销量") + private Integer salesVolume; + + @ApiModelProperty("基础奖金") + private BigDecimal basicRewardAmount; + + @ApiModelProperty("超额奖金") + private BigDecimal excessRewardAmount; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeEmployeeDetailVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeEmployeeDetailVO.java new file mode 100644 index 000000000..0b32ba6db --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeEmployeeDetailVO.java @@ -0,0 +1,64 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 门店新品销售菜品员工详情VO + *

+ * + * @author wangff + * @since 2026/4/23 + */ +@Data +public class BonusProductRecipeEmployeeDetailVO extends BonusBasicVO { + @ApiModelProperty("菜品编码") + private String recipeNo; + + @ApiModelProperty("菜品名称") + private String recipeName; + + @ApiModelProperty("发放月份") + private Date payDate; + + @ApiModelProperty("日销量奖励最低达标数量") + private Integer minStandardNum; + + @ApiModelProperty("销售奖励(元/个)") + private BigDecimal rewardAmount; + + @ApiModelProperty("日销量超额奖励基数") + private Integer excessStandardNum; + + @ApiModelProperty("超额后额外销售奖励(元/个)") + private BigDecimal excessAmount; + + @ApiModelProperty("销量") + private Integer salesVolume; + + @ApiModelProperty("基础奖金") + private BigDecimal basicRewardAmount; + + @ApiModelProperty("超额奖金") + private BigDecimal excessRewardAmount; + + @ApiModelProperty("奖励人id") + private String rewardUserId; + + @ApiModelProperty("奖励比例") + private BigDecimal rewardRatio; + + @ApiModelProperty("奖励人姓名") + private String rewardUserName; + + @ApiModelProperty("奖金总计") + private BigDecimal amountTotal; + + public BigDecimal getAmountTotal() { + return basicRewardAmount.add(excessRewardAmount); + } +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeEmployeeListVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeEmployeeListVO.java new file mode 100644 index 000000000..813a86cc8 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeEmployeeListVO.java @@ -0,0 +1,49 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 门店新品销售菜品员工列表VO + *

+ * + * @author wangff + * @since 2026/4/23 + */ +@Data +public class BonusProductRecipeEmployeeListVO extends BonusBasicVO { + @ApiModelProperty("菜品编码") + private String recipeNo; + + @ApiModelProperty("菜品名称") + private String recipeName; + + @ApiModelProperty("发放月份") + private Date payDate; + + @ApiModelProperty("销量") + private Integer salesVolume; + + @ApiModelProperty("基础奖金") + private BigDecimal basicRewardAmount; + + @ApiModelProperty("超额奖金") + private BigDecimal excessRewardAmount; + + @ApiModelProperty("奖励人id") + private String rewardUserId; + + @ApiModelProperty("奖励人姓名") + private String rewardUserName; + + @ApiModelProperty("奖金总计") + private BigDecimal amountTotal; + + public BigDecimal getAmountTotal() { + return basicRewardAmount.add(excessRewardAmount); + } +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeListVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeListVO.java new file mode 100644 index 000000000..27e74b4b6 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductRecipeListVO.java @@ -0,0 +1,41 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 门店新品销售奖金发放列表-菜品 + *

+ * + * @author wangff + * @since 2026/4/22 + */ +@Data +public class BonusProductRecipeListVO extends BonusBasicVO { + + @ApiModelProperty("菜品编码") + private String recipeNo; + + @ApiModelProperty("菜品名称") + private String recipeName; + + @ApiModelProperty("发放月份") + private Date payDate; + + @ApiModelProperty("基础奖金") + private BigDecimal basicRewardAmount; + + @ApiModelProperty("超额奖金") + private BigDecimal excessRewardAmount; + + @ApiModelProperty("奖金总计") + private BigDecimal amountTotal; + + public BigDecimal getAmountTotal() { + return basicRewardAmount.add(excessRewardAmount); + } +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductStoreDetailVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductStoreDetailVO.java new file mode 100644 index 000000000..ec86435b8 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductStoreDetailVO.java @@ -0,0 +1,32 @@ +package com.cool.store.vo.bonus; + +import com.cool.store.request.bonus.BonusRuleProductConfig; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 门店新品销售奖金详情VO + * + * @author wangff + * @since 2026/4/22 + */ +@Data +public class BonusProductStoreDetailVO { + @ApiModelProperty("门店编码") + private String storeNum; + + @ApiModelProperty("门店名称") + private String storeName; + + @ApiModelProperty("发放年月") + private Date payDate; + + @ApiModelProperty("新品销售奖金规则配置(新品销售必填)") + private List productConfigs; + + @ApiModelProperty("发放明细列表") + private List employeeList; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductStoreListVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductStoreListVO.java new file mode 100644 index 000000000..edee18c8f --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusProductStoreListVO.java @@ -0,0 +1,25 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 门店新品销售奖金发放列表VO + * + * @author wangff + * @since 2026/4/22 + */ +@Data +public class BonusProductStoreListVO extends BonusBasicVO { + @ApiModelProperty("规则id") + private Long ruleId; + + @ApiModelProperty("发放年月") + private Date payDate; + + @ApiModelProperty("奖金额总计") + private BigDecimal amountTotal; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedComputeVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedComputeVO.java new file mode 100644 index 000000000..32ef3bb6e --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedComputeVO.java @@ -0,0 +1,31 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.List; + +/** + *

+ * 实收实算VO + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BonusReceivedComputeVO { + @ApiModelProperty("日均实收") + private BigDecimal receivedDaily; + + @ApiModelProperty("奖金总计") + private BigDecimal amountTotal; + + @ApiModelProperty("发放明细") + private List detail; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedEmployeeListVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedEmployeeListVO.java new file mode 100644 index 000000000..df27a43f7 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedEmployeeListVO.java @@ -0,0 +1,49 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 员工实收奖金发放列表VO + * + * @author wangff + * @since 2026/4/22 + */ +@Data +public class BonusReceivedEmployeeListVO extends BonusBasicVO { + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("门店实收id") + private Long receivedStoreId; + + @ApiModelProperty("发放月份") + private Date payDate; + + @ApiModelProperty("月度实收") + private BigDecimal receivedMonthly; + + @ApiModelProperty("月度营业天数") + private Integer businessDays; + + @ApiModelProperty("日均实收") + private BigDecimal receivedDaily; + + @ApiModelProperty("上月日均实收") + private BigDecimal receivedDailyLast; + + @ApiModelProperty("实收奖金额总计") + private BigDecimal amountTotal; + + @ApiModelProperty("奖励比例") + private BigDecimal rewardRatio; + + @ApiModelProperty("实收奖励金额") + private BigDecimal receivedAmount; + + @ApiModelProperty("奖励人姓名") + private String rewardUserName; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedStoreDetailVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedStoreDetailVO.java new file mode 100644 index 000000000..089b51b0f --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedStoreDetailVO.java @@ -0,0 +1,57 @@ +package com.cool.store.vo.bonus; + +import com.cool.store.request.bonus.BonusRuleReceivedConfig; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * 门店实收奖金详情VO + * + * @author wangff + * @since 2026/4/22 + */ +@Data +public class BonusReceivedStoreDetailVO { + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("门店id") + private String storeId; + + @ApiModelProperty("门店编码") + private String storeNum; + + @ApiModelProperty("门店名称") + private String storeName; + + @ApiModelProperty("发放月份") + private Date payDate; + + @ApiModelProperty("月度实收") + private BigDecimal receivedMonthly; + + @ApiModelProperty("月度营业天数") + private Integer businessDays; + + @ApiModelProperty("日均实收小于等于该值不发放奖金(实收必填)") + private BigDecimal receivedStart; + + @ApiModelProperty("实收奖励规则配置(实收必填)") + private List receivedConfigs; + + @ApiModelProperty("日均实收") + private BigDecimal receivedDaily; + + @ApiModelProperty("上月日均实收") + private BigDecimal receivedDailyLast; + + @ApiModelProperty("奖金额总计") + private BigDecimal amountTotal; + + @ApiModelProperty("员工本月奖金发放列表") + private List employeeList; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedStoreListVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedStoreListVO.java new file mode 100644 index 000000000..4e777ce82 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusReceivedStoreListVO.java @@ -0,0 +1,38 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * 门店实收奖金发放列表VO + * + * @author wangff + * @since 2026/4/22 + */ +@Data +public class BonusReceivedStoreListVO extends BonusBasicVO { + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("发放月份") + private Date payDate; + + @ApiModelProperty("月度实收") + private BigDecimal receivedMonthly; + + @ApiModelProperty("月度营业天数") + private Integer businessDays; + + @ApiModelProperty("日均实收") + private BigDecimal receivedDaily; + + @ApiModelProperty("上月日均实收") + private BigDecimal receivedDailyLast; + + @ApiModelProperty("奖金额总计") + private BigDecimal amountTotal; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusRuleListVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusRuleListVO.java new file mode 100644 index 000000000..38dd651d7 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusRuleListVO.java @@ -0,0 +1,35 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + *

+ * 奖金发放规则列表VO + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class BonusRuleListVO extends BonusBasicVO { + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("规则类型,1-实收 2-新品销售") + private Integer type; + + @ApiModelProperty("是否启用,0否1是") + private Integer enable; + + @ApiModelProperty("生效开始年月") + private Date startDate; + + @ApiModelProperty("生效结束年月") + private Date endDate; + + @ApiModelProperty("创建时间") + private Date createTime; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusRuleVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusRuleVO.java new file mode 100644 index 000000000..cb4a18653 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/BonusRuleVO.java @@ -0,0 +1,61 @@ +package com.cool.store.vo.bonus; + +import com.cool.store.request.bonus.BonusRuleDistributeConfig; +import com.cool.store.request.bonus.BonusRuleProductConfig; +import com.cool.store.request.bonus.BonusRuleReceivedConfig; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + *

+ * 奖金发放规则VO + *

+ * + * @author wangff + * @since 2026/4/20 + */ +@Data +public class BonusRuleVO { + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("规则类型,1-实收 2-新品销售") + private Integer type; + + @ApiModelProperty("门店id") + private String storeId; + + @ApiModelProperty("门店编码") + private String storeNum; + + @ApiModelProperty("门店名称") + private String storeName; + + @ApiModelProperty("生效开始年月") + private Date startDate; + + @ApiModelProperty("生效结束年月") + private Date endDate; + + @ApiModelProperty("日均实收小于等于该值不发放奖金(实收必填)") + private BigDecimal receivedStart; + + @ApiModelProperty("实收奖励规则配置(实收必填)") + private List receivedConfigs; + + @ApiModelProperty("新品销售奖金规则配置(新品销售必填)") + private List productConfigs; + + @ApiModelProperty("分配规则") + private List distributeConfigs; + + @ApiModelProperty("是否启用,0否1是") + private Integer enable; + + @ApiModelProperty("上月日均实收") + private BigDecimal receivedDailyLast; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/EmployeeBonusVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/EmployeeBonusVO.java new file mode 100644 index 000000000..bf0e178ce --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/bonus/EmployeeBonusVO.java @@ -0,0 +1,33 @@ +package com.cool.store.vo.bonus; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + *

+ * 门店实收员工VO + *

+ * + * @author wangff + * @since 2026/4/22 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class EmployeeBonusVO { + @ApiModelProperty("员工id") + private String rewardUserId; + + @ApiModelProperty("员工名称") + private String rewardUserName; + + @ApiModelProperty("奖励比例") + private BigDecimal rewardRatio; + + @ApiModelProperty("金额") + private BigDecimal receivedAmount; +} \ No newline at end of file diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/StoreService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/StoreService.java index f4d8d380e..e1422a652 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/StoreService.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/StoreService.java @@ -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 authStoreUser(List storeIdList, String positionType); + /** + * 同标品方法一致;authStoreUser方法会查询出运营顾问等角色 + */ + List authStoreUserV2(List storeIdList, String positionType); + List getStorePositionUserList(List storeIds, List positionIds, List nodePersonList, @@ -51,4 +57,9 @@ public interface StoreService { Boolean handleStoreLogLai(Integer flag,String specialStoreCode); + /** + * 获取门店人员的店内职位信息 + */ + List getStoreUserPositionList(String storeId, String userName); + } diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/ThirdStoreOpenDataService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/ThirdStoreOpenDataService.java new file mode 100644 index 000000000..bd3132425 --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/ThirdStoreOpenDataService.java @@ -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 getMonthRevenue(StoreMonthRevenueRequest request); + + /** + * 查询门店菜品日销量数据 + * + * @param request 请求参数 + * @return 菜品日销量数据列表 + */ + List getRecipeDailySales(StoreRecipeDailySalesRequest request); + + /** + * 查询门店菜品种类 + * + * @param request 请求参数 + * @return 菜品种类列表 + */ + List getRecipes(StoreRecipesRequest request); +} \ No newline at end of file diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/bonus/BonusService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/bonus/BonusService.java new file mode 100644 index 000000000..43ae83168 --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/bonus/BonusService.java @@ -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; + +/** + *

+ * 奖金发放规则服务类 + *

+ * + * @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 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 getReceivedStoreList(BonusReceivedStoreQueryRequest request); + + /** + * 门店实收奖金详情 + */ + BonusReceivedStoreDetailVO getReceivedStoreDetail(Long id); + + /** + * 员工实收奖金发放列表 + */ + PageInfo getReceivedEmployeeList(BonusReceivedEmployeeQueryRequest request); + + /** + * 员工实收奖金详情 + */ + BonusReceivedStoreDetailVO getReceivedEmployeeDetail(Long id); + + /** + * 门店新品销售奖金发放列表-门店 + */ + PageInfo getNewProductStoreList(BonusProductQueryRequest request); + + /** + * 门店新品销售奖金详情 + */ + BonusProductStoreDetailVO getNewProductStoreDetail(BonusProductMonthlyQueryRequest request); + + /** + * 门店新品销售奖金发放列表-菜品 + */ + PageInfo getNewProductRecipeList(BonusProductQueryRequest request); + + /** + * 门店新品销售奖金发放详情-菜品 + */ + PageInfo getNewProductRecipeDetail(BonusProductRecipeQueryRequest request); + + /** + * 门店新品销售奖金发放列表-员工 + */ + PageInfo getNewProductEmployeeList(BonusProductEmployeeQueryRequest request); + + /** + * 门店新品销售奖金发放详情-员工 + */ + BonusProductStoreDetailVO getNewProductEmployeeDetail(BonusProductMonthlyQueryRequest request); + + /** + * 门店新品销售奖金方法列表-菜品+员工 + */ + PageInfo getNewProductRecipeEmployeeList(BonusProductEmployeeQueryRequest request); + + /** + * 门店新品销售奖金发放详情-菜品+员工 + */ + PageInfo getNewProductRecipeEmployeeDetail(BonusProductRecipeEmployeeQueryRequest request); + + /** + * 员工奖金明细 + */ + PageInfo getEmployeeMonthlyDetail(BonusProductEmployeeQueryRequest request); + + /** + * 删除月度实收数据 + */ + void deleteMonthlyReceived(BonusDistributionRuleDO ruleDO, String payMonth); + + /** + * 删除每日新品销售数据 + */ + void deleteMonthlyNewProduct(BonusDistributionRuleDO ruleDO, String payDate); + + /** + * 查询门店菜品种类 + */ + List getRecipes(String storeId); + + /** + * 查询上月日均实收 + */ + BigDecimal receivedDailyLast(String storeId); +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/bonus/impl/BonusServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/bonus/impl/BonusServiceImpl.java new file mode 100644 index 000000000..9dcddc18b --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/bonus/impl/BonusServiceImpl.java @@ -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; + +/** + *

+ * 奖金发放规则服务实现类 + *

+ * + * @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> group = CollStreamUtil.groupByKey(request.getProductConfigs(), BonusRuleProductConfig::getRecipeNo); + for (List 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 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 getList(BonusRuleQueryRequest request) { + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List list = ruleDAO.getList(request.getStoreNumOrName(), request.getType(), request.getEnable(), request.getStoreId()); + PageInfo 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 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 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 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 recipeSaleMap = CollStreamUtil.toMap(request.getRecipeSales(), BonusProductRecipeCompute::getRecipeNo, BonusProductRecipeCompute::getSalesVolume); + Map employeeAmount = new HashMap<>(); + + List 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 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 userMap = CollStreamUtil.toMap(request.getDistributeConfigs(), BonusRuleDistributeConfig::getRewardUserId, BonusRuleDistributeConfig::getRewardUserName); + List 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 receivedConfigs = bonusConfig.getJSONArray("receivedConfigs") + .toJavaList(BonusRuleReceivedConfig.class); + List distributeConfigs = JSONObject.parseArray(rule.getDistributeConfig(), BonusRuleDistributeConfig.class); + + // 调用API获取门店月营收数据 + StoreMonthRevenueRequest request = new StoreMonthRevenueRequest(); + request.setStoreNum(storeNum); + request.setStartDate(payMonth); + request.setEndDate(payMonth); + + List 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 productConfigs = bonusConfig.getJSONArray("productConfigs") + .toJavaList(BonusRuleProductConfig.class); + List distributeConfigs = JSONObject.parseArray(rule.getDistributeConfig(), BonusRuleDistributeConfig.class); + + // 调用API获取门店菜品日销量数据 + StoreRecipeDailySalesRequest request = new StoreRecipeDailySalesRequest(); + request.setStoreNum(storeNum); + request.setStartDate(payDate); + request.setEndDate(payDate); + + List salesList = storeOpenDataService.getRecipeDailySales(request); + if (CollectionUtils.isEmpty(salesList)) { + log.warn("门店菜品日销量数据为空, storeNum: {}", storeNum); + return; + } + + // 构建销量请求 + List 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 receiveList = receivedEmployeeDAO.getMonthlyStatisticsGroupByStore(payMonth); + // 查询门店员工新品销售数据 + List productList = newProductEmployeeDAO.getMonthlyStatisticsGroupByStore(payMonth); + + // 将实收数据转为 Map> + Map> receiveMap = receiveList.stream() + .collect(Collectors.groupingBy( + BonusReceivedEmployeeDO::getStoreId, + Collectors.toMap( + BonusReceivedEmployeeDO::getRewardUserId, + v -> v, + (v1, v2) -> v1 + ) + )); + + // 将新品数据转为 Map> + Map> productMap = productList.stream() + .collect(Collectors.groupingBy( + BonusNewProductEmployeeDO::getStoreId, + Collectors.toMap( + BonusNewProductEmployeeDO::getRewardUserId, + v -> v, + (v1, v2) -> v1 + ) + )); + + Set> 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 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 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 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 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 productConfigs, + List 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 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 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 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 getReceivedStoreList(BonusReceivedStoreQueryRequest request) { + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List list = receivedStoreDAO.selectListByCondition( + request.getStoreNumOrName(), request.getStartMonth(), request.getEndMonth(), request.getStoreId()); + PageInfo 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 employeeList = receivedEmployeeDAO.selectByReceivedStoreId(id); + List employeeVOList = CollStreamUtil.toList(employeeList, e -> + new EmployeeBonusVO(e.getRewardUserId(), e.getRewardUserName(), e.getRewardRatio(), e.getReceivedAmount())); + vo.setEmployeeList(employeeVOList); + return vo; + } + + @Override + public PageInfo getReceivedEmployeeList(BonusReceivedEmployeeQueryRequest request) { + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List list = receivedEmployeeDAO.selectEmployeeListByCondition( + request.getStoreNumOrName(), request.getStartMonth(), request.getEndMonth(), request.getRewardUserName(), request.getStoreId()); + PageInfo page = BeanUtil.toPage(new PageInfo<>(list), BonusReceivedEmployeeListVO.class); + if (CollectionUtils.isEmpty(list)) { + return page; + } + // 获取门店实收信息 + Set receivedStoreIds = CollStreamUtil.toSet(list, BonusReceivedEmployeeDO::getReceivedStoreId); + Map 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 getNewProductStoreList(BonusProductQueryRequest request) { + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List list = newProductStoreDAO.monthlyStatistics(request.getStoreNumOrName(), request.getStartDate(), request.getEndDate(), null, null); + + PageInfo 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 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 employeeList = newProductEmployeeDAO.monthlyStatistics(request.getRuleId(), request.getStoreId(), request.getPayDate(), null); + List employeeVOList = CollStreamUtil.toList(employeeList, e -> + new EmployeeBonusVO(e.getRewardUserId(), e.getRewardUserName(), null, e.getRewardAmount())); + vo.setEmployeeList(employeeVOList); + return vo; + } + + @Override + public PageInfo getNewProductRecipeList(BonusProductQueryRequest request) { + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List list = newProductRecipeDAO.monthlyStatistics(request.getStoreNumOrName(), request.getStartDate(), request.getEndDate(), request.getRecipeNoOrName()); + PageInfo page = BeanUtil.toPage(new PageInfo<>(list), BonusProductRecipeListVO.class); + fillBasicField(page.getList()); + return page; + } + + @Override + public PageInfo getNewProductRecipeDetail(BonusProductRecipeQueryRequest request) { + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List list = newProductRecipeDAO.selectListByCondition(request.getStoreId(), request.getRecipeNo(), request.getStartDate(), request.getEndDate()); + PageInfo page = BeanUtil.toPage(new PageInfo<>(list), BonusProductRecipeDetailVO.class); + fillBasicField(page.getList()); + return page; + } + + @Override + public PageInfo getNewProductEmployeeList(BonusProductEmployeeQueryRequest request) { + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List list = newProductEmployeeDAO.employeeMonthlyStatistics(request.getStartDate(), + request.getEndDate(), request.getStoreNumOrName(), request.getRewardUserName(), request.getStoreId()); + List result = CollStreamUtil.toList(list, v -> { + BonusProductEmployeeListVO vo = BeanUtil.toBean(v, BonusProductEmployeeListVO.class); + vo.setReceivedAmount(v.getRewardAmount()); + return vo; + }); + PageInfo 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 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 employeeVOList = Collections.singletonList(new EmployeeBonusVO(employeeDO.getRewardUserId(), employeeDO.getRewardUserName(), null, employeeDO.getRewardAmount())); + vo.setEmployeeList(employeeVOList); + return vo; + } + + @Override + public PageInfo getNewProductRecipeEmployeeList(BonusProductEmployeeQueryRequest request) { + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List list = newProductRecipeEmployeeDAO.monthlyStatistics(request.getStoreNumOrName(), request.getStartDate(), request.getEndDate(), request.getRewardUserName(), request.getRecipeNoOrName()); + PageInfo page = BeanUtil.toPage(new PageInfo<>(list), BonusProductRecipeEmployeeListVO.class); + fillBasicField(page.getList()); + return page; + } + + @Override + public PageInfo getNewProductRecipeEmployeeDetail(BonusProductRecipeEmployeeQueryRequest request) { + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List list = newProductRecipeEmployeeDAO.selectListByCondition(request.getStoreId(), request.getRecipeNo(), request.getRewardUserId(), request.getStartDate(), request.getEndDate()); + Set productRecipeIds = CollStreamUtil.toSet(list, BonusNewProductRecipeEmployeeDO::getProductRecipeId); + Map productRecipeMap = newProductRecipeDAO.getMapByIds(new ArrayList<>(productRecipeIds)); + List 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 page = BeanUtil.toPage(new PageInfo<>(list), result); + fillBasicField(page.getList()); + return page; + } + + @Override + public PageInfo getEmployeeMonthlyDetail(BonusProductEmployeeQueryRequest request) { + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List list = rewardDetailDAO.selectListByCondition(request.getStoreNumOrName(), + request.getStartDate(), request.getEndDate(), request.getRewardUserName(), request.getStoreId()); + PageInfo 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 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 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 list) { + Set storeIds = CollStreamUtil.toSet(list, BonusBasicVO::getStoreId); + Map 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()); + } + }); + } +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/StoreServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/StoreServiceImpl.java index 33843b91a..34c70186c 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/StoreServiceImpl.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/StoreServiceImpl.java @@ -353,6 +353,51 @@ public class StoreServiceImpl implements StoreService { return Boolean.TRUE; } + @Override + public List getStoreUserPositionList(String storeId, String userName) { + if (StrUtil.isBlank(storeId)) { + throw new ServiceException(ErrorCodeEnum.PARAMS_VALIDATE_ERROR.getCode(), "请选择门店后查询"); + } + List authStoreUserDTOList = this.authStoreUserV2( + Collections.singletonList(storeId), "store_inside"); + + if (CollectionUtils.isEmpty(authStoreUserDTOList)) { + return new ArrayList<>(); + } + List userIdList = ListUtils.emptyIfNull(authStoreUserDTOList) + .stream() + .map(AuthStoreUserDTO::getUserIdList) + .flatMap(Collection::stream) + .distinct() + .collect(Collectors.toList()); + if (CollUtil.isEmpty(userIdList)) { + return new ArrayList<>(); + } + List 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> storeUserDTOMap = ListUtils.emptyIfNull(list).stream().collect(Collectors.groupingBy(k -> k.getUserId())); + List result = Lists.newArrayList(); + for (String userId : storeUserDTOMap.keySet()) { + List singleUserDTOList = storeUserDTOMap.get(userId); + if (CollectionUtils.isEmpty(singleUserDTOList)) { + continue; + } + StoreUserDTO storeUserDTO = singleUserDTOList.get(0); + List 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 authStoreUser(List 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 authStoreUserV2(List storeIdList, String positionType) { + List result = new ArrayList<>(); + if (CollectionUtils.isEmpty(storeIdList)) { + return result; + } + //将拥有管理员角色、角色属性为全企业数据的人查询出来 + List roleUserByRoleId = sysRoleMapper.getRoleUserByRoleEnum(Role.MASTER.getRoleEnum(),positionType); + List roleUserByRoleAuth = sysRoleMapper.getRoleUserByRoleAuth(AuthRoleEnum.ALL.getCode(),positionType); + //组合出拥有所有门店信息的人 + List allStoreUserIdList = getAllStoreUserIdList(roleUserByRoleId, roleUserByRoleAuth); + //查询出有门店权限配置的的人员 + // 1.将门店区域切分出门店所属于的区域ID + // 2.将配置了区域的人 查询出来 + // 3.将配置了门店的人 查询出来 + List storeAreaList = storeMapper.getStoreAreaList(storeIdList); + if (CollectionUtils.isEmpty(storeAreaList)) { + return Collections.emptyList(); + } + + List fullAreaIdList = ListUtils.emptyIfNull(storeAreaList) + .stream() + .map(StoreAreaDTO::getAreaIdList) + .flatMap(Collection::stream) + .distinct() + .collect(Collectors.toList()); + + + List lastAreaIdList = ListUtils.emptyIfNull(storeAreaList) + .stream() + .map(StoreAreaDTO::getAreaId) + .distinct() + .collect(Collectors.toList()); + + //除不包含子区域的可视化范围的区域配置。 + List regionUserAuthMappingList = userAuthMappingMapper.listUserAuthMappingByAuthV2( + UserAuthMappingTypeEnum.REGION.getCode(), fullAreaIdList, positionType, AuthRoleEnum.NOT_INCLUDE_SUBORDINATE.getCode()); + //不包含子区域的的直属连接门店的区域下的配置(会重复一些选择了上面数据) + List notIncludeRegionUserAuthMappingList = userAuthMappingMapper.listUserAuthMappingByAuthV2( + UserAuthMappingTypeEnum.REGION.getCode(), lastAreaIdList, positionType, null); + //配置了门店的的配置 + List 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 getAllStoreUserIdList(List roleUserByRoleId, List roleUserByRoleAuth) { List allUserIdList= new ArrayList<>(); diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/ThirdStoreOpenDataServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/ThirdStoreOpenDataServiceImpl.java new file mode 100644 index 000000000..a6c81417d --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/ThirdStoreOpenDataServiceImpl.java @@ -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 getMonthRevenue(StoreMonthRevenueRequest request) { + String path = "/open/v1/store/monthRevenue"; + String url = apiUrl + path; + return executeApiCall(url, path, request, StoreMonthRevenueResponse.class); + } + + @Override + public List getRecipeDailySales(StoreRecipeDailySalesRequest request) { + String path = "/open/v1/store/recipeDailySales"; + String url = apiUrl + path; + return executeApiCall(url, path, request, StoreRecipeDailySalesResponse.class); + } + + @Override + public List getRecipes(StoreRecipesRequest request) { + String path = "/open/v1/store/recipes"; + String url = apiUrl + path; + return executeApiCall(url, path, request, StoreRecipesResponse.class); + } + + private List executeApiCall(String url, String path, Object request, Class 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> 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); + } + } + } +} \ No newline at end of file diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/BonusController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/BonusController.java new file mode 100644 index 000000000..6e8273353 --- /dev/null +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/BonusController.java @@ -0,0 +1,164 @@ +package com.cool.store.controller.webb; + +import com.cool.store.context.CurrentUserHolder; +import com.cool.store.request.bonus.*; +import com.cool.store.response.ResponseResult; +import com.cool.store.response.storeopen.StoreRecipesResponse; +import com.cool.store.service.bonus.BonusService; +import com.cool.store.vo.bonus.*; +import com.github.pagehelper.PageInfo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + *

+ * 工资奖金发放 前端控制器 + *

+ * + * @author wangff + * @since 2026/4/21 + */ +@Api(tags = "工资奖金发放") +@RestController +@RequestMapping("/pc/bonus") +@RequiredArgsConstructor +public class BonusController { + private final BonusService bonusService; + + @ApiOperation("新增规则") + @PostMapping("/addRule") + public ResponseResult addRule(@RequestBody @Validated BonusRuleAddRequest request) { + return ResponseResult.success(bonusService.addRule(request, CurrentUserHolder.getUserId())); + } + + @ApiOperation("编辑规则") + @PostMapping("/updateRule") + public ResponseResult updateRule(@RequestBody @Validated BonusRuleUpdateRequest request) { + return ResponseResult.success(bonusService.updateRule(request, CurrentUserHolder.getUserId())); + } + + @ApiOperation("启用规则") + @PostMapping("/enableRule") + public ResponseResult enableRule(@RequestBody @Validated BonusRuleEnableRequest request) { + return ResponseResult.success(bonusService.enableRule(request)); + } + + @ApiOperation("规则详情") + @GetMapping("/ruleDetail") + @ApiImplicitParam(name = "ruleId", value = "规则id", required = true, dataType = "Long", paramType = "query") + public ResponseResult getRuleDetail(@NotNull(message = "规则id不能为空") Long ruleId) { + return ResponseResult.success(bonusService.getRuleDetail(ruleId)); + } + + @ApiOperation("规则列表查询") + @PostMapping("/list") + public ResponseResult> getList(@RequestBody BonusRuleQueryRequest request) { + return ResponseResult.success(bonusService.getList(request)); + } + + @ApiOperation("实收实算") + @PostMapping("/receivedCompute") + public ResponseResult receivedCompute(@RequestBody @Validated BonusReceivedComputeRequest request) { + return ResponseResult.success(bonusService.receivedCompute(request)); + } + + @ApiOperation("新品销售实算") + @PostMapping("/productCompute") + public ResponseResult productCompute(@RequestBody @Validated BonusProductComputeRequest request) { + return ResponseResult.success(bonusService.productCompute(request)); + } + + @ApiOperation("门店实收奖金发放列表") + @PostMapping("/receivedStoreList") + public ResponseResult> getReceivedStoreList(@RequestBody BonusReceivedStoreQueryRequest request) { + return ResponseResult.success(bonusService.getReceivedStoreList(request)); + } + + @ApiOperation("门店实收奖金详情") + @GetMapping("/receivedStoreDetail") + @ApiImplicitParam(name = "id", value = "门店实收奖金id", required = true, dataType = "Long", paramType = "query") + public ResponseResult getReceivedStoreDetail(@NotNull(message = "id不能为空") Long id) { + return ResponseResult.success(bonusService.getReceivedStoreDetail(id)); + } + + @ApiOperation("员工实收奖金发放列表") + @PostMapping("/receivedEmployeeList") + public ResponseResult> getReceivedEmployeeList(@RequestBody BonusReceivedEmployeeQueryRequest request) { + return ResponseResult.success(bonusService.getReceivedEmployeeList(request)); + } + + @ApiOperation("员工实收奖金详情") + @GetMapping("/receivedEmployeeDetail") + @ApiImplicitParam(name = "id", value = "员工实收奖金id", required = true, dataType = "Long", paramType = "query") + public ResponseResult getReceivedEmployeeDetail(@NotNull(message = "id不能为空") Long id) { + return ResponseResult.success(bonusService.getReceivedEmployeeDetail(id)); + } + + @ApiOperation("新品销售奖金发放-门店列表") + @PostMapping("/newProductStoreList") + public ResponseResult> getNewProductStoreList(@RequestBody BonusProductQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductStoreList(request)); + } + + @ApiOperation("新品销售奖金-门店详情") + @PostMapping("/newProductStoreDetail") + @ApiImplicitParam(name = "id", value = "门店新品销售奖金id", required = true, dataType = "Long", paramType = "query") + public ResponseResult getNewProductStoreDetail(@RequestBody @Validated BonusProductMonthlyQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductStoreDetail(request)); + } + + @ApiOperation("新品销售奖金-菜品列表") + @PostMapping("/newProductRecipeList") + public ResponseResult> getNewProductRecipeList(@RequestBody BonusProductQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductRecipeList(request)); + } + + @ApiOperation("新品销售奖金-菜品详情") + @PostMapping("/newProductRecipeDetail") + public ResponseResult> getNewProductRecipeDetail(@RequestBody @Validated BonusProductRecipeQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductRecipeDetail(request)); + } + + @ApiOperation("新品销售奖金-员工列表") + @PostMapping("/newProductEmployeeList") + public ResponseResult> getNewProductEmployeeList(@RequestBody BonusProductEmployeeQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductEmployeeList(request)); + } + + @ApiOperation("新品销售奖金-员工详情") + @PostMapping("/newProductEmployeeDetail") + public ResponseResult getNewProductEmployeeDetail(@RequestBody @Validated BonusProductMonthlyQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductEmployeeDetail(request)); + } + + @ApiOperation("新品销售奖金-菜品+员工列表") + @PostMapping("/newProductRecipeEmployeeList") + public ResponseResult> getNewProductRecipeEmployeeList(@RequestBody BonusProductEmployeeQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductRecipeEmployeeList(request)); + } + + @ApiOperation("新品销售奖金-菜品+员工详情") + @PostMapping("/newProductRecipeEmployeeDetail") + public ResponseResult> getNewProductRecipeEmployeeDetail(@RequestBody @Validated BonusProductRecipeEmployeeQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductRecipeEmployeeDetail(request)); + } + + @ApiOperation("员工奖金明细") + @PostMapping("/employeeBonusDetail") + public ResponseResult> getEmployeeBonusDetail(@RequestBody BonusProductEmployeeQueryRequest request) { + return ResponseResult.success(bonusService.getEmployeeMonthlyDetail(request)); + } + + @ApiOperation("门店菜品列表") + @GetMapping("/recipeList") + public ResponseResult> getRecipeList(@RequestParam @NotNull(message = "门店id不能为空") String storeId) { + return ResponseResult.success(bonusService.getRecipes(storeId)); + } +} \ No newline at end of file diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCStoreController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCStoreController.java index 699c765f9..869e9bf5e 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCStoreController.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCStoreController.java @@ -2,6 +2,7 @@ package com.cool.store.controller.webb; import com.cool.store.common.PageBasicInfo; import com.cool.store.context.CurrentUserHolder; +import com.cool.store.dto.store.StoreUserDTO; import com.cool.store.request.store.StoreListRequest; import com.cool.store.request.UserStoreRequest; import com.cool.store.response.MiniShopsResponse; @@ -15,6 +16,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.List; + /** *

* PC门店 前端控制器 @@ -42,4 +45,9 @@ public class PCStoreController { return ResponseResult.success(storeService.getAuthStoreList(request)); } + @ApiOperation("门店人员列表") + @GetMapping("/storeUserPositionList") + public ResponseResult> getStoreUserPositionList(String storeId, String userName) { + return ResponseResult.success(storeService.getStoreUserPositionList(storeId, userName)); + } } diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCTestController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCTestController.java index 11f03b229..0f713124d 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCTestController.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCTestController.java @@ -1,8 +1,10 @@ package com.cool.store.controller.webb; import com.alibaba.fastjson.JSONObject; +import com.cool.store.annotation.Debounce; import com.cool.store.constants.CommonConstants; import com.cool.store.dao.*; +import com.cool.store.dao.bonus.BonusDistributionRuleDAO; import com.cool.store.dao.fees.WalletPayInfoDAO; import com.cool.store.dto.*; import com.cool.store.dto.contract.ContractCallbackDTO; @@ -13,11 +15,9 @@ import com.cool.store.dto.xgj.XgjPartnerPageDTO; import com.cool.store.dto.wallet.*; import com.cool.store.dto.xgj.XgjPayResultDTO; import com.cool.store.entity.*; +import com.cool.store.entity.bonus.BonusDistributionRuleDO; import com.cool.store.entity.fees.WalletPayInfoDO; -import com.cool.store.enums.DownSystemTypeEnum; -import com.cool.store.enums.FranchiseBrandEnum; -import com.cool.store.enums.MessageEnum; -import com.cool.store.enums.SMSMsgEnum; +import com.cool.store.enums.*; import com.cool.store.enums.point.ShopSubStageStatusEnum; import com.cool.store.enums.wechat.WechatTemplateEnum; import com.cool.store.handler.WeChatHandler; @@ -31,6 +31,9 @@ import com.cool.store.request.bigdata.ProfitDataRequest; import com.cool.store.request.close.store.CloseStoreApplyRequest; import com.cool.store.request.huoma.ShopBasicInfoRequest; import com.cool.store.request.oppty.*; +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.request.wallet.*; import com.cool.store.request.xgj.PushFranchiseFeeRequest; import com.cool.store.request.xgj.*; @@ -43,7 +46,11 @@ import com.cool.store.response.huoma.ShopBaseInfoResponse; import com.cool.store.response.oppty.CityResponse; import com.cool.store.response.oppty.OpportunityDetailResponse; import com.cool.store.response.oppty.OpportunityInfoPageResponse; +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.*; +import com.cool.store.service.bonus.BonusService; import com.cool.store.service.close.CloseStoreService; import com.cool.store.service.fees.WalletPayInfoService; import com.cool.store.service.impl.CommonService; @@ -138,6 +145,65 @@ public class PCTestController { @Resource WalletPayInfoService walletPayInfoService; + @Resource + ThirdStoreOpenDataService thirdStoreOpenDataService; + @Resource + BonusService bonusService; + @Resource + BonusDistributionRuleDAO bonusRuleDAO; + + @PostMapping("/processReceivedRule") + @Debounce(timeMs = 10000, diffUser = false) + public ResponseResult processReceivedRule(Long ruleId, String payMonth) { + BonusDistributionRuleDO ruleDO = bonusRuleDAO.getById(ruleId); + if (Objects.isNull(ruleDO)) { + return ResponseResult.fail(ErrorCodeEnum.BONUS_RULE_NOT_EXIST); + } + // 删除所有实收数据 + bonusService.deleteMonthlyReceived(ruleDO, payMonth); + bonusService.processReceivedRule(ruleDO, payMonth); + return ResponseResult.success(true); + } + + @PostMapping("/processNewProductRule") + @Debounce(timeMs = 10000, diffUser = false) + public ResponseResult processNewProductRule(Long ruleId, String payDate) { + BonusDistributionRuleDO ruleDO = bonusRuleDAO.getById(ruleId); + if (Objects.isNull(ruleDO)) { + return ResponseResult.fail(ErrorCodeEnum.BONUS_RULE_NOT_EXIST); + } + bonusService.deleteMonthlyNewProduct(ruleDO, payDate); + bonusService.processNewProductRule(ruleDO, payDate); + return ResponseResult.success(true); + } + + @PostMapping("/dailyNewProductBonus") + public ResponseResult dailyNewProductBonus() { + xxlJobHandler.dailyNewProductBonus(); + return ResponseResult.success(true); + } + + @PostMapping("/monthlyReceivedBonus") + public ResponseResult monthlyReceivedBonus() { + xxlJobHandler.monthlyReceivedBonus(); + return ResponseResult.success(true); + } + + @PostMapping("/getMonthRevenue") + public ResponseResult> getMonthRevenue(@RequestBody StoreMonthRevenueRequest request) { + return ResponseResult.success(thirdStoreOpenDataService.getMonthRevenue(request)); + } + + @PostMapping("/getRecipeDailySales") + public ResponseResult> getRecipeDailySales(@RequestBody StoreRecipeDailySalesRequest request) { + return ResponseResult.success(thirdStoreOpenDataService.getRecipeDailySales(request)); + } + + @PostMapping("/getRecipes") + public ResponseResult> getRecipes(@RequestBody StoreRecipesRequest request) { + return ResponseResult.success(thirdStoreOpenDataService.getRecipes(request)); + } + @PostMapping("/walletReceiptRePush") public ResponseResult walletReceiptRePush(Long id) { walletPayInfoService.rePushReceipt(id); diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniBonusController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniBonusController.java new file mode 100644 index 000000000..547568a6a --- /dev/null +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniBonusController.java @@ -0,0 +1,174 @@ +package com.cool.store.controller.webc; + +import com.cool.store.context.PartnerUserHolder; +import com.cool.store.request.bonus.*; +import com.cool.store.response.ResponseResult; +import com.cool.store.response.storeopen.StoreRecipesResponse; +import com.cool.store.service.bonus.BonusService; +import com.cool.store.vo.bonus.*; +import com.github.pagehelper.PageInfo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.util.List; + +/** + *

+ * Mini工资奖金发放 + *

+ * + * @author wangff + * @since 2026/4/23 + */ +@Api(tags = "Mini工资奖金发放") +@RestController +@RequestMapping("/mini/bonus") +@RequiredArgsConstructor +@Valid +public class MiniBonusController { + private final BonusService bonusService; + + @ApiOperation("新增规则") + @PostMapping("/addRule") + public ResponseResult addRule(@RequestBody @Validated BonusRuleAddRequest request) { + return ResponseResult.success(bonusService.addRule(request, PartnerUserHolder.getUser().getPartnerId())); + } + + @ApiOperation("编辑规则") + @PostMapping("/updateRule") + public ResponseResult updateRule(@RequestBody @Validated BonusRuleUpdateRequest request) { + return ResponseResult.success(bonusService.updateRule(request, PartnerUserHolder.getUser().getPartnerId())); + } + + @ApiOperation("启用规则") + @PostMapping("/enableRule") + public ResponseResult enableRule(@RequestBody @Validated BonusRuleEnableRequest request) { + return ResponseResult.success(bonusService.enableRule(request)); + } + + @ApiOperation("规则详情") + @GetMapping("/ruleDetail") + @ApiImplicitParam(name = "ruleId", value = "规则id", required = true, dataType = "Long", paramType = "query") + public ResponseResult getRuleDetail(@NotNull(message = "规则id不能为空") Long ruleId) { + return ResponseResult.success(bonusService.getRuleDetail(ruleId)); + } + + @ApiOperation("规则列表查询") + @PostMapping("/list") + public ResponseResult> getList(@RequestBody BonusRuleQueryRequest request) { + return ResponseResult.success(bonusService.getList(request)); + } + + @ApiOperation("实收实算") + @PostMapping("/receivedCompute") + public ResponseResult receivedCompute(@RequestBody @Validated BonusReceivedComputeRequest request) { + return ResponseResult.success(bonusService.receivedCompute(request)); + } + + @ApiOperation("新品销售实算") + @PostMapping("/productCompute") + public ResponseResult productCompute(@RequestBody @Validated BonusProductComputeRequest request) { + return ResponseResult.success(bonusService.productCompute(request)); + } + + @ApiOperation("门店实收奖金发放列表") + @PostMapping("/receivedStoreList") + public ResponseResult> getReceivedStoreList(@RequestBody BonusReceivedStoreQueryRequest request) { + return ResponseResult.success(bonusService.getReceivedStoreList(request)); + } + + @ApiOperation("门店实收奖金详情") + @GetMapping("/receivedStoreDetail") + @ApiImplicitParam(name = "id", value = "门店实收奖金id", required = true, dataType = "Long", paramType = "query") + public ResponseResult getReceivedStoreDetail(@NotNull(message = "id不能为空") Long id) { + return ResponseResult.success(bonusService.getReceivedStoreDetail(id)); + } + + @ApiOperation("员工实收奖金发放列表") + @PostMapping("/receivedEmployeeList") + public ResponseResult> getReceivedEmployeeList(@RequestBody BonusReceivedEmployeeQueryRequest request) { + return ResponseResult.success(bonusService.getReceivedEmployeeList(request)); + } + + @ApiOperation("员工实收奖金详情") + @GetMapping("/receivedEmployeeDetail") + @ApiImplicitParam(name = "id", value = "员工实收奖金id", required = true, dataType = "Long", paramType = "query") + public ResponseResult getReceivedEmployeeDetail(@NotNull(message = "id不能为空") Long id) { + return ResponseResult.success(bonusService.getReceivedEmployeeDetail(id)); + } + + @ApiOperation("新品销售奖金发放-门店列表") + @PostMapping("/newProductStoreList") + public ResponseResult> getNewProductStoreList(@RequestBody BonusProductQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductStoreList(request)); + } + + @ApiOperation("新品销售奖金-门店详情") + @PostMapping("/newProductStoreDetail") + @ApiImplicitParam(name = "id", value = "门店新品销售奖金id", required = true, dataType = "Long", paramType = "query") + public ResponseResult getNewProductStoreDetail(@RequestBody @Validated BonusProductMonthlyQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductStoreDetail(request)); + } + + @ApiOperation("新品销售奖金-菜品列表") + @PostMapping("/newProductRecipeList") + public ResponseResult> getNewProductRecipeList(@RequestBody BonusProductQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductRecipeList(request)); + } + + @ApiOperation("新品销售奖金-菜品详情") + @PostMapping("/newProductRecipeDetail") + public ResponseResult> getNewProductRecipeDetail(@RequestBody @Validated BonusProductRecipeQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductRecipeDetail(request)); + } + + @ApiOperation("新品销售奖金-员工列表") + @PostMapping("/newProductEmployeeList") + public ResponseResult> getNewProductEmployeeList(@RequestBody BonusProductEmployeeQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductEmployeeList(request)); + } + + @ApiOperation("新品销售奖金-员工详情") + @PostMapping("/newProductEmployeeDetail") + public ResponseResult getNewProductEmployeeDetail(@RequestBody @Validated BonusProductMonthlyQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductEmployeeDetail(request)); + } + + @ApiOperation("新品销售奖金-菜品+员工列表") + @PostMapping("/newProductRecipeEmployeeList") + public ResponseResult> getNewProductRecipeEmployeeList(@RequestBody BonusProductEmployeeQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductRecipeEmployeeList(request)); + } + + @ApiOperation("新品销售奖金-菜品+员工详情") + @PostMapping("/newProductRecipeEmployeeDetail") + public ResponseResult> getNewProductRecipeEmployeeDetail(@RequestBody @Validated BonusProductRecipeEmployeeQueryRequest request) { + return ResponseResult.success(bonusService.getNewProductRecipeEmployeeDetail(request)); + } + + @ApiOperation("员工奖金明细") + @PostMapping("/employeeBonusDetail") + public ResponseResult> getEmployeeBonusDetail(@RequestBody BonusProductEmployeeQueryRequest request) { + return ResponseResult.success(bonusService.getEmployeeMonthlyDetail(request)); + } + + @ApiOperation("门店菜品列表") + @GetMapping("/recipeList") + public ResponseResult> getRecipeList(@RequestParam @NotNull(message = "门店id不能为空") String storeId) { + return ResponseResult.success(bonusService.getRecipes(storeId)); + } + + @ApiOperation("门店上月日均实收") + @GetMapping("/receivedDailyLast") + public ResponseResult getReceivedDailyLast(@RequestParam @NotBlank(message = "门店id不能为空") String storeId) { + return ResponseResult.success(bonusService.receivedDailyLast(storeId)); + } +} diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniStoreController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniStoreController.java new file mode 100644 index 000000000..9ceb5df07 --- /dev/null +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniStoreController.java @@ -0,0 +1,35 @@ +package com.cool.store.controller.webc; + +import com.cool.store.dto.store.StoreUserDTO; +import com.cool.store.response.ResponseResult; +import com.cool.store.service.StoreService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + *

+ * Mini门店 前端控制器 + *

+ * + * @author wangff + * @since 2026/4/24 + */ +@Api(tags = "mini门店") +@RestController +@RequestMapping("/mini/stores") +@RequiredArgsConstructor +public class MiniStoreController { + private final StoreService storeService; + + @ApiOperation("门店人员列表") + @GetMapping("/storeUserPositionList") + public ResponseResult> getStoreUserPositionList(String storeId, String userName) { + return ResponseResult.success(storeService.getStoreUserPositionList(storeId, userName)); + } +} diff --git a/coolstore-partner-web/src/main/java/com/cool/store/job/XxlJobHandler.java b/coolstore-partner-web/src/main/java/com/cool/store/job/XxlJobHandler.java index 61266ab01..9b756a019 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/job/XxlJobHandler.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/job/XxlJobHandler.java @@ -4,11 +4,13 @@ import cn.hutool.core.collection.CollStreamUtil; import com.alibaba.fastjson.JSONObject; import com.cool.store.constants.CommonConstants; import com.cool.store.dao.*; +import com.cool.store.dao.bonus.BonusDistributionRuleDAO; import com.cool.store.dao.tp.TpApplyFormDAO; import com.cool.store.dao.wallet.WalletTradeDAO; import com.cool.store.dto.*; import com.cool.store.dto.store.StoreOrderTimeDTO; import com.cool.store.entity.*; +import com.cool.store.entity.bonus.BonusDistributionRuleDO; import com.cool.store.entity.tp.TpApplyFormDO; import com.cool.store.entity.wallet.WalletTradeDO; import com.cool.store.enums.*; @@ -27,6 +29,7 @@ import com.cool.store.request.tp.TpApplyQueryRequest; import com.cool.store.request.close.store.CloseStoreApplyRequest; import com.cool.store.response.bigdata.LatestOrderDateResponse; import com.cool.store.service.*; +import com.cool.store.service.bonus.BonusService; import com.cool.store.service.close.CloseStoreRefundService; import com.cool.store.service.close.CloseStoreService; import com.cool.store.service.fees.WalletPayInfoService; @@ -50,6 +53,7 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; @@ -139,6 +143,14 @@ public class XxlJobHandler { SplitOrderService splitOrderService; @Resource WithdrawApplicationService withdrawApplicationService; + @Resource + BonusDistributionRuleDAO ruleDAO; + @Resource + BonusService bonusService; + + private static final DateTimeFormatter MONTH_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM"); + private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + /** @@ -756,4 +768,90 @@ public class XxlJobHandler { } log.info("------end withdrawUpdate------"); } + + /** + * 每月统计上一个月门店的实收数据并入库 + * 建议每月1日凌晨执行 + */ + @XxlJob("monthlyReceivedBonus") + public void monthlyReceivedBonus() { + MDCUtils.put(CommonConstants.REQUEST_ID, UUID.randomUUID().toString()); + log.info("------start monthlyReceivedBonus------"); + + // 计算上一个月 + LocalDate lastMonth = LocalDate.now().minusMonths(1); + String payMonth = lastMonth.format(MONTH_FORMATTER); + log.info("统计月份: {}", payMonth); + + try { + // 获取类型为1(实收)的启用规则列表 + int pageNum = 1, pageSize = CommonConstants.BATCH_SIZE; + boolean hasNext = true; + while (hasNext) { + PageHelper.startPage(pageNum, pageSize); + List rules = ruleDAO.getEnabledRulesByTypeAndMonth(1, payMonth); + if (CollectionUtils.isEmpty(rules)) { + break; + } + hasNext = rules.size() >= pageSize; + // 按门店分组处理 + for (BonusDistributionRuleDO rule : rules) { + try { + log.info("处理门店:{}, ruleId;{}", rule.getStoreId(), rule.getId()); + bonusService.processReceivedRule(rule, payMonth); + } catch (Exception e) { + log.error("处理实收规则失败, ruleId: {}, storeId: {}", rule.getId(), rule.getStoreId(), e); + } + } + pageNum++; + } + log.info("------end monthlyReceivedBonus------"); + } catch (Exception e) { + log.error("monthlyReceivedBonus执行失败", e); + XxlJobHelper.handleFail("执行失败: " + e.getMessage()); + } + } + + /** + * 每天统计前一天的新品销售数据并入库 + * 建议每天凌晨执行 + */ + @XxlJob("dailyNewProductBonusJob") + public void dailyNewProductBonus() { + MDCUtils.put(CommonConstants.REQUEST_ID, UUID.randomUUID().toString()); + log.info("------start dailyNewProductBonus------"); + + // 计算前一天 + LocalDate yesterday = LocalDate.now().minusDays(1); + String payDate = yesterday.format(DATE_FORMATTER); + String payMonth = yesterday.format(MONTH_FORMATTER); + log.info("统计日期: {}", payDate); + + try { + // 获取类型为2(新品销售)的启用规则列表 + int pageNum = 1, pageSize = CommonConstants.BATCH_SIZE; + boolean hasNext = true; + while (hasNext) { + PageHelper.startPage(pageNum, pageSize); + List rules = ruleDAO.getEnabledRulesByTypeAndMonth(2, payMonth); + if (CollectionUtils.isEmpty(rules)) { + break; + } + hasNext = rules.size() >= pageSize; + // 按门店分组处理 + for (BonusDistributionRuleDO rule : rules) { + try { + log.info("处理门店:{}, ruleId;{}", rule.getStoreId(), rule.getId()); + bonusService.processNewProductRule(rule, payDate); + } catch (Exception e) { + log.error("处理新品销售规则失败, ruleId: {}, storeId: {}", rule.getId(), rule.getStoreId(), e); + } + } + } + log.info("------end dailyNewProductBonus------"); + } catch (Exception e) { + log.error("dailyNewProductBonus执行失败", e); + XxlJobHelper.handleFail("执行失败: " + e.getMessage()); + } + } } diff --git a/coolstore-partner-web/src/main/resources/application-ab.properties b/coolstore-partner-web/src/main/resources/application-ab.properties index a71670c96..1803c5173 100644 --- a/coolstore-partner-web/src/main/resources/application-ab.properties +++ b/coolstore-partner-web/src/main/resources/application-ab.properties @@ -178,4 +178,9 @@ wallet.api.yzt.key=360155690205317 cool.api.rsa.private.key=MIIEpQIBAAKCAQEA0erPAWesjkp9J4htmfCyqKS9npmT9dW3KqWTfb4c7x/QBUtKuokWOO0XikHd4bGUa9kl+twSv/5A3kYz1B9eg6wRuDJoads+G5U7rVQjzdoUtLaf3lNXkuSehl4uHUPQfNa6vcmvzraXPxJjEpYzj9WZh7uJqq2oSgw42H1qdbFCXSaE5BwsOb+2vZXjzh4RO10Sy3Qb1UqGsoZoxVzrtDeEctCjrecFyQr96L2UtYa4NTxSTfu4rgObrwIOMvqqnLsXEzK/rd6kIHYjkZYQCOa48AedWp2YKQ7Ldclj+VMLnXvl42J9exVkbs++8k3P5sI9fdZX4Ey2RBjnSoAo/QIDAQABAoIBACbBGi8I+CE77M+13wAu4RkD8xL7CQc3ic2ojGqIRPi7r5CuphD6mpzvXqtyfhd7DKr9h8bAxwBlnQ28ObjVgsI96/aM7dxvMs/uVPpqwIJyWuTDG5A05EPVC9REQnC6Mp09mnPL7rZz3Mfy6dIGY2YQWfwmWiPl1B45k+wZ+WPZPI0JVnvRzM881kf4aAhEAt08i9VoihylwVAjWIPmLuhf6ZcqI5q8iUsjfO22wZJsudVTCA/dsJdNxv+1RDKeYnSLJL79cZQcodqEhFqTy6vnn2dMsaHH7dpphU27barxUjeL482SR7kFfMqEXn5sltRn/3ep+3sf4Ph2vMtoZeECgYEA6gXzEtT9ZOeAMp4BRGmfNZ0TQLprPPVSwudz/uUBE4j/vyhfXkh9p7hqwyoxN+Z8b65yINvx8yP6hge6ek/MyAwBCZyfIRxZAPZu1eEGoYKl391ubFt2EIVqrN2DtAvzHMr5B/E2VHBq6AJm/rERFX5oKsg6zHS9tPLhgGnWVd0CgYEA5aFWOrtiqZJlp1MHQ4OeWBJatBSynkORdxCW7ic0CKbkYus0NSz1SsvskpbnfEXNB53x98qJxRhSopg/DC4m7XqxjSf9lY3HH4Y/9907olj33yGAnLWC88GivVndt577u/XhYRCk33vOQ3GoibEdjnpMOkWmOfwYG/FsRWWQvaECgYEA1N2siEisZIgel+wZAv2AD+hchtgKi1wqd5bIb+Yl4HsRBfPXK4+MnG6mzfcm5c4FCiEHNtRZc+waCKgm+vJzNtOUbgXEyP1cCAAgOPOCcI7CCqsDshRPhB+XNL4Y+kCUVnBZrNu/q3bGB1uIC8tL2t0sKx4OPcNCe8EhVQjwKRECgYEA4uothdhKRPtwDIsVsHfN74Yjr7SMVay7gIcaPrjqyGnzYnS+oJWOx50AaFNK6Rko5JAF3jF9NxE0B4yfMPAic6Y88hpEkpcJ4HMPn2Y1WdbFCu/WYgVUJICCys6VNLCcXj85umtyIY38Y9VbEMW/SV49GZBeFQqy4FoP/fvBrkECgYEAnfjTDYwgdmJdsUqyNzAocwcJXG2rVtYc7Txrl0TltcwuJmgoSywdzyOP2R9+NZsfoxWDzG0/yr15ApMvUcnnTwHN/8bGQ9SLatFLKqS4EtdwDKKS1JvNbs7V1myQGpt7jbShZOI0e6Fs4xP8ujxsLeGgiq9mZrS9UdRj5XKDoVM= cool.api.rsa.public.key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0erPAWesjkp9J4htmfCyqKS9npmT9dW3KqWTfb4c7x/QBUtKuokWOO0XikHd4bGUa9kl+twSv/5A3kYz1B9eg6wRuDJoads+G5U7rVQjzdoUtLaf3lNXkuSehl4uHUPQfNa6vcmvzraXPxJjEpYzj9WZh7uJqq2oSgw42H1qdbFCXSaE5BwsOb+2vZXjzh4RO10Sy3Qb1UqGsoZoxVzrtDeEctCjrecFyQr96L2UtYa4NTxSTfu4rgObrwIOMvqqnLsXEzK/rd6kIHYjkZYQCOa48AedWp2YKQ7Ldclj+VMLnXvl42J9exVkbs++8k3P5sI9fdZX4Ey2RBjnSoAo/QIDAQAB wallet.api.rsa.public.key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvU5WUX5MaZhS4MRfZ5OeqmSxTgjNi64SEwTiDYS++DRHRFTEguk1g5AbiW3l9eEdATeVk0WX+T6ZIIa2do3bQOKhlMtRwWMWQIucjGa7ySOCuicvnCD2HAQ2EThfqQdSpAW5UpcyodrhcyUkuevBA4fQQ06k9lB4FjqWtao2+aYFIPFPu8Wu28KI/9QIMLI02Q1YY3duJ67QW4EM4I2oS0t3sWJeZtIJPRHFWW1EaLJz2FdbJJq+z6D2p++9pmkHsvdnktUUO+nPL3PCLtxGYxEwr/AqTYR/1yXfkVWe3nHXc+qvRt967X1hDHC+gEPJItr7kUk3pQTGBv9kNu75DwIDAQAB -wallet.org.id=140732221567301 \ No newline at end of file +wallet.org.id=140732221567301 + +store.open.url=https://zhengxin.zhidiansoft.com:5943 +store.open.appId=289704779317445 +store.open.appKey=IGSAEQoakR2HEaYx +store.open.secret=aPsA99K1obFeFm3m \ No newline at end of file diff --git a/coolstore-partner-web/src/main/resources/application-local.properties b/coolstore-partner-web/src/main/resources/application-local.properties index a076dd7dc..2d487403c 100644 --- a/coolstore-partner-web/src/main/resources/application-local.properties +++ b/coolstore-partner-web/src/main/resources/application-local.properties @@ -176,4 +176,9 @@ liePin.secretKey=dns6x4f1p14a36u4t22xvteppmz07ir2 liePin.aesSecretKey=_nkULTpkBHHZeWgQ liePin.baseUrl=https://open-xhopen-qa53.qa.xunhou.cn liePin.tenantId=12833 -liePin.mobile=13345565081 \ No newline at end of file +liePin.mobile=13345565081 + +store.open.url=https://zhengxin.zhidiansoft.com:5943 +store.open.appId=289704779317445 +store.open.appKey=IGSAEQoakR2HEaYx +store.open.secret=aPsA99K1obFeFm3m \ No newline at end of file diff --git a/coolstore-partner-web/src/main/resources/application-online.properties b/coolstore-partner-web/src/main/resources/application-online.properties index 30232c226..600a50851 100644 --- a/coolstore-partner-web/src/main/resources/application-online.properties +++ b/coolstore-partner-web/src/main/resources/application-online.properties @@ -173,4 +173,9 @@ wallet.api.yzt.key=375393764171845 cool.api.rsa.private.key=MIIEoQIBAAKCAQEAleyT39qxm9Vi4d3f/pF4yI3EATtLlP870dFfk5Rwj1MEM4OVTUeoBrld5GwTARQYzuyZETTZPh9taFCVtLFVsQv4waTqDf/7vnfBbvrTZ2mvZv6H/M6BTQnTx5UmOIP1RsA933ce7v/hmG/DlMaHU3JVC840Ae1q7uJZ2yA6+r6aAGdTGMSH4oQ+U9omJOJbgbuti9DsBuGDDKZ1uMhrWW/l4El5y2Qdu/71wIQuI08kPegmuGl4+FLRJ2OnoGsp+BRXKpFbN0fq0YwPQhjzSHsKg64qimmzRRr5Ewd+4w1/27dJ6mopQd4zvf7+VQ4wEZgATTe/hjBw1njOOBD/WQIDAQABAoIBACSFU0ZSEzbXRbWoo0JzdF1Cb28vXwuGGy/S1XnxTHQVcG4ODSYcoPk2WYFltEFsgFiTuPvAiHUCGdgx3S39jtbIiEm/nwZXB5+Ps46RykKkM4ae1UiHk2bNUIoLMprMxkh8VvYjIeVtbqp/+0A4FkoFDWOJURDxIT3c5K+ky8k9mKz59SiOkNoiayPQTEjzZPgKSsT64286PGmE9v4BlpyxQ1bLXeZaQGAkQ7YVtU5XJgbMM86hgmFlTcHVMGeMoQvJTfcsLlRg8ucX/zzBTHR7fZP6i5OJl5CYLbzHbTyHN9KRYDYv066SvbGLNa+4NO2cY+L6NehiwAkkFxSGKkMCgYEAoVgEjOqLyL1CpeaW7ckWQSbcae0a6J61b6meCkRaKrwcWi7ut9OfmvkCae2qsMsHQlitFM8blrnhtJxMt3EhWKYHI1seZto6YR0mzEEz5IVM3OStIZN7RY4Fg6AyB0C5Gure3GgGHaSs5J8AbCpJyLjTWuOdcnThgHHe4Mw2dGsCgYEA7eF0TpAbdYn8xjqNEgeRSSXYpwtRQ1zrpH0b1KQBxx/fvoZPzWG0SYIi6eYV5bxV5EDnCKlXXFD3ztMfThPFUGt8hHAG6CKpsiVNvYDVhAzXN18JQJtRQRO/4S0f42C8os87ToL1nlM83c8hegrsGO+JnoTzKf8KkpYqTNrvrEsCf1HuYGEuuc02TqHwdrRJaQOsuEESJpf6ACiz+Y09KIyK+drR+mdfD62ixZcFGaitcQJABaSLh3cC7ZrJxCtjR4u8w+MwYj/Ykcy/APS4J6HkDyQc+84RFog7lpFAyCbmtxj0LDfAm1pyRVnTZGOJFe7X7Hw7GbkFoX2YVZXSHdUCgYEA6rCuYPxIOxSicKg/mfQhYLuYHmZKDF3WlnhgRtBweJZ31q8IeKbWild8PqukGv5O910ZEzCPYiL3+fPNROi4mPkS5k7oYYohRgMLydUb0qYghx6aMEWMStpDStOMTHaaZT5zUqhdz5Br0qKScqfn+0oIyn58sYhQVAMXRLAUGjUCgYAYiuiTme9S9gSt1pZrDbPxXlbVm6PjlkP/OKrmBj5gq8iYeKzmYKp66UKFo6ZeeRcKiXLWdQS0i0rKBPux8kmfIwbrfbuYAVGE0GmUdEMNsBQvEjxpwo3afyB5F70tdnm4EBo0qeqJxuBK8DLpBFka2yfzEo/3Z6i0X/XqIwq/7A== cool.api.rsa.public.key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAleyT39qxm9Vi4d3f/pF4yI3EATtLlP870dFfk5Rwj1MEM4OVTUeoBrld5GwTARQYzuyZETTZPh9taFCVtLFVsQv4waTqDf/7vnfBbvrTZ2mvZv6H/M6BTQnTx5UmOIP1RsA933ce7v/hmG/DlMaHU3JVC840Ae1q7uJZ2yA6+r6aAGdTGMSH4oQ+U9omJOJbgbuti9DsBuGDDKZ1uMhrWW/l4El5y2Qdu/71wIQuI08kPegmuGl4+FLRJ2OnoGsp+BRXKpFbN0fq0YwPQhjzSHsKg64qimmzRRr5Ewd+4w1/27dJ6mopQd4zvf7+VQ4wEZgATTe/hjBw1njOOBD/WQIDAQAB wallet.api.rsa.public.key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvU5WUX5MaZhS4MRfZ5OeqmSxTgjNi64SEwTiDYS++DRHRFTEguk1g5AbiW3l9eEdATeVk0WX+T6ZIIa2do3bQOKhlMtRwWMWQIucjGa7ySOCuicvnCD2HAQ2EThfqQdSpAW5UpcyodrhcyUkuevBA4fQQ06k9lB4FjqWtao2+aYFIPFPu8Wu28KI/9QIMLI02Q1YY3duJ67QW4EM4I2oS0t3sWJeZtIJPRHFWW1EaLJz2FdbJJq+z6D2p++9pmkHsvdnktUUO+nPL3PCLtxGYxEwr/AqTYR/1yXfkVWe3nHXc+qvRt967X1hDHC+gEPJItr7kUk3pQTGBv9kNu75DwIDAQAB -wallet.org.id=420289242456261 \ No newline at end of file +wallet.org.id=420289242456261 + +store.open.url=https://zhengxin.zhidiansoft.com:5943 +store.open.appId=289704779317445 +store.open.appKey=IGSAEQoakR2HEaYx +store.open.secret=aPsA99K1obFeFm3m \ No newline at end of file diff --git a/coolstore-partner-web/src/main/resources/application-test.properties b/coolstore-partner-web/src/main/resources/application-test.properties index b1d3c087e..48673fdb7 100644 --- a/coolstore-partner-web/src/main/resources/application-test.properties +++ b/coolstore-partner-web/src/main/resources/application-test.properties @@ -178,4 +178,9 @@ wallet.url=https://api.dev.wenmatech.com:443 wallet.api.yzt.key=360155690205317 cool.api.rsa.private.key=MIIEpQIBAAKCAQEA0erPAWesjkp9J4htmfCyqKS9npmT9dW3KqWTfb4c7x/QBUtKuokWOO0XikHd4bGUa9kl+twSv/5A3kYz1B9eg6wRuDJoads+G5U7rVQjzdoUtLaf3lNXkuSehl4uHUPQfNa6vcmvzraXPxJjEpYzj9WZh7uJqq2oSgw42H1qdbFCXSaE5BwsOb+2vZXjzh4RO10Sy3Qb1UqGsoZoxVzrtDeEctCjrecFyQr96L2UtYa4NTxSTfu4rgObrwIOMvqqnLsXEzK/rd6kIHYjkZYQCOa48AedWp2YKQ7Ldclj+VMLnXvl42J9exVkbs++8k3P5sI9fdZX4Ey2RBjnSoAo/QIDAQABAoIBACbBGi8I+CE77M+13wAu4RkD8xL7CQc3ic2ojGqIRPi7r5CuphD6mpzvXqtyfhd7DKr9h8bAxwBlnQ28ObjVgsI96/aM7dxvMs/uVPpqwIJyWuTDG5A05EPVC9REQnC6Mp09mnPL7rZz3Mfy6dIGY2YQWfwmWiPl1B45k+wZ+WPZPI0JVnvRzM881kf4aAhEAt08i9VoihylwVAjWIPmLuhf6ZcqI5q8iUsjfO22wZJsudVTCA/dsJdNxv+1RDKeYnSLJL79cZQcodqEhFqTy6vnn2dMsaHH7dpphU27barxUjeL482SR7kFfMqEXn5sltRn/3ep+3sf4Ph2vMtoZeECgYEA6gXzEtT9ZOeAMp4BRGmfNZ0TQLprPPVSwudz/uUBE4j/vyhfXkh9p7hqwyoxN+Z8b65yINvx8yP6hge6ek/MyAwBCZyfIRxZAPZu1eEGoYKl391ubFt2EIVqrN2DtAvzHMr5B/E2VHBq6AJm/rERFX5oKsg6zHS9tPLhgGnWVd0CgYEA5aFWOrtiqZJlp1MHQ4OeWBJatBSynkORdxCW7ic0CKbkYus0NSz1SsvskpbnfEXNB53x98qJxRhSopg/DC4m7XqxjSf9lY3HH4Y/9907olj33yGAnLWC88GivVndt577u/XhYRCk33vOQ3GoibEdjnpMOkWmOfwYG/FsRWWQvaECgYEA1N2siEisZIgel+wZAv2AD+hchtgKi1wqd5bIb+Yl4HsRBfPXK4+MnG6mzfcm5c4FCiEHNtRZc+waCKgm+vJzNtOUbgXEyP1cCAAgOPOCcI7CCqsDshRPhB+XNL4Y+kCUVnBZrNu/q3bGB1uIC8tL2t0sKx4OPcNCe8EhVQjwKRECgYEA4uothdhKRPtwDIsVsHfN74Yjr7SMVay7gIcaPrjqyGnzYnS+oJWOx50AaFNK6Rko5JAF3jF9NxE0B4yfMPAic6Y88hpEkpcJ4HMPn2Y1WdbFCu/WYgVUJICCys6VNLCcXj85umtyIY38Y9VbEMW/SV49GZBeFQqy4FoP/fvBrkECgYEAnfjTDYwgdmJdsUqyNzAocwcJXG2rVtYc7Txrl0TltcwuJmgoSywdzyOP2R9+NZsfoxWDzG0/yr15ApMvUcnnTwHN/8bGQ9SLatFLKqS4EtdwDKKS1JvNbs7V1myQGpt7jbShZOI0e6Fs4xP8ujxsLeGgiq9mZrS9UdRj5XKDoVM= cool.api.rsa.public.key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0erPAWesjkp9J4htmfCyqKS9npmT9dW3KqWTfb4c7x/QBUtKuokWOO0XikHd4bGUa9kl+twSv/5A3kYz1B9eg6wRuDJoads+G5U7rVQjzdoUtLaf3lNXkuSehl4uHUPQfNa6vcmvzraXPxJjEpYzj9WZh7uJqq2oSgw42H1qdbFCXSaE5BwsOb+2vZXjzh4RO10Sy3Qb1UqGsoZoxVzrtDeEctCjrecFyQr96L2UtYa4NTxSTfu4rgObrwIOMvqqnLsXEzK/rd6kIHYjkZYQCOa48AedWp2YKQ7Ldclj+VMLnXvl42J9exVkbs++8k3P5sI9fdZX4Ey2RBjnSoAo/QIDAQAB -wallet.api.rsa.public.key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvU5WUX5MaZhS4MRfZ5OeqmSxTgjNi64SEwTiDYS++DRHRFTEguk1g5AbiW3l9eEdATeVk0WX+T6ZIIa2do3bQOKhlMtRwWMWQIucjGa7ySOCuicvnCD2HAQ2EThfqQdSpAW5UpcyodrhcyUkuevBA4fQQ06k9lB4FjqWtao2+aYFIPFPu8Wu28KI/9QIMLI02Q1YY3duJ67QW4EM4I2oS0t3sWJeZtIJPRHFWW1EaLJz2FdbJJq+z6D2p++9pmkHsvdnktUUO+nPL3PCLtxGYxEwr/AqTYR/1yXfkVWe3nHXc+qvRt967X1hDHC+gEPJItr7kUk3pQTGBv9kNu75DwIDAQAB \ No newline at end of file +wallet.api.rsa.public.key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvU5WUX5MaZhS4MRfZ5OeqmSxTgjNi64SEwTiDYS++DRHRFTEguk1g5AbiW3l9eEdATeVk0WX+T6ZIIa2do3bQOKhlMtRwWMWQIucjGa7ySOCuicvnCD2HAQ2EThfqQdSpAW5UpcyodrhcyUkuevBA4fQQ06k9lB4FjqWtao2+aYFIPFPu8Wu28KI/9QIMLI02Q1YY3duJ67QW4EM4I2oS0t3sWJeZtIJPRHFWW1EaLJz2FdbJJq+z6D2p++9pmkHsvdnktUUO+nPL3PCLtxGYxEwr/AqTYR/1yXfkVWe3nHXc+qvRt967X1hDHC+gEPJItr7kUk3pQTGBv9kNu75DwIDAQAB + +store.open.url=https://zhengxin.zhidiansoft.com:5943 +store.open.appId=289704779317445 +store.open.appKey=IGSAEQoakR2HEaYx +store.open.secret=aPsA99K1obFeFm3m