diff --git a/coolstore-partner-common/src/main/java/com/cool/store/constants/RedisConstant.java b/coolstore-partner-common/src/main/java/com/cool/store/constants/RedisConstant.java index e4d4b6115..d087525f2 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/constants/RedisConstant.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/constants/RedisConstant.java @@ -331,9 +331,14 @@ public class RedisConstant { * 每刻退款用户信息 */ public static final String MK_USER_MAPPING = "zxjp_mk_user_mapping"; - + /** * 建店资料总部订货收款账户信息 */ public static final String BUILD_RECEIVE_BANK_INFO = "zxjp_build_receive_bank_info"; + + /** + * 十二分导入锁 + */ + public static final String TP_PENALTY_APPLY_IMPORT_LOCK = "tp_penalty_apply_import_lock"; } 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 5b11549ba..ffbcdcfd6 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 @@ -368,6 +368,8 @@ public enum ErrorCodeEnum { TP_PENALTY_APPLY_UNABLE_ACCEPT(1810009, "该处罚单无法认缴", null), TP_PENALTY_APPLY_INEFFECTIVE(1810010, "该处罚单未生效无法完成缴费", null), TP_PENALTY_APPLY_NO_NEED_PAY(1810011, "该处罚单无需缴费", null), + TP_EXIST_PENDING_IMPORT_TASK(1810012, "存在导入中的任务,请稍后再试", null), + TP_NOT_EXIST_FORM_TYPE(1810013, "不存在该表单类型", null), CITY_PLANNING_EXISTS(1820001, "同年份同季度同省市已存在规划,不能重复添加", null), ; diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/FileTypeEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/FileTypeEnum.java index 99cf24b9b..a9ff32cd4 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/enums/FileTypeEnum.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/FileTypeEnum.java @@ -27,6 +27,8 @@ public enum FileTypeEnum { IMPORT_FITMENT_SHOP_STAGE_DATA_ERROR_LIST("OaOldShopStageDataErrorList", "导入装修阶段完成数据错误列表 "), SELLING_DETAILS_REPORT("sellingDetailsReport", "开店明细报表"), PRE_FRY_QUALIFICATION_APPLY_EXPORT("preFryQualificationApplyExport", "预炸品资质申请导出"), + TP_PENALTY_IMPORT("tpPenaltyImport", "十二分惩处申请单导入"), + TP_PENALTY_ERROR_EXPORT("tpPenaltyErrorExport", "十二分惩处申请单导入错误列表"), ; private String fileType; private String desc; diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/JoinModeEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/JoinModeEnum.java index 078b02850..037bee727 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/enums/JoinModeEnum.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/JoinModeEnum.java @@ -1,5 +1,7 @@ package com.cool.store.enums; +import java.util.Objects; + /** * @Author: WangShuo * @Date: 2025/01/08/下午5:51 @@ -55,6 +57,9 @@ public enum JoinModeEnum { } public static String getDescByCode(Integer code) { + if (Objects.isNull(code)) { + return null; + } for (JoinModeEnum e : JoinModeEnum.values()) { if (e.getCode() == code) { return e.desc; diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/tp/TpFormStatusEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/tp/TpFormStatusEnum.java index 5dbf56f40..3b10fc6ad 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/enums/tp/TpFormStatusEnum.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/tp/TpFormStatusEnum.java @@ -14,6 +14,7 @@ import lombok.Getter; @Getter @AllArgsConstructor public enum TpFormStatusEnum { + DRAFT("draft", "草稿"), PENDING("pending", "审批中"), PASS("pass", "审批通过"), diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/StoreDao.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/StoreDao.java index a4b1bbba8..c86ce7f31 100644 --- a/coolstore-partner-dao/src/main/java/com/cool/store/dao/StoreDao.java +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/StoreDao.java @@ -131,6 +131,19 @@ public class StoreDao { return score; } + /** + * 根据门店id查询门店编码 + * @param storeIds 门店id列表 + * @return store_id -> score + */ + public Map getScoreByStoreIds(List storeIds) { + if (CollectionUtils.isEmpty(storeIds)) { + return Collections.emptyMap(); + } + List> list = storeMapper.getScoreByStoreIds(storeIds); + return CollStreamUtil.toMap(list, v -> MapUtils.getString(v, "storeId"), v -> BigDecimal.valueOf(MapUtils.getDouble(v, "score"))); + } + /** * 根据门店id查询门店映射 * @param storeIds 门店id列表 @@ -211,4 +224,14 @@ public class StoreDao { ); } + + /** + * 根据区域id查询门店列表 + * @param regionIds 区域id + * @param keyword 门店名称或门店编码 + * @return 门店列表 + */ + public List getStoreByRegionIds(List regionIds, String keyword) { + return storeMapper.getStoreByRegionIds(regionIds, keyword); + } } diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/tp/TpApplyFormDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/tp/TpApplyFormDAO.java index dc3a459e1..e5c41dfa8 100644 --- a/coolstore-partner-dao/src/main/java/com/cool/store/dao/tp/TpApplyFormDAO.java +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/tp/TpApplyFormDAO.java @@ -134,7 +134,12 @@ public class TpApplyFormDAO { * @return 申请单 */ public TpApplyFormDO getAppealByPenaltyId(Long penaltyId) { - return tpApplyFormMapper.selectOne(TpApplyFormDO.builder().penaltyId(penaltyId).deleted(0).build()); + Example example = new Example(TpApplyFormDO.class); + example.createCriteria() + .andEqualTo("penaltyId", penaltyId) + .andEqualTo("deleted", 0) + .andIn("status", Arrays.asList(TpFormStatusEnum.PENDING.getStatus(), TpFormStatusEnum.PASS.getStatus(), TpFormStatusEnum.EFFECTIVE.getStatus())); + return tpApplyFormMapper.selectOneByExample(example); } /** diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/tp/TpRuleDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/tp/TpRuleDAO.java index 7288c83f5..031542f7d 100644 --- a/coolstore-partner-dao/src/main/java/com/cool/store/dao/tp/TpRuleDAO.java +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/tp/TpRuleDAO.java @@ -61,6 +61,13 @@ public class TpRuleDAO { return tpRuleMapper.selectByPrimaryKey(id); } + /** + * 根据规则编码查询启用的规则 + */ + public TpRuleDO getEnableByCode(String ruleNo) { + return tpRuleMapper.selectOne(TpRuleDO.builder().ruleNo(ruleNo).status(1).deleted(0).build()); + } + public List getEffectiveList(TpRuleQueryRequest request) { Example example = new Example(TpRuleDO.class); Example.Criteria criteria = example.createCriteria(); diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/StoreMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/StoreMapper.java index 5d54889ff..8dedc88b2 100644 --- a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/StoreMapper.java +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/StoreMapper.java @@ -75,6 +75,13 @@ public interface StoreMapper { */ BigDecimal getStoreScore(@Param("storeId") String storeId); + /** + * 根据门店id查询门店编码 + * @param storeIds 门店id列表 + * @return store_id -> score + */ + List> getScoreByStoreIds(@Param("storeIds") List storeIds); + /** * 更新门店积分 * @param storeId 门店id @@ -131,4 +138,12 @@ public interface StoreMapper { @Param("city") String city, @Param("openStartTime") LocalDate openStartTime, @Param("openEndTime") LocalDate openEndTime); + + /** + * 根据区域id查询门店列表 + * @param regionIds 区域id + * @param keyword 门店名称或门店编码 + * @return 门店列表 + */ + List getStoreByRegionIds(@Param("regionIds") List regionIds, @Param("keyword") String keyword); } diff --git a/coolstore-partner-dao/src/main/resources/mapper/StoreMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/StoreMapper.xml index f06b014a6..d6a8baf3f 100644 --- a/coolstore-partner-dao/src/main/resources/mapper/StoreMapper.xml +++ b/coolstore-partner-dao/src/main/resources/mapper/StoreMapper.xml @@ -281,6 +281,14 @@ WHERE store_id = #{storeId} + + INSERT INTO store_extend_info_${enterpriseId} (store_id, score) VALUES (#{storeId}, #{score}) ON DUPLICATE KEY UPDATE @@ -355,4 +363,21 @@ AND open_time <= #{openEndTime} + + diff --git a/coolstore-partner-dao/src/main/resources/mapper/tp/TpApplyFormMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/tp/TpApplyFormMapper.xml index 441492861..35c87aa35 100644 --- a/coolstore-partner-dao/src/main/resources/mapper/tp/TpApplyFormMapper.xml +++ b/coolstore-partner-dao/src/main/resources/mapper/tp/TpApplyFormMapper.xml @@ -45,8 +45,15 @@ penalty_id, applicant_name, phone, appeal_reason, appeal_detail_reason + + a.id,a.type,a.apply_no,a.store_id,a.rule_id,a.rule_no,a.problem_classification,a.project_category, + a.project_name,a.is_full,a.score,a.remark,a.amount,a.appeal_end_date,a.status,a.pay_status,a.is_draft, + a.source,a.apply_user_id,a.apply_user_name,a.approve_user_id,a.approve_time,a.create_time,a.update_time, + a.deleted,a.proof_urls,a.penalty_id,a.applicant_name,a.phone,a.appeal_reason,a.appeal_detail_reason + + diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/ImportOaOldShopDataErrorDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/ImportOaOldShopDataErrorDTO.java index 642294e9a..0e66d71bc 100644 --- a/coolstore-partner-model/src/main/java/com/cool/store/dto/ImportOaOldShopDataErrorDTO.java +++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/ImportOaOldShopDataErrorDTO.java @@ -16,7 +16,7 @@ public class ImportOaOldShopDataErrorDTO { @ExcelProperty(value = "门店编码", order = 1) @ColumnWidth(30) private String shopCode; - @ExcelProperty(value = "门店", order = 2) + @ExcelProperty(value = "惩处规则编码", order = 2) @ColumnWidth(30) private String shopName; @ExcelProperty(value = "错误原因", order =3) diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/tp/TpPenaltyImportErrorDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/tp/TpPenaltyImportErrorDTO.java new file mode 100644 index 000000000..d061e0341 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/tp/TpPenaltyImportErrorDTO.java @@ -0,0 +1,32 @@ +package com.cool.store.dto.tp; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * 惩处申请单导入错误DTO + *

+ * + * @author wangff + * @since 2026/1/9 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class TpPenaltyImportErrorDTO { + @ExcelProperty(value = "门店编码", order = 1) + @ColumnWidth(30) + private String storeNum; + + @ExcelProperty(value = "惩处规则编码", order = 3) + @ColumnWidth(30) + private String ruleNo; + + @ExcelProperty(value = "错误原因", order =3) + @ColumnWidth(40) + private String errorReason; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/store/StoreListRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/store/StoreListRequest.java new file mode 100644 index 000000000..f7b497d30 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/store/StoreListRequest.java @@ -0,0 +1,19 @@ +package com.cool.store.request.store; + +import com.cool.store.common.PageBasicInfo; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + *

+ * 根据区域查询门店Request + *

+ * + * @author wangff + * @since 2025/12/29 + */ +@Data +public class StoreListRequest extends PageBasicInfo { + @ApiModelProperty("门店编码或门店名称") + private String keyword; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpApplyAuditRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpApplyAuditRequest.java index 9df312896..ab4233e3a 100644 --- a/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpApplyAuditRequest.java +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpApplyAuditRequest.java @@ -1,7 +1,9 @@ package com.cool.store.request.tp; import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import javax.validation.constraints.NotNull; @@ -14,6 +16,8 @@ import javax.validation.constraints.NotNull; * @since 2025/11/6 */ @Data +@AllArgsConstructor +@NoArgsConstructor public class TpApplyAuditRequest { @ApiModelProperty("申请单id") @NotNull(message = "申请单id不能为空") diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpApplyIdRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpApplyIdRequest.java new file mode 100644 index 000000000..cbca02398 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpApplyIdRequest.java @@ -0,0 +1,21 @@ +package com.cool.store.request.tp; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + *

+ * 十二分申请单idRequest + *

+ * + * @author wangff + * @since 2026/1/8 + */ +@Data +public class TpApplyIdRequest { + @ApiModelProperty("申请单id") + @NotNull(message = "申请单id不能为空") + private Long applyId; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpApplyQueryRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpApplyQueryRequest.java index e9d11ad19..883b827c8 100644 --- a/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpApplyQueryRequest.java +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpApplyQueryRequest.java @@ -1,15 +1,12 @@ package com.cool.store.request.tp; import com.cool.store.common.PageBasicInfo; -import com.cool.store.constants.CommonConstants; import io.swagger.annotations.ApiModelProperty; import lombok.Data; -import org.apache.commons.lang3.StringUtils; import java.math.BigDecimal; -import java.util.Arrays; +import java.util.Date; import java.util.List; -import java.util.stream.Collectors; /** *

@@ -27,6 +24,9 @@ public class TpApplyQueryRequest extends PageBasicInfo { @ApiModelProperty("门店名称或编码") private String storeNameOrNum; + @ApiModelProperty("门店id") + private String storeId; + @ApiModelProperty("项目大类") private String projectCategory; @@ -56,4 +56,13 @@ public class TpApplyQueryRequest extends PageBasicInfo { @ApiModelProperty(value = "是否已逾期", hidden = true) private Boolean overdue; + + @ApiModelProperty("开始时间") + private Date startTime; + + @ApiModelProperty("结束时间") + private Date endTime; + + @ApiModelProperty("惩处状态,1惩处待处理 2惩处已处理") + private Integer penaltyStatus; } diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpBatchAuditRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpBatchAuditRequest.java new file mode 100644 index 000000000..e2c6d4e29 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpBatchAuditRequest.java @@ -0,0 +1,34 @@ +package com.cool.store.request.tp; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + *

+ * 申请单批量审批Request + *

+ * + * @author wangff + * @since 2026/1/20 + */ +@Data +public class TpBatchAuditRequest { + @ApiModelProperty("申请单类型") + @NotNull(message = "申请单类型不能为空") + private Integer type; + + @ApiModelProperty("审批状态 1通过 2拒绝") + @NotNull(message = "审批状态不能为空") + private Integer auditStatus; + + @ApiModelProperty("申请单id列表") + @NotEmpty(message = "申请单id不能为空") + private List applyIds; + + @ApiModelProperty("备注") + private String remark; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpRuleEnableRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpRuleEnableRequest.java new file mode 100644 index 000000000..2e58bbe6b --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/tp/TpRuleEnableRequest.java @@ -0,0 +1,27 @@ +package com.cool.store.request.tp; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + *

+ * 十二分规则启用Request + *

+ * + * @author wangff + * @since 2025/12/25 + */ +@Data +public class TpRuleEnableRequest { + @ApiModelProperty("规则id列表") + @NotEmpty(message = "规则id列表不能为空") + private List ruleIds; + + @ApiModelProperty("是否启用,0禁用 1启用") + @NotNull(message = "是否启用不能为空") + private Integer status; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/store/StoreListVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/store/StoreListVO.java new file mode 100644 index 000000000..5089c2218 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/store/StoreListVO.java @@ -0,0 +1,40 @@ +package com.cool.store.vo.store; + +import com.cool.store.enums.StoreStatusEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + *

+ * 门店列表VO + *

+ * + * @author wangff + * @since 2025/12/29 + */ +@Data +public class StoreListVO { + @ApiModelProperty("门店ID") + private String storeId; + + @ApiModelProperty("门店名称") + private String storeName; + + @ApiModelProperty("门店编号") + private String storeNum; + + @ApiModelProperty("门店状态") + private String storeStatus; + + @ApiModelProperty("门店状态名称") + private String storeStatusName; + + @ApiModelProperty("门店积分") + private BigDecimal score; + + public String getStoreStatusName() { + return StoreStatusEnum.getName(this.storeStatus); + } +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpAppealFormDetailVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpAppealFormDetailVO.java index 44de731c3..57e4de1b1 100644 --- a/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpAppealFormDetailVO.java +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpAppealFormDetailVO.java @@ -1,6 +1,7 @@ package com.cool.store.vo.tp; import com.cool.store.annotation.DictField; +import com.cool.store.enums.tp.TpFormStatusEnum; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -56,4 +57,14 @@ public class TpAppealFormDetailVO { @ApiModelProperty("处罚单") private TpPenaltyApplyDetailVO penaltyDetail; + + @ApiModelProperty("状态") + private String status; + + @ApiModelProperty("状态名称") + private String statusName; + + public String getStatusName() { + return TpFormStatusEnum.getMsgByStatus(this.status); + } } diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpBatchAuditVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpBatchAuditVO.java new file mode 100644 index 000000000..238e78fa8 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpBatchAuditVO.java @@ -0,0 +1,37 @@ +package com.cool.store.vo.tp; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * 申请单批量审批结果VO + *

+ * + * @author wangff + * @since 2026/1/20 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class TpBatchAuditVO { + @ApiModelProperty("id") + private Long applyId; + + @ApiModelProperty("申请单号") + private String applyNo; + + @ApiModelProperty("审批结果,1审批成功 2审批失败") + private Integer status; + + @ApiModelProperty("失败原因") + private String failReason; + + public TpBatchAuditVO(Long applyId, Integer status, String failReason) { + this.applyId = applyId; + this.status = status; + this.failReason = failReason; + } +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpPenaltyRuleListVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpPenaltyRuleListVO.java index b840d179a..8fa594762 100644 --- a/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpPenaltyRuleListVO.java +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpPenaltyRuleListVO.java @@ -50,4 +50,10 @@ public class TpPenaltyRuleListVO { @ApiModelProperty("启用状态,0未启用 1启用") private Integer status; + + @ApiModelProperty("项目描述") + private String remark; + + @ApiModelProperty("复议申请时效") + private Integer appealDeadline; } diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpScoreJournalVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpScoreJournalVO.java index 59938de4c..f221f0e13 100644 --- a/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpScoreJournalVO.java +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpScoreJournalVO.java @@ -85,7 +85,7 @@ public class TpScoreJournalVO { return BrandTypeEnum.getDescByCode(this.joinBrand); } - public String getJoinModelNam() { + public String getJoinModelName() { return JoinModeEnum.getDescByCode(this.joinModel); } diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpStoreScoreVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpStoreScoreVO.java new file mode 100644 index 000000000..15ceed480 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/TpStoreScoreVO.java @@ -0,0 +1,30 @@ +package com.cool.store.vo.tp; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + *

+ * 门店积分VO + *

+ * + * @author wangff + * @since 2026/1/9 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class TpStoreScoreVO { + @ApiModelProperty("门店名称") + private String storeName; + + @ApiModelProperty("门头照") + private String avatar; + + @ApiModelProperty("积分") + private BigDecimal score; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/mini/MiniTpAppealVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/mini/MiniTpAppealVO.java index 6124d7b5b..9855517d6 100644 --- a/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/mini/MiniTpAppealVO.java +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/mini/MiniTpAppealVO.java @@ -1,6 +1,7 @@ package com.cool.store.vo.tp.mini; import com.cool.store.annotation.DictField; +import com.cool.store.enums.tp.TpFormStatusEnum; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -35,4 +36,14 @@ public class MiniTpAppealVO { @ApiModelProperty("证明材料") private String proofUrls; + + @ApiModelProperty("状态") + private String status; + + @ApiModelProperty("状态名称") + private String statusName; + + public String getStatusName() { + return TpFormStatusEnum.getMsgByStatus(this.status); + } } diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/mini/MiniTpPenaltyApplyVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/mini/MiniTpPenaltyApplyVO.java index 687db2cb2..a8d165f26 100644 --- a/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/mini/MiniTpPenaltyApplyVO.java +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/tp/mini/MiniTpPenaltyApplyVO.java @@ -66,6 +66,9 @@ public class MiniTpPenaltyApplyVO { @ApiModelProperty("复议申请") private MiniTpAppealVO appeal; + @ApiModelProperty("金额") + private BigDecimal amount; + public String getStatusName() { return TpFormStatusEnum.getMsgByStatus(this.status); } diff --git a/coolstore-partner-service/src/main/java/com/cool/store/oss/OssClientService.java b/coolstore-partner-service/src/main/java/com/cool/store/oss/OssClientService.java index 129df2a91..ba7decdb5 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/oss/OssClientService.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/oss/OssClientService.java @@ -1,5 +1,6 @@ package com.cool.store.oss; +import cn.hutool.core.date.DateUtil; import com.aliyun.oss.ClientException; import com.aliyun.oss.OSSClient; import com.aliyun.oss.OSSException; @@ -13,6 +14,7 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import java.io.InputStream; +import java.util.Date; /** * Created by gavin on 15/8/5. @@ -33,6 +35,10 @@ public class OssClientService { @Value("${oss.host}") private String ossHost; + @Value("${cdn.url:null}") + private String cdnUrl; + @Value("${oss.file.dir:null}") + private String dir; private OSSClient client = null; @@ -146,6 +152,11 @@ public class OssClientService { putObject(fileName, inputStream, contentLength, contentType); } + public String putObjectWithoutPrefix(String fileName, InputStream inputStream, Long contentLength, String contentType) throws Exception { + String time = DateUtil.format(new Date(), "yyMM"); + return putObject(dir + time + "/" + fileName, inputStream, contentLength, contentType); + } + /** * 上传文件到阿里云OSS * @@ -167,7 +178,7 @@ public class OssClientService { PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName, inputStream, meta); log.info("uploadBaseImage, send..."); PutObjectResult p = ossClient.putObject(putObjectRequest.withProgressListener(new PutObjectProgressListener())); - String url = "https://"+bucketName+"."+endpoint +"/"+ fileName; + String url = cdnUrl + fileName; log.info("uploadBaseImage, send over,url:{}", url); return url; diff --git a/coolstore-partner-service/src/main/java/com/cool/store/request/tp/TpPenaltyImportRowDTO.java b/coolstore-partner-service/src/main/java/com/cool/store/request/tp/TpPenaltyImportRowDTO.java new file mode 100644 index 000000000..1727d4033 --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/request/tp/TpPenaltyImportRowDTO.java @@ -0,0 +1,61 @@ +package com.cool.store.request.tp; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 扣分申请单导入行 DTO(不含图片列) + * 第1行为说明,忽略 + * 第2行为表头 + * 从第3行开始为数据行: + * A 门店编码 + * B 惩处规则编码 + * C 扣分分值 + * D 罚款金额 + * E 复议申请时效(天) + * F 备注 + * G~L 证明图片1~6(由监听器处理) + */ +@Data +public class TpPenaltyImportRowDTO { + + /** + * 门店编码 + */ + @ExcelProperty(index = 0) + private String storeNum; + + /** + * 惩处规则编码 + */ + @ExcelProperty(index = 1) + private String ruleNo; + + /** + * 扣分分值 + */ + @ExcelProperty(index = 2) + private BigDecimal score; + + /** + * 罚款金额 + */ + @ExcelProperty(index = 3) + private BigDecimal amount; + + /** + * 复议申请时效(天) + */ + @ExcelProperty(index = 4) + private Integer AppealDeadline; + + /** + * 备注 + */ + @ExcelProperty(index = 5) + private String remark; +} + + 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 3397041b1..2bd3f3229 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 @@ -4,7 +4,9 @@ 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.StoreUserPositionDTO; +import com.cool.store.request.store.StoreListRequest; import com.cool.store.response.MiniShopsResponse; +import com.cool.store.vo.store.StoreListVO; import com.github.pagehelper.PageInfo; import java.util.List; @@ -42,4 +44,9 @@ public interface StoreService { List groupIdList, List regionIdList); + /** + * 获取当前用户权限区域下的门店列表 + */ + PageInfo getAuthStoreList(StoreListRequest request); + } 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 fa3909557..3dc2c2533 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 @@ -1,10 +1,10 @@ package com.cool.store.service.impl; import cn.hutool.core.collection.CollStreamUtil; -import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; +import com.cool.store.context.CurrentUserHolder; import com.cool.store.dto.StoreNameDTO; import com.cool.store.dao.store.StoreMasterSignerInfoDAO; import com.cool.store.dto.store.AuthStoreUserDTO; @@ -21,11 +21,14 @@ import com.cool.store.entity.store.StoreMasterSignerInfoDO; import com.cool.store.enums.*; import com.cool.store.exception.ServiceException; import com.cool.store.mapper.*; +import com.cool.store.request.store.StoreListRequest; import com.cool.store.response.MiniShopsResponse; import com.cool.store.service.StoreService; import com.cool.store.service.UserAuthMappingService; +import com.cool.store.utils.BeanUtil; import com.cool.store.utils.poi.constant.Constants; import com.cool.store.vo.SysRoleVO; +import com.cool.store.vo.store.StoreListVO; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.pagehelper.PageHelper; @@ -38,6 +41,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -281,6 +285,29 @@ public class StoreServiceImpl implements StoreService { return authStoreUsers; } + @Override + public PageInfo getAuthStoreList(StoreListRequest request) { + String userId = CurrentUserHolder.getUserId(); + + List regionIds = null; + Boolean isAdmin = enterpriseUserRoleDao.checkIsAdmin(userId); + if (!isAdmin) { + List userAuthMappings = userAuthMappingService.listUserAuthMappingByUserId(userId); + if (CollectionUtils.isEmpty(userAuthMappings)) { + return new PageInfo<>(Collections.emptyList()); + } + regionIds = CollStreamUtil.toList(userAuthMappings, UserAuthMappingDO::getMappingId); + } + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List storeList = storeDao.getStoreByRegionIds(regionIds, request.getKeyword()); + List storeIds = CollStreamUtil.toList(storeList, StoreDO::getStoreId); + Map scoreMap = storeDao.getScoreByStoreIds(storeIds); + PageInfo page = BeanUtil.toPage(new PageInfo<>(storeList), StoreListVO.class); + page.getList().forEach(v -> { + v.setScore(scoreMap.getOrDefault(v.getStoreId(), new BigDecimal(12))); + }); + return page; + } @Override diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/tp/TpApplyService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/tp/TpApplyService.java index 0dfd11fd3..7b9a4e170 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/tp/TpApplyService.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/tp/TpApplyService.java @@ -9,6 +9,7 @@ import com.cool.store.vo.tp.mini.MiniTpPenaltyApplyVO; import com.cool.store.vo.tp.mini.MiniTpRewardApplyVO; import com.cool.store.vo.tp.mini.MiniTpRuleListVO; import com.github.pagehelper.PageInfo; +import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -162,9 +163,37 @@ public interface TpApplyService { */ Boolean completePayment(Long applyId); + /** + * 撤销复议申请 + * @param applyId 复议申请id + * @return 是否成功 + */ + Boolean withdrawAppeal(Long applyId); + /** * 积分变动 * @param formDO 申请单DO */ void scoreChange(TpApplyFormDO formDO); + + /** + * 惩处申请单Excel导入(异步执行,立即返回) + * + * @param file Excel 文件 + */ + Boolean penaltyImport(MultipartFile file); + + /** + * 门店积分 + * @param storeId 门店id + * @return 积分 + */ + TpStoreScoreVO getStoreScore(String storeId); + + /** + * 批量审批 + * @param request 申请单批量审批Request + * @return 申请单批量审批结果VO列表 + */ + List batchAudit(TpBatchAuditRequest request); } diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/tp/impl/TpApplyServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/tp/impl/TpApplyServiceImpl.java index b2a1e0232..de5bcf9e8 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/tp/impl/TpApplyServiceImpl.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/tp/impl/TpApplyServiceImpl.java @@ -1,28 +1,38 @@ package com.cool.store.service.tp.impl; import cn.hutool.core.collection.CollStreamUtil; +import com.alibaba.fastjson.JSONObject; import com.cool.store.constants.CommonConstants; +import com.cool.store.constants.RedisConstant; import com.cool.store.context.CurrentUserHolder; import com.cool.store.context.LoginUserInfo; import com.cool.store.dao.EnterpriseUserDAO; import com.cool.store.dao.StoreDao; import com.cool.store.dao.tp.*; +import com.cool.store.dto.ImportOaOldShopDataErrorDTO; +import com.cool.store.dto.tp.TpPenaltyImportErrorDTO; +import com.cool.store.entity.ImportTaskDO; import com.cool.store.entity.StoreDO; import com.cool.store.entity.tp.TpApplyFormDO; import com.cool.store.entity.tp.TpRuleDO; import com.cool.store.entity.tp.TpScoreJournalDO; import com.cool.store.enums.ErrorCodeEnum; +import com.cool.store.enums.FileTypeEnum; +import com.cool.store.enums.ImportTaskStatusEnum; import com.cool.store.enums.tp.TpFormStatusEnum; import com.cool.store.enums.tp.TpFormTypeEnum; import com.cool.store.enums.tp.TpPayStatusEnum; import com.cool.store.exception.ServiceException; +import com.cool.store.mapper.ImportTaskMapper; +import com.cool.store.oss.OssClientService; import com.cool.store.request.tp.*; import com.cool.store.response.AuditInfoResponse; import com.cool.store.service.dict.impl.DictService; import com.cool.store.service.tp.TpApplyService; -import com.cool.store.utils.BeanUtil; -import com.cool.store.utils.CoolDateUtils; -import com.cool.store.utils.TpHelper; +import com.cool.store.request.tp.TpPenaltyImportRowDTO; +import com.cool.store.utils.*; +import com.cool.store.utils.easyExcel.EasyExcelUtil; +import com.cool.store.utils.poi.DateUtils; import com.cool.store.vo.tp.*; import com.cool.store.vo.tp.mini.*; import com.github.pagehelper.PageHelper; @@ -30,13 +40,24 @@ import com.github.pagehelper.PageInfo; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import com.alibaba.excel.EasyExcel; + +import javax.annotation.Resource; +import java.io.ByteArrayInputStream; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + +import static com.cool.store.utils.poi.DateUtils.SPECIAL_DATE_START_1; /** *

@@ -58,6 +79,14 @@ public class TpApplyServiceImpl implements TpApplyService { private final DictService dictService; private final TpScoreJournalDAO tpScoreJournalDAO; private final EnterpriseUserDAO enterpriseUserDAO; + private final RedisUtilPool redisUtilPool; + private final OssClientService ossClientService; + private final ImportTaskMapper importTaskMapper; + @Resource(name = "generalThreadPool") + private ThreadPoolTaskExecutor executor; + private final EasyExcelUtil easyExcelUtil; + @Value("${mybatis.configuration.variables.enterpriseId}") + private String eid; @Override @Transactional @@ -81,6 +110,7 @@ public class TpApplyServiceImpl implements TpApplyService { formDO.setType(TpFormTypeEnum.REWARD.getType()); formDO.setPayStatus(TpPayStatusEnum.NO_NEED_PAY.getStatus()); } + formDO.setStatus(isDraft ? TpFormStatusEnum.DRAFT.getStatus() : TpFormStatusEnum.PENDING.getStatus()); fillRuleFields(formDO); tpApplyFormDAO.insertOrUpdate(formDO); // 第一次提交后添加审批记录 @@ -126,6 +156,7 @@ public class TpApplyServiceImpl implements TpApplyService { throw new ServiceException(ErrorCodeEnum.TP_EXISTS_PENDING_APPLY); } fillRuleFields(formDO); + formDO.setStatus(isDraft ? TpFormStatusEnum.DRAFT.getStatus() : TpFormStatusEnum.PENDING.getStatus()); formDO.setApplyNo(Objects.isNull(request.getId()) ? TpHelper.generateApplyNo(formDO.getType()) : null); tpApplyFormDAO.insertOrUpdate(formDO); // 第一次提交后添加审批记录 @@ -171,7 +202,7 @@ public class TpApplyServiceImpl implements TpApplyService { if (!TpFormStatusEnum.PENDING.getStatus().equals(formDO.getStatus())) { throw new ServiceException(ErrorCodeEnum.TP_APPLY_AUDIT_COMPLETED); } - if (tpApplyFormDAO.existPassRewardForm(formDO.getStoreId(), formDO.getRuleId())) { + if (CommonConstants.INDEX_ONE.equals(request.getAuditStatus()) && tpApplyFormDAO.existPassRewardForm(formDO.getStoreId(), formDO.getRuleId())) { throw new ServiceException(ErrorCodeEnum.TP_MONTH_EXIST_APPLY); } auditCommon(request, formDO); @@ -220,6 +251,7 @@ public class TpApplyServiceImpl implements TpApplyService { formDO.setRuleId(penaltyFormDO.getRuleId()); formDO.setType(TpFormTypeEnum.APPEAL.getType()); formDO.setStoreId(penaltyFormDO.getStoreId()); + formDO.setStatus(isDraft ? TpFormStatusEnum.DRAFT.getStatus() : TpFormStatusEnum.PENDING.getStatus()); fillRuleFields(formDO); tpApplyFormDAO.insertOrUpdate(formDO); // 第一次提交后添加审批记录 @@ -307,7 +339,9 @@ public class TpApplyServiceImpl implements TpApplyService { @Override public MiniTpRewardApplyVO getMiniRewardApplyDetail(Long applyId) { TpApplyFormDO formDO = tpApplyFormDAO.getEffectiveById(applyId); - return BeanUtil.toBean(formDO, MiniTpRewardApplyVO.class); + MiniTpRewardApplyVO vo = BeanUtil.toBean(formDO, MiniTpRewardApplyVO.class); + dictService.fillDictField(vo); + return vo; } @Override @@ -315,7 +349,7 @@ public class TpApplyServiceImpl implements TpApplyService { TpApplyFormDO formDO = tpApplyFormDAO.getEffectiveById(applyId); if (Objects.nonNull(formDO)) { MiniTpPenaltyApplyVO vo = BeanUtil.toBean(formDO, MiniTpPenaltyApplyVO.class); - TpApplyFormDO appealForm = tpApplyFormDAO.getAppealByPenaltyId(formDO.getPenaltyId()); + TpApplyFormDO appealForm = tpApplyFormDAO.getAppealByPenaltyId(formDO.getId()); vo.setAppeal(BeanUtil.toBean(appealForm, MiniTpAppealVO.class)); dictService.fillDictField(vo); return vo; @@ -366,6 +400,19 @@ public class TpApplyServiceImpl implements TpApplyService { return true; } + @Override + public Boolean withdrawAppeal(Long applyId) { + TpApplyFormDO formDO = tpApplyFormDAO.getById(applyId); + if (Objects.isNull(formDO) || !TpFormTypeEnum.APPEAL.getType().equals(formDO.getType())) { + throw new ServiceException(ErrorCodeEnum.TP_NOT_EXIST_APPLY_FORM); + } + if (!TpFormStatusEnum.PENDING.getStatus().equals(formDO.getStatus()) && !TpFormStatusEnum.DRAFT.getStatus().equals(formDO.getStatus())) { + throw new ServiceException(ErrorCodeEnum.TP_APPLY_AUDIT_COMPLETED); + } + tpApplyFormDAO.deleteByIds(Collections.singletonList(applyId)); + return true; + } + /** * 审批通用方法 */ @@ -374,6 +421,7 @@ public class TpApplyServiceImpl implements TpApplyService { // 修改申请单审批数据 formDO.setStatus(CommonConstants.INDEX_ONE.equals(request.getAuditStatus()) ? TpFormStatusEnum.PASS.getStatus() : TpFormStatusEnum.REJECT.getStatus()); formDO.setApproveTime(now); + formDO.setApproveUserId(CurrentUserHolder.getUserId()); tpApplyFormDAO.updateSelective(formDO); LoginUserInfo user = CurrentUserHolder.getUser(); // 处理审批记录 @@ -420,6 +468,13 @@ public class TpApplyServiceImpl implements TpApplyService { } // 修改门店积分 if (Objects.nonNull(occurAfterScore)) { + // 限制积分在0-12之间 + if (occurAfterScore.compareTo(BigDecimal.valueOf(12)) > 0) { + occurAfterScore = BigDecimal.valueOf(12); + } + if (occurAfterScore.compareTo(BigDecimal.ZERO) < 0) { + occurAfterScore = BigDecimal.ZERO; + } storeDao.updateStoreScore(formDO.getStoreId(), occurAfterScore); StoreDO storeDO = storeDao.getEffectiveByStoreId(formDO.getStoreId()); if (Objects.isNull(storeDO)) { @@ -431,6 +486,124 @@ public class TpApplyServiceImpl implements TpApplyService { } } + @Override + public TpStoreScoreVO getStoreScore(String storeId) { + StoreDO storeDO = storeDao.getEffectiveByStoreId(storeId); + BigDecimal score = storeDao.getStoreScore(storeId); + return new TpStoreScoreVO(storeDO.getStoreName(), storeDO.getAvatar(), score); + } + + @Override + @Transactional + public List batchAudit(TpBatchAuditRequest request) { + List result = new ArrayList<>(); + TpFormTypeEnum type = TpFormTypeEnum.getByType(request.getType()); + if (Objects.isNull(type)) { + throw new ServiceException(ErrorCodeEnum.TP_NOT_EXIST_FORM_TYPE); + } + for (Long applyId : request.getApplyIds()) { + boolean f = false; + String failReason = null; + try { + switch (type) { + case REWARD: + f = rewardAudit(new TpApplyAuditRequest(applyId, request.getAuditStatus(), request.getRemark())); + break; + case PENALTY: + case WARNING: + f = penaltyAudit(new TpApplyAuditRequest(applyId, request.getAuditStatus(), request.getRemark())); + break; + case APPEAL: + f = appealAudit(new TpApplyAuditRequest(applyId, request.getAuditStatus(), request.getRemark())); + break; + } + if (!f) { + failReason = "未知错误,请联系管理员"; + } + } catch (ServiceException e) { + failReason = e.getErrorMessage(); + } catch (Exception e) { + failReason = "未知错误,请联系管理员"; + log.error("申请单批量审批失败,applyId:{}", applyId, e); + } + result.add(new TpBatchAuditVO(applyId, f ? 1 : 2, failReason)); + } + List applyIds = CollStreamUtil.toList(result, TpBatchAuditVO::getApplyId); + List forms = tpApplyFormDAO.getByIds(applyIds); + Map applyNoMap = CollStreamUtil.toMap(forms, TpApplyFormDO::getId, TpApplyFormDO::getApplyNo); + result.forEach(v -> v.setApplyNo(applyNoMap.get(v.getApplyId()))); + return result; + } + + /** + * 惩处申请单Excel导入(异步执行,立即返回) + */ + @Override + public Boolean penaltyImport(MultipartFile file) { + final String lockKey = RedisConstant.TP_PENALTY_APPLY_IMPORT_LOCK; + boolean lock = redisUtilPool.setNxExpire(lockKey, UUIDUtils.get32UUID(), 30 * 60 * 1000); + if (!lock) { + throw new ServiceException(ErrorCodeEnum.TP_EXIST_PENDING_IMPORT_TASK); + } + ImportTaskDO importTaskDO = new ImportTaskDO(); + importTaskDO.setFileName(file.getOriginalFilename()); + importTaskDO.setFileType(FileTypeEnum.TP_PENALTY_IMPORT.getFileType()); + importTaskDO.setIsImport(true); + importTaskDO.setStatus(ImportTaskStatusEnum.PROGRESS.getCode()); + importTaskDO.setCreateUserId(CurrentUserHolder.getUserId()); + importTaskDO.setCreateName(CurrentUserHolder.getUser().getName()); + importTaskDO.setCreateTime(System.currentTimeMillis()); + importTaskMapper.insert(eid, importTaskDO); + LoginUserInfo user = CurrentUserHolder.getUser(); + try { + // 图片是额外读取文件操作,这里使用异步会导致临时文件被清理,因此改成字节数组传参 + byte[] excelBytes = file.getBytes(); + executor.execute(() -> importPenalty(excelBytes, importTaskDO, user)); + } catch (Exception e) { + log.error("导入失败"); + } + return true; + } + + private void importPenalty(byte[] excelBytes, ImportTaskDO importTaskDO, LoginUserInfo user) { + List errorList = new ArrayList<>(); + AtomicInteger successNum = new AtomicInteger(); + AtomicInteger totalNum = new AtomicInteger(); + try { + EasyExcel.read(new ByteArrayInputStream(excelBytes), TpPenaltyImportRowDTO.class, + new TpPenaltyImportListener(this, tpRuleDAO, storeDao, ossClientService, errorList, user, excelBytes, totalNum, successNum)) + .sheet(0) + .headRowNumber(2) + .doRead(); + } catch (Exception e) { + log.error("惩处申请单导入失败", e); + } finally { + try { + final String lockKey = RedisConstant.TP_PENALTY_APPLY_IMPORT_LOCK; + String value = redisUtilPool.getString(lockKey); + if (StringUtils.isNotBlank(value)) { + redisUtilPool.delKey(lockKey); + } + } catch (Exception ex) { + log.error("释放惩处申请导入锁异常", ex); + } + } + importTaskDO.setStatus(totalNum.get() == successNum.get() ? ImportTaskStatusEnum.SUCCESS.getCode() : ImportTaskStatusEnum.ERROR.getCode()); + importTaskDO.setTotalNum(totalNum.get()); + importTaskDO.setSuccessNum(successNum.get()); + if (CollectionUtils.isNotEmpty(errorList)) { + try { + String url = easyExcelUtil.exportExcel(ImportOaOldShopDataErrorDTO.class, errorList, null, + FileTypeEnum.TP_PENALTY_ERROR_EXPORT.getDesc() + DateUtils.parseDateToStr(SPECIAL_DATE_START_1, new Date()), + FileTypeEnum.TP_PENALTY_ERROR_EXPORT.getDesc() + DateUtils.parseDateToStr(SPECIAL_DATE_START_1, new Date())); + importTaskDO.setFileUrl(url); + } catch (Exception e) { + log.info("导出失败列表失败 errorList:{}", JSONObject.toJSONString(errorList)); + } + } + importTaskMapper.update(eid, importTaskDO); + } + /** * 填充规则相关字段 */ diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/tp/impl/TpPenaltyImportListener.java b/coolstore-partner-service/src/main/java/com/cool/store/service/tp/impl/TpPenaltyImportListener.java new file mode 100644 index 000000000..467f40c43 --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/tp/impl/TpPenaltyImportListener.java @@ -0,0 +1,208 @@ +package com.cool.store.service.tp.impl; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.CellExtra; +import com.alibaba.excel.read.listener.ReadListener; +import com.cool.store.context.LoginUserInfo; +import com.cool.store.dao.StoreDao; +import com.cool.store.dao.tp.TpRuleDAO; +import com.cool.store.dto.tp.TpPenaltyImportErrorDTO; +import com.cool.store.entity.StoreDO; +import com.cool.store.entity.tp.TpRuleDO; +import com.cool.store.exception.ServiceException; +import com.cool.store.oss.OssClientService; +import com.cool.store.request.tp.TpApplyRequest; +import com.cool.store.request.tp.TpPenaltyImportRowDTO; +import com.cool.store.service.tp.TpApplyService; +import com.cool.store.utils.CoolDateUtils; +import com.cool.store.utils.UUIDUtils; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.ClientAnchor; +import org.apache.poi.xssf.usermodel.*; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.time.LocalDate; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +/** + * 扣分申请单导入监听器 + */ +@RequiredArgsConstructor +@Slf4j +public class TpPenaltyImportListener implements ReadListener { + + /** + * 证明图片起始列索引(从0开始,G列=6) + */ + private static final int IMAGE_COL_START_INDEX = 6; + /** + * 证明图片结束列索引(L列=11) + */ + private static final int IMAGE_COL_END_INDEX = 11; + /** + * 每行最多图片数量 + */ + private static final int MAX_IMAGE_PER_ROW = 6; + + private final TpApplyService tpApplyService; + private final TpRuleDAO tpRuleDAO; + private final StoreDao storeDao; + private final OssClientService ossClientService; + private final List errorList; + private final LoginUserInfo user; + private final byte[] excelBytes; + private final AtomicInteger totalNum; + private final AtomicInteger successNum; + + private final Map> pictureMap = new HashMap<>(); + private volatile boolean pictureParsed = false; + + + @Override + public void onException(Exception e, AnalysisContext analysisContext) { + log.error("导入失败", e); + } + + @Override + public void invokeHead(Map map, AnalysisContext analysisContext) { + // head会回调多次,图片解析只做一次 + if (pictureParsed) { + return; + } + try { + XSSFWorkbook book = new XSSFWorkbook(new ByteArrayInputStream(excelBytes)); + XSSFSheet sheet = book.getSheetAt(0); + if (Objects.isNull(sheet)) { + log.error("读取失败"); + } + + // 获取所有图片 + XSSFDrawing drawingPatriarch = sheet.getDrawingPatriarch(); + if (Objects.isNull(drawingPatriarch)) { + throw new RuntimeException("excel表格中没有图片,请补充"); + } + List shapes = drawingPatriarch.getShapes(); + if (CollectionUtils.isEmpty(shapes)) { + log.info("表格中没有图片"); + } + List pictures = shapes.stream() + .filter(shape -> shape instanceof XSSFPicture) + .map(shape -> (XSSFPicture) shape) + .collect(Collectors.toList()); + if (pictures.isEmpty()) { + return; + } + + // 查找指定单元格中的图片 + String fileNamePrefix = UUIDUtils.get32UUID(); + for (XSSFPicture picture : pictures) { + ClientAnchor anchor = picture.getPreferredSize(); + int row = anchor.getRow1(); + int col = anchor.getCol1(); + // 检查图片是否在指定单元格中 + if (IMAGE_COL_START_INDEX <= col && col <= IMAGE_COL_END_INDEX) { + XSSFPictureData pictureData = picture.getPictureData(); + byte[] data = pictureData.getData(); + // 获取图片后缀 + String fileName = fileNamePrefix + "-" + (row + 1) + "-" + (col + 1) + ".jpg"; + try (InputStream in = new ByteArrayInputStream(data)) { + String url = ossClientService.putObjectWithoutPrefix(fileName, in, (long) data.length, "image/jpeg"); + pictureMap.compute(row, (key, value) -> { + if (value == null) { + value = new ArrayList<>(); + } + value.add(url); + return value; + }); + } catch (Exception e) { + log.error("第{}行图片上传失败", row + 1, e); + } + } + } + pictureParsed = true; + } catch (Exception e) { + log.error("图片解析失败", e); + } + } + + @Override + public void invoke(TpPenaltyImportRowDTO data, AnalysisContext context) { + totalNum.incrementAndGet(); + int rowIndex = context.readRowHolder().getRowIndex(); + + // 基础必填校验 + if (data == null) { + return; + } + if (data.getStoreNum() == null || data.getStoreNum().trim().isEmpty()) { + errorList.add(new TpPenaltyImportErrorDTO(data.getStoreNum(), data.getRuleNo(), "门店编码为空")); + return; + } + if (data.getRuleNo() == null || data.getRuleNo().trim().isEmpty()) { + errorList.add(new TpPenaltyImportErrorDTO(data.getStoreNum(), data.getRuleNo(), "行惩处规则编码为空")); + return; + } + + // 根据门店编码查询门店 + StoreDO store = storeDao.getByStoreNum(data.getStoreNum()); + if (store == null) { + errorList.add(new TpPenaltyImportErrorDTO(data.getStoreNum(), data.getRuleNo(), "门店编码不存在")); + return; + } + + // 根据规则编码查询规则 + TpRuleDO rule = tpRuleDAO.getEnableByCode(data.getRuleNo()); + if (rule == null) { + errorList.add(new TpPenaltyImportErrorDTO(data.getStoreNum(), data.getRuleNo(), "惩处规则编码不存在")); + return; + } + + TpApplyRequest request = new TpApplyRequest(); + request.setStoreId(store.getStoreId()); + request.setRuleId(rule.getId()); + request.setRemark(data.getRemark()); + request.setIsDraft(0); + request.setSource(0); + request.setApplyUserId(user.getUserId()); + request.setApplyUserName(user.getName()); + List proofUrls = pictureMap.getOrDefault(rowIndex, Collections.emptyList()); + request.setProofUrls(String.join(",", proofUrls.subList(0, Math.min(proofUrls.size(), MAX_IMAGE_PER_ROW)))); + request.setScore(data.getScore()); + request.setAmount(data.getAmount()); + if (Objects.nonNull(data.getAppealDeadline())) { + request.setAppealEndDate(CoolDateUtils.localDate2Date(LocalDate.now().plusDays(data.getAppealDeadline()))); + } + try { + tpApplyService.penaltyApplySubmit(request); + successNum.incrementAndGet(); + } catch (ServiceException e) { + errorList.add(new TpPenaltyImportErrorDTO(data.getStoreNum(), data.getRuleNo(), e.getErrorMessage())); + } catch (Exception e) { + log.error("申请单创建失败", e); + errorList.add(new TpPenaltyImportErrorDTO(data.getStoreNum(), data.getRuleNo(), "数据异常")); + } + } + + @Override + public void extra(CellExtra cellExtra, AnalysisContext analysisContext) { + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + // ignore + } + + @Override + public boolean hasNext(AnalysisContext analysisContext) { + return true; + } +} + + 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 74216d6da..699c765f9 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,14 +2,17 @@ package com.cool.store.controller.webb; import com.cool.store.common.PageBasicInfo; import com.cool.store.context.CurrentUserHolder; +import com.cool.store.request.store.StoreListRequest; import com.cool.store.request.UserStoreRequest; import com.cool.store.response.MiniShopsResponse; import com.cool.store.response.ResponseResult; import com.cool.store.service.StoreService; +import com.cool.store.vo.store.StoreListVO; import com.github.pagehelper.PageInfo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; /** @@ -32,4 +35,11 @@ public class PCStoreController { public ResponseResult> getCurrentUserStoreList(@RequestBody UserStoreRequest request) { return ResponseResult.success(storeService.getStoreListByMobile(CurrentUserHolder.getUser().getMobile(), request.getPageNum(), request.getPageSize(), request.getKeyword(), null)); } + + @ApiOperation("当前用户管辖下的门店列表") + @PostMapping("/storeList") + public ResponseResult> getStoreList(@RequestBody @Validated StoreListRequest request) { + return ResponseResult.success(storeService.getAuthStoreList(request)); + } + } diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/TpApplyController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/TpApplyController.java index be06ab8c6..6f57f6b8e 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/TpApplyController.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/TpApplyController.java @@ -3,10 +3,7 @@ package com.cool.store.controller.webb; import com.cool.store.context.CurrentUserHolder; import com.cool.store.context.LoginUserInfo; import com.cool.store.enums.tp.TpFormTypeEnum; -import com.cool.store.request.tp.TpAppealApplyRequest; -import com.cool.store.request.tp.TpApplyAuditRequest; -import com.cool.store.request.tp.TpApplyQueryRequest; -import com.cool.store.request.tp.TpApplyRequest; +import com.cool.store.request.tp.*; import com.cool.store.response.AuditInfoResponse; import com.cool.store.response.ResponseResult; import com.cool.store.service.tp.TpApplyService; @@ -18,6 +15,7 @@ import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.validation.constraints.NotNull; import java.util.List; @@ -86,7 +84,7 @@ public class TpApplyController { @ApiOperation("惩处申请单分页查询") @PostMapping("/penaltyPage") - public ResponseResult > penaltyPage(@RequestBody TpApplyQueryRequest request) { + public ResponseResult> penaltyPage(@RequestBody TpApplyQueryRequest request) { request.setIsPenalty(true); return ResponseResult.success(tpApplyService.penaltyPage(request)); } @@ -146,4 +144,16 @@ public class TpApplyController { public ResponseResult completePayment(@NotNull(message = "申请单id不能为空") Long applyId) { return ResponseResult.success(tpApplyService.completePayment(applyId)); } + + @ApiOperation("惩处申请单Excel导入") + @PostMapping("/penaltyImport") + public ResponseResult penaltyImport(MultipartFile file) { + return ResponseResult.success(tpApplyService.penaltyImport(file)); + } + + @ApiOperation("批量审批") + @PostMapping("/batchAudit") + public ResponseResult> batchAudit(@RequestBody @Validated TpBatchAuditRequest request) { + return ResponseResult.success(tpApplyService.batchAudit(request)); + } } diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/TpRuleController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/TpRuleController.java index 2cd12bb3b..7d3c9f587 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/TpRuleController.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/TpRuleController.java @@ -4,6 +4,7 @@ import com.cool.store.common.InsertGroup; import com.cool.store.common.UpdateGroup; import com.cool.store.request.tp.TpPenaltyRuleUpdateRequest; import com.cool.store.request.tp.TpRewardRuleUpdateRequest; +import com.cool.store.request.tp.TpRuleEnableRequest; import com.cool.store.request.tp.TpRuleQueryRequest; import com.cool.store.response.ResponseResult; import com.cool.store.service.tp.TpRuleService; @@ -96,13 +97,7 @@ public class TpRuleController { @ApiOperation("启用规则") @PostMapping("/enable") - public ResponseResult enableRuleByIds(@RequestBody List ruleIds) { - return ResponseResult.success(tpRuleService.enableRuleByIds(ruleIds, 1)); - } - - @ApiOperation("禁用规则") - @PostMapping("/disable") - public ResponseResult disableRuleByIds(@RequestBody List ruleIds) { - return ResponseResult.success(tpRuleService.enableRuleByIds(ruleIds, 0)); + public ResponseResult enableRuleByIds(@RequestBody @Validated TpRuleEnableRequest request) { + return ResponseResult.success(tpRuleService.enableRuleByIds(request.getRuleIds(), request.getStatus())); } } diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniTpApplyController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniTpApplyController.java index 8f83e8c51..5f9747071 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniTpApplyController.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniTpApplyController.java @@ -2,14 +2,12 @@ package com.cool.store.controller.webc; import com.cool.store.context.PartnerUserHolder; import com.cool.store.enums.tp.TpFormTypeEnum; -import com.cool.store.request.tp.TpAppealApplyRequest; -import com.cool.store.request.tp.TpApplyQueryRequest; -import com.cool.store.request.tp.TpApplyRequest; -import com.cool.store.request.tp.TpRuleQueryRequest; +import com.cool.store.request.tp.*; import com.cool.store.response.AuditInfoResponse; import com.cool.store.response.ResponseResult; import com.cool.store.service.tp.TpApplyService; import com.cool.store.vo.PartnerUserInfoVO; +import com.cool.store.vo.tp.TpStoreScoreVO; import com.cool.store.vo.tp.mini.MiniTpApplyListVO; import com.cool.store.vo.tp.mini.MiniTpPenaltyApplyVO; import com.cool.store.vo.tp.mini.MiniTpRewardApplyVO; @@ -17,12 +15,15 @@ import com.cool.store.vo.tp.mini.MiniTpRuleListVO; import com.github.pagehelper.PageInfo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; +import java.math.BigDecimal; import java.util.List; /** @@ -37,6 +38,7 @@ import java.util.List; @RestController @RequestMapping("/mini/tp/apply") @RequiredArgsConstructor +@Validated public class MiniTpApplyController { private final TpApplyService tpApplyService; @@ -97,19 +99,28 @@ public class MiniTpApplyController { } @ApiOperation("规则分页查询") - @GetMapping("/rulePage") - @ApiImplicitParam(name = "type", value = "规则类型,0惩处 1加分", required = true, dataType = "Integer", paramType = "query") - public ResponseResult> rewardRulePage(@NotNull(message = "规则类型不能为空") Integer type) { - TpRuleQueryRequest request = new TpRuleQueryRequest(); - request.setType(type); + @PostMapping("/rulePage") + public ResponseResult> rewardRulePage(@RequestBody TpRuleQueryRequest request) { request.setStatus(1); return ResponseResult.success(tpApplyService.getMiniRulePage(request)); } @ApiOperation("认罚缴款") @PostMapping("/acceptPenalty") - @ApiImplicitParam(name = "applyId", value = "惩处申请单id", required = true, dataType = "Long", paramType = "query") - public ResponseResult acceptPenalty(@NotNull(message = "惩处申请单id不能为空") Long applyId) { - return ResponseResult.success(tpApplyService.acceptPenalty(applyId)); + public ResponseResult acceptPenalty(@RequestBody @Validated TpApplyIdRequest request) { + return ResponseResult.success(tpApplyService.acceptPenalty(request.getApplyId())); + } + + @ApiOperation("撤销复议申请") + @PostMapping("/withdrawAppeal") + public ResponseResult withdrawAppeal(@RequestBody @Validated TpApplyIdRequest request) { + return ResponseResult.success(tpApplyService.withdrawAppeal(request.getApplyId())); + } + + @ApiOperation("门店积分") + @GetMapping("/storeScore") + @ApiImplicitParam(name = "storeId", value = "门店id", required = true, dataType = "String", paramType = "query") + public ResponseResult storeScore(@NotBlank(message = "门店id不能为空") String storeId) { + return ResponseResult.success(tpApplyService.getStoreScore(storeId)); } } diff --git a/coolstore-partner-web/src/main/resources/application-local.properties b/coolstore-partner-web/src/main/resources/application-local.properties index 86cd2a019..04227de1e 100644 --- a/coolstore-partner-web/src/main/resources/application-local.properties +++ b/coolstore-partner-web/src/main/resources/application-local.properties @@ -46,14 +46,14 @@ rocketmq.orderTopic=zx_order_message oss.excelFile.dir=lineExcel/ oss.accessKeyId=LTAI5tGBwmXwZkMuHK4MudMJ oss.accessKeySecret=bnZoUMRQ9834STgz5E291YrqlBu6yn -oss.bucket=store-ossfile +oss.bucket=store-ossfile-zx oss.file.dir=eid/${mybatis.configuration.variables.enterpriseId}/ oss.endpoint=oss-cn-hangzhou.aliyuncs.com oss.host=https://oss-cool.coolstore.cn/ #cdn地址 -cdn.url=https://oss-cool.coolstore.cn +cdn.url=https://ossfilezx.coolstore.cn/ #TRTC trtc.sdkAppId=1600026212 @@ -150,4 +150,18 @@ 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 + +huoMa.token.url = https://www.huoMayunping.com/api/SAASLogin/merchant +huoMa.id.url = https://www.huomayunping.com/api/reportCenter/executeSql +huoMa.store.device.detail.url = https://www.huomayunping.com/api/terminal/search +huoMa.get.point.terminal.url = https://www.huoMayunping.com/api/terminal/getPointTerminalInfos +huoMa.get.tag.url = https://www.huomayunping.com/api/tag/search +huoMa.get.program.url = https://www.huomayunping.com/api/program/search +huoMa.get.publish.url = https://www.huomayunping.com/api/channelPublish/target/v2/quick-publish +huoMa.direct.stores.account = 18375320931 +huoMa.direct.stores.password = Huoma@123456. +huoMa.franchise.stores.account = 13345565081 +huoMa.franchise.stores.password = Huoma@123456. +huoMa.restaurant.stores.account = 15167817007 +huoMa.restaurant.stores.password = Huoma@123456. \ No newline at end of file