From 19bce915ac2fe7d997e9f5751f4102f26b46109e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=9D=9E=E5=87=A1?= Date: Wed, 15 Apr 2026 08:23:40 +0000 Subject: [PATCH] Merge #99 into master from cc_20260408_close_up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat:歇业管理 * cc_20260408_close_up: (18 commits squashed) - fix:歇业管理(部分) - fix:歇业管理(部分) - fix:审批逻辑修改;拒绝审批实现 - fix:恢复开业申请及审批 - fix:主流程补充 - fix:主流程补充 - fix:字段补充及逻辑修改 - fix:字段补充 - fix - fix:平台处理新增字段 - fix - Merge remote-tracking branch 'origin/cc_20260408_close_up' into cc_20260408_close_up - fix:歇业营业发送短信 - fix:排序 - fix:详情接口新增加盟商手机号字段;申请单日期和已有申请单存在交集时申请失败 - fix:申请单详情接口新增品牌字段 - fix:新增列表筛选条件;审批单状态校验 - Merge branch 'master' into cc_20260408_close_up # Conflicts: # coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java Signed-off-by: 王非凡 Merged-by: 正新 CR-link: https://codeup.aliyun.com/692ea314dec569489f6f167c/hangzhou/java/custom_zxjp/change/99 --- .../com/cool/store/enums/ErrorCodeEnum.java | 12 + .../cool/store/enums/RocketMqGroupEnum.java | 1 + .../com/cool/store/enums/RocketMqTagEnum.java | 1 + .../cool/store/enums/SmsNoticeTypeEnum.java | 27 + .../com/cool/store/enums/SmsSignEnum.java | 24 + .../enums/closeup/CloseUpPlatformEnum.java | 43 ++ .../enums/closeup/CloseUpStatusEnum.java | 42 ++ .../java/com/cool/store/utils/BeanUtil.java | 10 + .../java/com/cool/store/dao/StoreDao.java | 21 + .../dao/closeup/CloseUpApplyFormDAO.java | 99 +++ .../dao/closeup/CloseUpAuditRecordDAO.java | 136 ++++ .../store/dao/closeup/CloseUpPlatformDAO.java | 87 +++ .../com/cool/store/mapper/StoreMapper.java | 5 + .../closeup/CloseUpApplyFormMapper.java | 24 + .../closeup/CloseUpAuditRecordMapper.java | 7 + .../mapper/closeup/CloseUpPlatformMapper.java | 17 + .../src/main/resources/mapper/StoreMapper.xml | 13 + .../mapper/closeup/CloseUpApplyFormMapper.xml | 108 ++++ .../closeup/CloseUpAuditRecordMapper.xml | 22 + .../mapper/closeup/CloseUpPlatformMapper.xml | 44 ++ .../entity/closeup/CloseUpApplyFormDO.java | 112 ++++ .../entity/closeup/CloseUpAuditRecordDO.java | 100 +++ .../entity/closeup/CloseUpPlatformDO.java | 78 +++ .../request/closeup/CloseUpApplyRequest.java | 41 ++ .../CloseUpApplySimpleQueryRequest.java | 22 + .../request/closeup/CloseUpAuditRequest.java | 30 + .../closeup/CloseUpOpenApplyRequest.java | 32 + .../closeup/CloseUpPlatformHandleRequest.java | 25 + .../request/closeup/CloseUpQueryRequest.java | 55 ++ .../closeup/CloseUpTodoQueryRequest.java | 22 + .../vo/closeup/CloseUpApplyFormSimpleVO.java | 89 +++ .../store/vo/closeup/CloseUpApplyFormVO.java | 92 +++ .../store/vo/closeup/CloseUpPlatformVO.java | 33 + .../store/mq/consumer/ConsumerClient.java | 15 + .../CloseUpApplyStoreUpdateListener.java | 53 ++ .../close/impl/CloseStoreServiceImpl.java | 8 +- .../store/service/closeup/CloseUpService.java | 87 +++ .../service/closeup/PlatformAutoStrategy.java | 18 + .../closeup/impl/CloseUpServiceImpl.java | 591 ++++++++++++++++++ .../impl/DefaultPlatformAutoStrategy.java | 30 + .../closeup/impl/PlatformAutoFactory.java | 32 + .../store/service/impl/CommonService.java | 33 +- .../store/service/sms/AliyunSmsService.java | 6 + .../sms/impl/AliyunSmsServiceImpl.java | 7 + .../controller/webb/CloseUpController.java | 91 +++ .../webc/MiniCloseUpController.java | 56 ++ .../main/resources/application-ab.properties | 2 + .../main/resources/application-hd.properties | 2 + .../resources/application-local.properties | 2 + .../resources/application-online.properties | 2 + .../resources/application-test.properties | 2 + 51 files changed, 2502 insertions(+), 9 deletions(-) create mode 100644 coolstore-partner-common/src/main/java/com/cool/store/enums/SmsNoticeTypeEnum.java create mode 100644 coolstore-partner-common/src/main/java/com/cool/store/enums/SmsSignEnum.java create mode 100644 coolstore-partner-common/src/main/java/com/cool/store/enums/closeup/CloseUpPlatformEnum.java create mode 100644 coolstore-partner-common/src/main/java/com/cool/store/enums/closeup/CloseUpStatusEnum.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/dao/closeup/CloseUpApplyFormDAO.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/dao/closeup/CloseUpAuditRecordDAO.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/dao/closeup/CloseUpPlatformDAO.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/mapper/closeup/CloseUpApplyFormMapper.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/mapper/closeup/CloseUpAuditRecordMapper.java create mode 100644 coolstore-partner-dao/src/main/java/com/cool/store/mapper/closeup/CloseUpPlatformMapper.java create mode 100644 coolstore-partner-dao/src/main/resources/mapper/closeup/CloseUpApplyFormMapper.xml create mode 100644 coolstore-partner-dao/src/main/resources/mapper/closeup/CloseUpAuditRecordMapper.xml create mode 100644 coolstore-partner-dao/src/main/resources/mapper/closeup/CloseUpPlatformMapper.xml create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/entity/closeup/CloseUpApplyFormDO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/entity/closeup/CloseUpAuditRecordDO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/entity/closeup/CloseUpPlatformDO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpApplyRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpApplySimpleQueryRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpAuditRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpOpenApplyRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpPlatformHandleRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpQueryRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpTodoQueryRequest.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/closeup/CloseUpApplyFormSimpleVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/closeup/CloseUpApplyFormVO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/vo/closeup/CloseUpPlatformVO.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/mq/consumer/listener/CloseUpApplyStoreUpdateListener.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/service/closeup/CloseUpService.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/service/closeup/PlatformAutoStrategy.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/service/closeup/impl/CloseUpServiceImpl.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/service/closeup/impl/DefaultPlatformAutoStrategy.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/service/closeup/impl/PlatformAutoFactory.java create mode 100644 coolstore-partner-web/src/main/java/com/cool/store/controller/webb/CloseUpController.java create mode 100644 coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniCloseUpController.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 a03ccd22d..9f0155cab 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 @@ -478,6 +478,18 @@ public enum ErrorCodeEnum { IP_LIMIT(1840000, "IP访问次数超限", null), + + CLOSE_UP_CLOSED_DOWN(1840000, "门店已歇业", null), + CLOSE_UP_ONLY_SUPPORT_OPEN(1840001, "仅支持在营门店发起歇业申请", null), + CLOSE_UP_EXIST_ONGOING_RECORD(18400002,"该日期下当前门店有进行中的申请,请确认!",null), + CLOSE_UP_AUDIT_RECORD_NOT_EXIST(1840003, "审批记录不存在", null), + CLOSE_UP_FORM_NOT_EXIST(1840004, "申请单不存在", null), + CLOSE_UP_AUDIT_ACCESS_DENIED(1840005, "无权限审批", null), + CLOSE_UP_STORE_OPEN(1840006, "门店已营业", null), + CLOSE_UP_ONLY_SUPPORT_CLOSE_UP(1840007, "仅支持歇业门店发起营业申请", null), + CLOSE_UP_CLOSED_AUDIT_NOT_PASS(1840008, "歇业申请未通过", null), + CLOSE_UP_EXIST_OPEN_APPLY(1840009, "该歇业申请单已存在开业申请", null), + CLOSE_UP_APPROVED(1840010, "该申请单已审批", null), ; diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/RocketMqGroupEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/RocketMqGroupEnum.java index defb4596d..2d6e80929 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/enums/RocketMqGroupEnum.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/RocketMqGroupEnum.java @@ -39,6 +39,7 @@ public enum RocketMqGroupEnum { STORE_MASTER_ISSUE("store_master_issue", new ArrayList<>(Arrays.asList(RocketMqTagEnum.STORE_MASTER_ISSUE))), VISIT_RECORD_INVALID("visit_record_invalid", new ArrayList<>(Arrays.asList(RocketMqTagEnum.VISIT_RECORD_INVALID))), TP_PENALTY_APPEAL_OVERDUE("tp_penalty_appeal_overdue", new ArrayList<>(Arrays.asList(RocketMqTagEnum.TP_PENALTY_APPEAL_OVERDUE))), + CLOSE_UP_APPLY_STORE_UPDATE("close_up_apply_store_update", new ArrayList<>(Arrays.asList(RocketMqTagEnum.CLOSE_UP_APPLY_STORE_UPDATE))), ; private final String group; diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/RocketMqTagEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/RocketMqTagEnum.java index 72a14d4c1..f5cc0d64f 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/enums/RocketMqTagEnum.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/RocketMqTagEnum.java @@ -23,6 +23,7 @@ public enum RocketMqTagEnum { STORE_MASTER_ISSUE("store_master_issue","门店主数据下发"), VISIT_RECORD_INVALID("visit_record_invalid", "拜访记录失效"), TP_PENALTY_APPEAL_OVERDUE("tp_penalty_appeal_overdue", "十二分惩处单复议逾期"), + CLOSE_UP_APPLY_STORE_UPDATE("close_up_apply_store_update", "歇业申请修改门店状态"), ; diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/SmsNoticeTypeEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/SmsNoticeTypeEnum.java new file mode 100644 index 000000000..90a233f65 --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/SmsNoticeTypeEnum.java @@ -0,0 +1,27 @@ +package com.cool.store.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + *

+ * 短信通知模板 + *

+ * + * @author wangff + * @since 2026/4/13 + */ +@Getter +@AllArgsConstructor +public enum SmsNoticeTypeEnum { + CLOSE_UP_CLOSE_NOTICE("SMS_504775487", "歇业通知", SmsSignEnum.ZHENGXIN), + CLOSE_UP_OPEN_NOTICE("SMS_504845455", "恢复营业通知", SmsSignEnum.ZHENGXIN), + + ; + + private final String templateCode; + + private final String message; + + private final SmsSignEnum smsSign; +} diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/SmsSignEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/SmsSignEnum.java new file mode 100644 index 000000000..6f22559f0 --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/SmsSignEnum.java @@ -0,0 +1,24 @@ +package com.cool.store.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + *

+ * 短信签名 + *

+ * + * @author wangff + * @since 2026/4/13 + */ +@Getter +@AllArgsConstructor +public enum SmsSignEnum { + + ZHENGXIN("正新", "正新"), + ; + + private final String signName; + + private final String message; +} diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/closeup/CloseUpPlatformEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/closeup/CloseUpPlatformEnum.java new file mode 100644 index 000000000..1c1269e8f --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/closeup/CloseUpPlatformEnum.java @@ -0,0 +1,43 @@ +package com.cool.store.enums.closeup; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + *

+ * 歇业开业平台账号 + *

+ * + * @author wangff + * @since 2026/4/8 + */ +@Getter +@AllArgsConstructor +public enum CloseUpPlatformEnum { + DOUYINTG("douyintg", "抖音", 0, "https://ossfilezx.coolstore.cn/icon/closeup/douyin.png"), + ELEMEWM("elemewm", "饿了么", 0, "https://ossfilezx.coolstore.cn/icon/closeup/ele.png"), + HUOMA("huoma", "火码POS", 0, "https://ossfilezx.coolstore.cn/icon/closeup/huoma.png"), + JINGDONGWM("jingdongwm", "京东外卖", 0, "https://ossfilezx.coolstore.cn/icon/closeup/jingdong.png"), + KUAISHOUTG("kuaishoutg", "快手团购", 0, "https://ossfilezx.coolstore.cn/icon/closeup/kuaishou.png"), + MEITUANTG("meituantg", "美团团购", 0, "https://ossfilezx.coolstore.cn/icon/closeup/meituan.png"), + MEITUANWM("meituanwm", "美团外卖", 0, "https://ossfilezx.coolstore.cn/icon/closeup/meituanwx.png"), + ZHIFUBAO("zhifubao", "支付宝团购", 0, "https://ossfilezx.coolstore.cn/icon/closeup/zhifubao.png"), + ; + + /** + * 编码 + */ + private final String code; + /** + * 名称 + */ + private final String name; + /** + * 关闭类型 + */ + private final Integer type; + /** + * 图标地址 + */ + private final String icon; +} diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/closeup/CloseUpStatusEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/closeup/CloseUpStatusEnum.java new file mode 100644 index 000000000..003f2f618 --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/closeup/CloseUpStatusEnum.java @@ -0,0 +1,42 @@ +package com.cool.store.enums.closeup; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + *

+ * 歇业申请单状态 + *

+ * + * @author wangff + * @since 2026/4/8 + */ +@Getter +@AllArgsConstructor +public enum CloseUpStatusEnum { + APPROVAL(1, "审批中"), + REJECTED(5, "审批拒绝"), + PASS(10, "审批通过"), + + APPLY_OPEN(15, "申请营业中"), + APPLY_OPEN_REJECTED(20, "申请营业审批拒绝"), + APPLY_OPEN_PASS(25, "申请营业审批通过"), + ; + + private final Integer status; + + private final String desc; + + public static String getDesc(Integer status) { + for (CloseUpStatusEnum value : CloseUpStatusEnum.values()) { + if (value.status.equals(status)) { + return value.desc; + } + } + return null; + } + + public static boolean unPass(Integer status) { + return REJECTED.getStatus().equals(status) || APPROVAL.getStatus().equals(status); + } +} diff --git a/coolstore-partner-common/src/main/java/com/cool/store/utils/BeanUtil.java b/coolstore-partner-common/src/main/java/com/cool/store/utils/BeanUtil.java index 60afd26c8..108a8fd40 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/utils/BeanUtil.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/utils/BeanUtil.java @@ -53,6 +53,16 @@ public class BeanUtil extends cn.hutool.core.bean.BeanUtil { return newPage; } + public static PageInfo toPage(PageInfo page, List list) { + PageInfo newPage = new PageInfo<>(); + newPage.setPages(page.getPages()); + newPage.setTotal(page.getTotal()); + newPage.setPageNum(page.getPageNum()); + newPage.setPageSize(page.getPageSize()); + newPage.setList(list); + return newPage; + } + public static void copyPropertiesIgnoreId(Object source, Object target, String... ignoreProperties) { if (source == null || target == null) { return; 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 0a7f25f25..4e6ce8a7a 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 @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollStreamUtil; import com.cool.store.dto.store.StoreAddressDTO; import com.cool.store.dto.store.StoreOrderTimeDTO; import com.cool.store.entity.StoreDO; +import com.cool.store.enums.StoreStatusEnum; import com.cool.store.mapper.StoreMapper; import com.cool.store.response.MiniShopsResponse; import com.google.common.collect.Lists; @@ -176,6 +177,26 @@ public class StoreDao { storeMapper.updateStoreStatus(storeId,storeStatus,actualOpenDate); } + /** + * 暂停营业 + * @param storeId 门店id + * @param closeUpReason 暂停营业原因 + */ + public void closeUp(String storeId, String closeUpReason) { + if (storeMapper.updateStatus(storeId, StoreStatusEnum.CLOSE_UP.getValue()) > 0) { + storeMapper.insertOrUpdateCloseUpReason(storeId, closeUpReason); + } + } + + /** + * 暂停营业门店转在营 + */ + public void closeUpToOpen(String storeId) { + if (storeMapper.updateStatus(storeId, StoreStatusEnum.OPEN.getValue()) > 0) { + storeMapper.insertOrUpdateCloseUpReason(storeId, null); + } + } + /** * 门店状态改为闭店 * @param storeId 门店id diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/closeup/CloseUpApplyFormDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/closeup/CloseUpApplyFormDAO.java new file mode 100644 index 000000000..508e1914a --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/closeup/CloseUpApplyFormDAO.java @@ -0,0 +1,99 @@ +package com.cool.store.dao.closeup; + +import com.cool.store.entity.closeup.CloseUpApplyFormDO; +import com.cool.store.mapper.closeup.CloseUpApplyFormMapper; +import com.cool.store.request.closeup.CloseUpQueryRequest; +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 static com.cool.store.enums.closeup.CloseUpStatusEnum.APPROVAL; +import static com.cool.store.enums.closeup.CloseUpStatusEnum.REJECTED; + +/** + *

+ * 歇业开业申请单DAO + *

+ * + * @author wangff + * @since 2026/4/8 + */ +@Repository +@RequiredArgsConstructor +public class CloseUpApplyFormDAO { + private final CloseUpApplyFormMapper closeUpApplyFormMapper; + + public void insertOrUpdate(CloseUpApplyFormDO record) { + closeUpApplyFormMapper.insertOrUpdate(record); + } + + /** + * 是否存在进行中的申请 + */ + public boolean existOngoingRecord(String storeId, Integer type) { + Example example = new Example(CloseUpApplyFormDO.class); + example.createCriteria() + .andEqualTo("storeId", storeId) + .andEqualTo("type", type) + .andEqualTo("status", APPROVAL.getStatus()); + return closeUpApplyFormMapper.selectCountByExample(example) > 0; + } + + public CloseUpApplyFormDO getById(Long id) { + return closeUpApplyFormMapper.selectByPrimaryKey(id); + } + + public List getByIds(List ids) { + if (CollectionUtils.isEmpty(ids)) { + return Collections.emptyList(); + } + Example example = new Example(CloseUpApplyFormDO.class); + example.createCriteria().andIn("id", ids); + return closeUpApplyFormMapper.selectByExample(example); + } + + public void updateByPrimaryKeySelective(CloseUpApplyFormDO record) { + closeUpApplyFormMapper.updateByPrimaryKeySelective(record); + } + + public List getList(Long lineId, Integer type, String storeId) { + Example example = new Example(CloseUpApplyFormDO.class); + example.createCriteria() + .andEqualTo("lineId", lineId) + .andEqualTo("type", type) + .andEqualTo("storeId", storeId); + example.setOrderByClause("create_time DESC"); + return closeUpApplyFormMapper.selectByExample(example); + } + + public List getList(CloseUpQueryRequest request) { + return closeUpApplyFormMapper.getList(request); + } + + /** + * 歇业申请单存在开业申请 + */ + public boolean existOpenApply(Long sourceApplyId) { + Example example = new Example(CloseUpApplyFormDO.class); + example.createCriteria() + .andEqualTo("sourceApplyId", sourceApplyId) + .andNotEqualTo("status", REJECTED.getStatus()); + return closeUpApplyFormMapper.selectCountByExample(example) > 0; + } + + public CloseUpApplyFormDO getBySourceApplyId(Long sourceApplyId) { + return closeUpApplyFormMapper.selectOne(CloseUpApplyFormDO.builder().sourceApplyId(sourceApplyId).build()); + } + + /** + * 判断是否存在时间交集的歇业申请单(非审批拒绝状态) + */ + public boolean existsTimeOverlap(String storeId, Date planCloseDate, Date planOpenDate) { + return closeUpApplyFormMapper.existsTimeOverlap(storeId, planCloseDate, planOpenDate) > 0; + } +} diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/closeup/CloseUpAuditRecordDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/closeup/CloseUpAuditRecordDAO.java new file mode 100644 index 000000000..4922bda94 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/closeup/CloseUpAuditRecordDAO.java @@ -0,0 +1,136 @@ +package com.cool.store.dao.closeup; + +import com.cool.store.entity.closeup.CloseUpAuditRecordDO; +import com.cool.store.enums.close.CloseStoreAuditStatusEnum; +import com.cool.store.enums.close.RecordTypeEnum; +import com.cool.store.mapper.closeup.CloseUpAuditRecordMapper; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +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.Objects; +import java.util.stream.Collectors; + +/** + *

+ * 歇业开业审批记录DAO + *

+ * + * @author wangff + * @since 2026/4/8 + */ +@Repository +@RequiredArgsConstructor +public class CloseUpAuditRecordDAO { + private final CloseUpAuditRecordMapper closeUpAuditRecordMapper; + + /** + * 提交新增记录 + */ + public void addSubmitRecord(Long applyId, Integer applyType, String userId, String userName) { + CloseUpAuditRecordDO recordDO = CloseUpAuditRecordDO.builder() + .applyId(applyId) + .applyType(applyType) + .recordType(RecordTypeEnum.CLOSE_STORE_RECORD_TYPE_10.getRecordType()) + .actionRemark("") + .finishTaskTime(new Date()) + .receiveTaskTime(new Date()) + .handlerUserId(userId) + .handlerUserName(userName) + .auditStatus(CloseStoreAuditStatusEnum.PASS.getStatus()) + .handlerUserIds(getUserIds(Collections.singletonList(userId))) + .build(); + closeUpAuditRecordMapper.insertSelective(recordDO); + } + + /** + * 提交审批记录 + */ + public void addApproveRecord(Long applyId, Integer applyType, List userIdList) { + CloseUpAuditRecordDO recordDO = CloseUpAuditRecordDO.builder() + .applyId(applyId) + .applyType(applyType) + .recordType(RecordTypeEnum.CLOSE_STORE_RECORD_TYPE_20.getRecordType()) + .receiveTaskTime(new Date()) + .handlerUserIds(getUserIds(userIdList)) + .auditStatus(CloseStoreAuditStatusEnum.PENDING.getStatus()) + .build(); + closeUpAuditRecordMapper.insertSelective(recordDO); + } + + /** + * 首次发起流程 添加审批记录 + */ + public void addRecord(Long applyId, Integer applyType, String userId, String userName, List userIdList) { + //新增提交审批 + addSubmitRecord(applyId, applyType, userId, userName); + //新增审批记录 + addApproveRecord(applyId, applyType, userIdList); + } + + private String getUserIds(List userIds) { + String userIdStr = userIds.stream() + .filter(StringUtils::isNotBlank) + .distinct() + .collect(Collectors.joining(",")); + return "," + userIdStr + ","; + } + + public CloseUpAuditRecordDO getById(Long id) { + CloseUpAuditRecordDO recordDO = closeUpAuditRecordMapper.selectByPrimaryKey(id); + if (Objects.nonNull(recordDO) && recordDO.getDeleted().equals(0)) { + return recordDO; + } + return null; + } + + public CloseUpAuditRecordDO getOngoingRecordByApplyId(Long applyId) { + Example example = new Example(CloseUpAuditRecordDO.class); + example.createCriteria() + .andEqualTo("applyId", applyId) + .andEqualTo("auditStatus", CloseStoreAuditStatusEnum.PENDING.getStatus()); + example.setOrderByClause("create_time desc limit 1"); + return closeUpAuditRecordMapper.selectOneByExample(example); + } + + public CloseUpAuditRecordDO getLatestRecordByStatus(Long applyId, Integer auditStatus) { + Example example = new Example(CloseUpAuditRecordDO.class); + example.createCriteria() + .andEqualTo("applyId", applyId) + .andEqualTo("auditStatus", auditStatus); + example.setOrderByClause("create_time desc limit 1"); + return closeUpAuditRecordMapper.selectOneByExample(example); + } + + public void updateByPrimaryKeySelective(CloseUpAuditRecordDO recordDO) { + closeUpAuditRecordMapper.updateByPrimaryKeySelective(recordDO); + } + + public List getList(String userId, Integer applyType, Integer auditStatus) { + Example example = new Example(CloseUpAuditRecordDO.class); + example.createCriteria() + .andLike("handlerUserIds", "%," + userId + ",%") + .andEqualTo("applyType", applyType) + .andEqualTo("auditStatus", auditStatus); + example.setOrderByClause("create_time desc"); + return closeUpAuditRecordMapper.selectByExample(example); + } + + /** + * 根据申请id查询审批记录 + * @param applyId 申请id + * @return 审批记录列表 + */ + public List getListByApplyId(Long applyId) { + Example example = new Example(CloseUpAuditRecordDO.class); + example.createCriteria() + .andEqualTo("applyId", applyId) + .andEqualTo("deleted", 0); + example.setOrderByClause("id ASC"); + return closeUpAuditRecordMapper.selectByExample(example); + } +} diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/dao/closeup/CloseUpPlatformDAO.java b/coolstore-partner-dao/src/main/java/com/cool/store/dao/closeup/CloseUpPlatformDAO.java new file mode 100644 index 000000000..2359f7221 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/dao/closeup/CloseUpPlatformDAO.java @@ -0,0 +1,87 @@ +package com.cool.store.dao.closeup; + +import com.alibaba.excel.util.CollectionUtils; +import com.cool.store.entity.closeup.CloseUpPlatformDO; +import com.cool.store.enums.closeup.CloseUpPlatformEnum; +import com.cool.store.mapper.closeup.CloseUpPlatformMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; +import tk.mybatis.mapper.entity.Example; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + *

+ * 歇业开业平台账号DAO + *

+ * + * @author wangff + * @since 2026/4/8 + */ +@Repository +@RequiredArgsConstructor +public class CloseUpPlatformDAO { + private final CloseUpPlatformMapper closeUpPlatformMapper; + + public List init(Long applyId, Integer applyType, Date taskStartDate) { + List list = Arrays.stream(CloseUpPlatformEnum.values()) + .map(v -> CloseUpPlatformDO.builder() + .applyId(applyId) + .applyType(applyType) + .code(v.getCode()) + .name(v.getName()) + .status(0) + .type(v.getType()) + .icon(v.getIcon()) + .taskStartDate(taskStartDate) + .build()) + .collect(Collectors.toList()); + closeUpPlatformMapper.insertBatch(list); + return list; + } + + public List getList(Long applyId, Integer status, Integer type) { + Example example = new Example(CloseUpPlatformDO.class); + Example.Criteria criteria = example.createCriteria() + .andEqualTo("applyId", applyId); + if (Objects.nonNull(status)) { + criteria.andEqualTo("status", status); + } + if (Objects.nonNull(type)) { + criteria.andEqualTo("type", type); + } + return closeUpPlatformMapper.selectByExample(example); + } + + /** + * 更新状态 + */ + public void updateStatusByIds(List ids, Integer status) { + if (CollectionUtils.isEmpty(ids)) { + return; + } + Example example = new Example(CloseUpPlatformDO.class); + example.createCriteria() + .andIn("id", ids); + CloseUpPlatformDO update = CloseUpPlatformDO.builder().status(status).build(); + closeUpPlatformMapper.updateByExampleSelective(update, example); + } + + /** + * 根据申请单id删除 + */ + public void deleteByApplyId(Long applyId) { + closeUpPlatformMapper.delete(CloseUpPlatformDO.builder().applyId(applyId).build()); + } + + /** + * 查询待处理的申请单id + */ + public List selectTodoApplyIds(Integer applyType, String storeKeyword) { + return closeUpPlatformMapper.selectTodoApplyIds(applyType, storeKeyword); + } +} 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 287c32701..7fbe58ee1 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 @@ -98,6 +98,9 @@ public interface StoreMapper { @Param("storeStatus") String storeStatus, @Param("actualOpenDate") Date actualOpenDate); + int updateStatus(@Param("storeId") String storeId, + @Param("storeStatus") String storeStatus); + /** * 门店状态改为闭店 * @param storeId 门店id @@ -113,6 +116,8 @@ public interface StoreMapper { */ int insertOrUpdateCloseInfo(@Param("storeId") String storeId, @Param("closeReason") Integer closeReason, @Param("closeNature") Integer closeNature); + int insertOrUpdateCloseUpReason(@Param("storeId") String storeId, @Param("closeUpReason") String closeUpReason); + /** * 查询最近没有订货记录的门店 * @param latestDate 最近订货时间 diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/closeup/CloseUpApplyFormMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/closeup/CloseUpApplyFormMapper.java new file mode 100644 index 000000000..b5b3cfe5f --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/closeup/CloseUpApplyFormMapper.java @@ -0,0 +1,24 @@ +package com.cool.store.mapper.closeup; + +import com.cool.store.entity.closeup.CloseUpApplyFormDO; +import com.cool.store.request.closeup.CloseUpQueryRequest; +import org.apache.ibatis.annotations.Param; +import tk.mybatis.mapper.common.Mapper; + +import java.util.Date; +import java.util.List; + +public interface CloseUpApplyFormMapper extends Mapper { + + List getList(CloseUpQueryRequest request); + + /** + * 新增或编辑,使用 ON DUPLICATE KEY UPDATE + */ + int insertOrUpdate(CloseUpApplyFormDO record); + + /** + * 判断是否存在时间交集的申请单(非审批拒绝状态) + */ + int existsTimeOverlap(@Param("storeId") String storeId, @Param("planCloseDate") Date planCloseDate, @Param("planOpenDate") Date planOpenDate); +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/closeup/CloseUpAuditRecordMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/closeup/CloseUpAuditRecordMapper.java new file mode 100644 index 000000000..18790f9f3 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/closeup/CloseUpAuditRecordMapper.java @@ -0,0 +1,7 @@ +package com.cool.store.mapper.closeup; + +import com.cool.store.entity.closeup.CloseUpAuditRecordDO; +import tk.mybatis.mapper.common.Mapper; + +public interface CloseUpAuditRecordMapper extends Mapper { +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/closeup/CloseUpPlatformMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/closeup/CloseUpPlatformMapper.java new file mode 100644 index 000000000..b65c738b1 --- /dev/null +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/closeup/CloseUpPlatformMapper.java @@ -0,0 +1,17 @@ +package com.cool.store.mapper.closeup; + +import com.cool.store.entity.closeup.CloseUpPlatformDO; +import org.apache.ibatis.annotations.Param; +import tk.mybatis.mapper.common.Mapper; + +import java.util.List; + +public interface CloseUpPlatformMapper extends Mapper { + + int insertBatch(List list); + + /** + * 查询待处理的申请单id + */ + List selectTodoApplyIds(@Param("applyType") Integer applyType, @Param("storeKeyword") String storeKeyword); +} \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/resources/mapper/StoreMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/StoreMapper.xml index 57ee263d6..ed31da732 100644 --- a/coolstore-partner-dao/src/main/resources/mapper/StoreMapper.xml +++ b/coolstore-partner-dao/src/main/resources/mapper/StoreMapper.xml @@ -302,6 +302,12 @@ WHERE store_id = #{storeId} AND is_delete = 'effective' + + UPDATE store_${enterpriseId} + SET store_status = #{storeStatus} + WHERE store_id = #{storeId} AND is_delete = 'effective' + + UPDATE store_${enterpriseId} SET store_status = 'closed', @@ -317,6 +323,13 @@ close_nature = VALUES(close_nature) + + INSERT INTO store_extend_info_${enterpriseId}(store_id, close_up_reason) + VALUES(#{storeId}, #{closeUpReason}) + ON DUPLICATE KEY UPDATE + close_up_reason = VALUES(close_up_reason) + + + SELECT + FROM zxjp_close_up_apply_form a + INNER JOIN store_${enterpriseId} b ON a.store_id = b.store_id AND b.is_delete = 'effective' + + INNER JOIN xfsg_line_info c ON a.line_id = c.id AND c.deleted = 0 + + + LEFT JOIN zxjp_close_up_apply_form d ON a.source_apply_id = d.id + + + + AND a.type = #{type} + + + AND a.status = #{status} + + + AND a.plan_close_date BETWEEN #{beginPlanCloseDate} AND #{endPlanCloseDate} + + + AND a.actual_open_date BETWEEN #{beginActualOpenDate} AND #{endActualOpenDate} + + + AND a.apply_no LIKE CONCAT('%',#{applyNo},'%') + + + AND (b.store_name LIKE CONCAT('%',#{storeKeyword},'%') OR b.store_num LIKE CONCAT('%',#{storeKeyword},'%')) + + + AND b.join_brand = #{joinBrand} + + + + b.region_path LIKE CONCAT('%/',#{regionId},'/%') + + + + AND (c.username LIKE CONCAT('%',#{lineKeyword},'%') OR c.mobile LIKE CONCAT('%',#{lineKeyword},'%')) + + + AND d.apply_no LIKE CONCAT('%', #{closeUpApplyNo}, '%') + + + ORDER BY a.create_time DESC + + + + INSERT INTO zxjp_close_up_apply_form ( + id, type, store_id, apply_no, line_id, status, plan_close_date, actual_close_date, + plan_open_date, actual_open_date, user_id, reason, source_apply_id, urls + ) VALUES ( + #{id}, #{type}, #{storeId}, #{applyNo}, #{lineId}, #{status}, #{planCloseDate}, #{actualCloseDate}, + #{planOpenDate}, #{actualOpenDate}, #{userId}, #{reason}, #{sourceApplyId}, #{urls} + ) ON DUPLICATE KEY UPDATE + type = #{type}, + store_id = #{storeId}, + apply_no = #{applyNo}, + line_id = #{lineId}, + status = #{status}, + plan_close_date = #{planCloseDate}, + actual_close_date = #{actualCloseDate}, + plan_open_date = #{planOpenDate}, + actual_open_date = #{actualOpenDate}, + user_id = #{userId}, + reason = #{reason}, + source_apply_id = #{sourceApplyId}, + urls = #{urls} + + + + \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/resources/mapper/closeup/CloseUpAuditRecordMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/closeup/CloseUpAuditRecordMapper.xml new file mode 100644 index 000000000..6cde55480 --- /dev/null +++ b/coolstore-partner-dao/src/main/resources/mapper/closeup/CloseUpAuditRecordMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/resources/mapper/closeup/CloseUpPlatformMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/closeup/CloseUpPlatformMapper.xml new file mode 100644 index 000000000..4cf2e1344 --- /dev/null +++ b/coolstore-partner-dao/src/main/resources/mapper/closeup/CloseUpPlatformMapper.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + INSERT INTO zxjp_close_up_platform(apply_id, apply_type, code, name, status, type, task_start_date, icon) + VALUES + + (#{item.applyId}, #{item.applyType}, #{item.code}, #{item.name}, #{item.status}, #{item.type}, #{item.taskStartDate}, #{item.icon}) + + + + + \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/entity/closeup/CloseUpApplyFormDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/closeup/CloseUpApplyFormDO.java new file mode 100644 index 000000000..a9850e668 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/closeup/CloseUpApplyFormDO.java @@ -0,0 +1,112 @@ +package com.cool.store.entity.closeup; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; +import javax.persistence.*; + +/** + * 歇业开业申请单 + */ +@Data +@Table(name = "zxjp_close_up_apply_form") +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CloseUpApplyFormDO { + /** + * id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** + * 类型,0歇业申请 1开业申请 + */ + private Integer type; + + /** + * 门店id + */ + @Column(name = "store_id") + private String storeId; + + /** + * 申请单号 + */ + @Column(name = "apply_no") + private String applyNo; + + /** + * 线索id + */ + @Column(name = "line_id") + private Long lineId; + + /** + * 状态,1-审批中 5-审批拒绝 10-审批通过 + */ + private Integer status; + + /** + * 计划歇业日期 + */ + @Column(name = "plan_close_date") + private Date planCloseDate; + + /** + * 实际歇业日期 + */ + @Column(name = "actual_close_date") + private Date actualCloseDate; + + /** + * 计划开业日期 + */ + @Column(name = "plan_open_date") + private Date planOpenDate; + + /** + * 实际开业日期 + */ + @Column(name = "actual_open_date") + private Date actualOpenDate; + + /** + * 代申请运营顾问id + */ + @Column(name = "user_id") + private String userId; + + /** + * 附件列表 + */ + private String urls; + + /** + * 原因说明 + */ + private String reason; + + /** + * 源申请单id + */ + @Column(name = "source_apply_id") + private Long sourceApplyId; + + /** + * 创建时间 + */ + @Column(name = "create_time") + private Date createTime; + + /** + * 更新时间 + */ + @Column(name = "updated_time") + private Date updatedTime; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/entity/closeup/CloseUpAuditRecordDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/closeup/CloseUpAuditRecordDO.java new file mode 100644 index 000000000..1f67fa1ac --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/closeup/CloseUpAuditRecordDO.java @@ -0,0 +1,100 @@ +package com.cool.store.entity.closeup; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; +import javax.persistence.*; + +/** + * 歇业开业审批记录 + */ +@Data +@Table(name = "zxjp_close_up_audit_record") +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CloseUpAuditRecordDO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** + * 申请单id + */ + @Column(name = "apply_id") + private Long applyId; + + /** + * 申请单类型 + */ + @Column(name = "apply_type") + private Integer applyType; + + /** + * 记录类型:1-申请提交,2-审批操作 + */ + @Column(name = "record_type") + private Integer recordType; + + /** + * 备注 + */ + @Column(name = "action_remark") + private String actionRemark; + + /** + * 实际处理人 + */ + @Column(name = "handler_user_id") + private String handlerUserId; + + /** + * 实际处理人名称 + */ + @Column(name = "handler_user_name") + private String handlerUserName; + + /** + * 处理人集合 + */ + @Column(name = "handler_user_ids") + private String handlerUserIds; + + /** + * 收到任务时间 + */ + @Column(name = "receive_task_time") + private Date receiveTaskTime; + + /** + * 完成任务时间 + */ + @Column(name = "finish_task_time") + private Date finishTaskTime; + + /** + * 审核状态 0待处理,1通过,2拒绝 + */ + @Column(name = "audit_status") + private Integer auditStatus; + + /** + * 删除标识 + */ + private Integer deleted; + + /** + * 创建时间 + */ + @Column(name = "create_time") + private Date createTime; + + /** + * 更新时间 + */ + @Column(name = "updated_time") + private Date updatedTime; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/entity/closeup/CloseUpPlatformDO.java b/coolstore-partner-model/src/main/java/com/cool/store/entity/closeup/CloseUpPlatformDO.java new file mode 100644 index 000000000..f33c51cc8 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/entity/closeup/CloseUpPlatformDO.java @@ -0,0 +1,78 @@ +package com.cool.store.entity.closeup; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; +import javax.persistence.*; + +/** + * 歇业开业平台账号 + */ +@Data +@Table(name = "zxjp_close_up_platform") +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CloseUpPlatformDO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** + * 申请单id + */ + @Column(name = "apply_id") + private Long applyId; + + /** + * 申请单类型,0歇业申请 1开业申请 + */ + @Column(name = "apply_type") + private Integer applyType; + + /** + * code + */ + private String code; + + /** + * 名称 + */ + private String name; + + /** + * 状态:0-待处理, 1-已处理 + */ + private Integer status; + + /** + * 关闭类型,0手动关闭,1自动关闭 + */ + private Integer type; + + /** + * 任务开始日期 + */ + @Column(name = "task_start_date") + private Date taskStartDate; + + /** + * 图标 + */ + private String icon; + + /** + * 创建时间 + */ + @Column(name = "create_time") + private Date createTime; + + /** + * 更新时间 + */ + @Column(name = "update_time") + private Date updateTime; +} \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpApplyRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpApplyRequest.java new file mode 100644 index 000000000..cd2a3aed2 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpApplyRequest.java @@ -0,0 +1,41 @@ +package com.cool.store.request.closeup; + +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/8 + */ +@Data +public class CloseUpApplyRequest { + @ApiModelProperty("申请单id") + private Long id; + + @ApiModelProperty("门店id") + @NotBlank(message = "门店id不能为空") + private String storeId; + + @ApiModelProperty("计划歇业日期") + @NotNull(message = "计划歇业日期不能为空") + private Date planCloseDate; + + @ApiModelProperty("计划开业日期") + @NotNull(message = "计划开业日期不能为空") + private Date planOpenDate; + + @ApiModelProperty("原因说明") + @NotBlank(message = "原因说明不能为空") + private String reason; + + @ApiModelProperty("附件列表,逗号分割") + private String urls; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpApplySimpleQueryRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpApplySimpleQueryRequest.java new file mode 100644 index 000000000..2f50eab56 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpApplySimpleQueryRequest.java @@ -0,0 +1,22 @@ +package com.cool.store.request.closeup; + +import com.cool.store.common.PageBasicInfo; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + *

+ * 申请单简单信息查询Request + *

+ * + * @author wangff + * @since 2026/4/9 + */ +@Data +public class CloseUpApplySimpleQueryRequest extends PageBasicInfo { + @ApiModelProperty("门店id") + @NotBlank(message = "门店id不能为空") + private String storeId; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpAuditRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpAuditRequest.java new file mode 100644 index 000000000..046b05d7e --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpAuditRequest.java @@ -0,0 +1,30 @@ +package com.cool.store.request.closeup; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + *

+ * 歇业申请审批Request + *

+ * + * @author wangff + * @since 2026/4/8 + */ +@Data +public class CloseUpAuditRequest { + @ApiModelProperty("审批记录id") + @NotNull(message = "审批记录id不能为空") + private Long auditRecordId; + + @ApiModelProperty("审批意见") + @Length(max = 300, message = "审批意见长度不能超过300") + private String remark; + + @ApiModelProperty("正式歇业时间") + private Date actualCloseDate; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpOpenApplyRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpOpenApplyRequest.java new file mode 100644 index 000000000..ac1fc3d3a --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpOpenApplyRequest.java @@ -0,0 +1,32 @@ +package com.cool.store.request.closeup; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + *

+ * 营业申请Request + *

+ * + * @author wangff + * @since 2026/4/9 + */ +@Data +public class CloseUpOpenApplyRequest { + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("源申请单id") + @NotNull(message = "源申请单id不能为空") + private Long sourceApplyId; + + @ApiModelProperty("实际开业日期") + @NotNull(message = "实际开业日期不能为空") + private Date actualOpenDate; + + @ApiModelProperty("原因说明") + private String reason; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpPlatformHandleRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpPlatformHandleRequest.java new file mode 100644 index 000000000..08c4c7eac --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpPlatformHandleRequest.java @@ -0,0 +1,25 @@ +package com.cool.store.request.closeup; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + *

+ * 平台关闭开启处理Request + *

+ * + * @author wangff + * @since 2026/4/12 + */ +@Data +public class CloseUpPlatformHandleRequest { + @ApiModelProperty("id") + @NotNull(message = "id不能为空") + private Long id; + + @ApiModelProperty("状态:0-待处理, 1-已处理") + @NotNull(message = "状态不能为空") + private Integer status; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpQueryRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpQueryRequest.java new file mode 100644 index 000000000..b070c1542 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpQueryRequest.java @@ -0,0 +1,55 @@ +package com.cool.store.request.closeup; + +import com.cool.store.common.PageBasicInfo; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + *

+ * 申请单查询Request + *

+ * + * @author wangff + * @since 2026/4/9 + */ +@Data +public class CloseUpQueryRequest extends PageBasicInfo { + @ApiModelProperty("申请单类型,0-歇业 1-开业") + private Integer type; + + @ApiModelProperty("加盟商姓名或手机号") + private String lineKeyword; + + @ApiModelProperty("门店名称或编码") + private String storeKeyword; + + @ApiModelProperty("状态") + private Integer status; + + @ApiModelProperty("计划歇业开始时间") + private Date beginPlanCloseDate; + + @ApiModelProperty("计划歇业结束时间") + private Date endPlanCloseDate; + + @ApiModelProperty("实际开业开始时间") + private Date beginActualOpenDate; + + @ApiModelProperty("实际开业结束时间") + private Date endActualOpenDate; + + @ApiModelProperty("所属品牌") + private Integer joinBrand; + + @ApiModelProperty("申请单号") + private String applyNo; + + @ApiModelProperty("歇业申请单号(恢复申请单使用)") + private String closeUpApplyNo; + + @ApiModelProperty(value = "管辖区域id", hidden = true) + private List regionIds; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpTodoQueryRequest.java b/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpTodoQueryRequest.java new file mode 100644 index 000000000..f63dd4cdf --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/request/closeup/CloseUpTodoQueryRequest.java @@ -0,0 +1,22 @@ +package com.cool.store.request.closeup; + +import com.cool.store.common.PageBasicInfo; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + *

+ * 歇业申请待办查询Request + *

+ * + * @author wangff + * @since 2026/4/9 + */ +@Data +public class CloseUpTodoQueryRequest extends PageBasicInfo { + @ApiModelProperty("类型,0歇业申请 1开业申请") + private Integer type; + + @ApiModelProperty("门店名称或编码") + private String storeKeyword; +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/closeup/CloseUpApplyFormSimpleVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/closeup/CloseUpApplyFormSimpleVO.java new file mode 100644 index 000000000..b2977ecf2 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/closeup/CloseUpApplyFormSimpleVO.java @@ -0,0 +1,89 @@ +package com.cool.store.vo.closeup; + +import com.cool.store.enums.closeup.CloseUpStatusEnum; +import com.cool.store.enums.master.BrandTypeEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + *

+ * 歇业申请单简单列表VO + *

+ * + * @author wangff + * @since 2026/4/9 + */ +@Data +public class CloseUpApplyFormSimpleVO { + private Long id; + + @ApiModelProperty("审批id") + private Long auditId; + + @ApiModelProperty("门店id") + private String storeId; + + @ApiModelProperty("门店名称") + private String storeName; + + @ApiModelProperty("门店编码") + private String storeNum; + + @ApiModelProperty("所属品牌") + private Integer joinBrand; + + @ApiModelProperty("所属品牌名称") + private String joinBrandName; + + @ApiModelProperty("申请单号") + private String applyNo; + + @ApiModelProperty("歇业申请单号") + private String closeUpApplyNo; + + @ApiModelProperty("线索id") + private Long lineId; + + @ApiModelProperty("申请人手机号") + private String applyMobile; + + @ApiModelProperty("申请人名称") + private String applyName; + + @ApiModelProperty("申请人角色") + private String applyRoleName; + + @ApiModelProperty("状态,1-审批中 5-审批拒绝 10-审批通过 15-申请营业中 20-申请营业审批拒绝 25-申请营业审批通过") + private Integer status; + + @ApiModelProperty("状态名称") + private String statusName; + + @ApiModelProperty("计划歇业日期") + private Date planCloseDate; + + @ApiModelProperty("实际歇业日期") + private Date actualCloseDate; + + @ApiModelProperty("计划开业日期") + private Date planOpenDate; + + @ApiModelProperty("实际开业日期") + private Date actualOpenDate; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty(value = "源申请单id", hidden = true) + private Long sourceApplyId; + + public String getStatusName() { + return CloseUpStatusEnum.getDesc(status); + } + + public String getJoinBrandName() { + return BrandTypeEnum.getDescByCode(joinBrand); + } +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/closeup/CloseUpApplyFormVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/closeup/CloseUpApplyFormVO.java new file mode 100644 index 000000000..0122b8f21 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/closeup/CloseUpApplyFormVO.java @@ -0,0 +1,92 @@ +package com.cool.store.vo.closeup; + +import com.cool.store.enums.closeup.CloseUpStatusEnum; +import com.cool.store.enums.master.BrandTypeEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + *

+ * 歇业申请单VO + *

+ * + * @author wangff + * @since 2026/4/9 + */ +@Data +public class CloseUpApplyFormVO { + private Long id; + + @ApiModelProperty("审批单id") + private Long auditId; + + @ApiModelProperty("类型,0歇业申请 1开业申请") + private Integer type; + + @ApiModelProperty("门店id") + private String storeId; + + @ApiModelProperty("门店名称") + private String storeName; + + @ApiModelProperty("门店编码") + private String storeNum; + + @ApiModelProperty("所属品牌") + private Integer joinBrand; + + @ApiModelProperty("所属品牌名称") + private String joinBrandName; + + @ApiModelProperty("申请单号") + private String applyNo; + + @ApiModelProperty("线索id") + private Long lineId; + + @ApiModelProperty("申请人手机号") + private String applyMobile; + + @ApiModelProperty("申请人名称") + private String applyName; + + @ApiModelProperty("申请人角色") + private String applyRoleName; + + @ApiModelProperty("状态,1-审批中 5-审批拒绝 10-审批通过") + private Integer status; + + @ApiModelProperty("状态名称") + private String statusName; + + @ApiModelProperty("计划歇业日期") + private Date planCloseDate; + + @ApiModelProperty("实际歇业日期") + private Date actualCloseDate; + + @ApiModelProperty("计划开业日期") + private Date planOpenDate; + + @ApiModelProperty("实际开业日期") + private Date actualOpenDate; + + @ApiModelProperty("附件列表") + private String urls; + + @ApiModelProperty("原因说明") + private String reason; + + @ApiModelProperty("审批拒绝原因") + private String rejectReason; + + public String getJoinBrandName() { + return BrandTypeEnum.getDescByCode(joinBrand); + } + + public String getStatusName() { + return CloseUpStatusEnum.getDesc(status); + } +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/vo/closeup/CloseUpPlatformVO.java b/coolstore-partner-model/src/main/java/com/cool/store/vo/closeup/CloseUpPlatformVO.java new file mode 100644 index 000000000..7c1827a76 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/vo/closeup/CloseUpPlatformVO.java @@ -0,0 +1,33 @@ +package com.cool.store.vo.closeup; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + *

+ * 歇业开业平台账号VO + *

+ * + * @author wangff + * @since 2026/4/9 + */ +@Data +public class CloseUpPlatformVO { + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("申请单类型,0歇业申请 1开业申请") + private Integer applyType; + + @ApiModelProperty("code") + private String code; + + @ApiModelProperty("名称") + private String name; + + @ApiModelProperty("状态:0-待处理, 1-已处理") + private Integer status; + + @ApiModelProperty("图标") + private String icon; +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/mq/consumer/ConsumerClient.java b/coolstore-partner-service/src/main/java/com/cool/store/mq/consumer/ConsumerClient.java index 35a1e6c7c..19d6039c3 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/mq/consumer/ConsumerClient.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/mq/consumer/ConsumerClient.java @@ -40,6 +40,8 @@ public class ConsumerClient { private VisitRecordListener visitRecordListener; @Resource private TpPenaltyAppealListener tpPenaltyAppealListener; + @Resource + private CloseUpApplyStoreUpdateListener closeUpApplyStoreUpdateListener; /** * 获取通用配置 @@ -145,4 +147,17 @@ public class ConsumerClient { return consumerBean; } + @Bean(initMethod = "start", destroyMethod = "shutdown") + public ConsumerBean closeUpApplyStoreUpdate() { + RocketMqGroupEnum groupEnum = RocketMqGroupEnum.CLOSE_UP_APPLY_STORE_UPDATE; + ConsumerBean consumerBean = new ConsumerBean(); + //配置文件 + Properties properties = getCommonProperties(groupEnum); + consumerBean.setProperties(properties); + Map commonSubscriptionTable = getCommonSubscriptionTable(groupEnum, closeUpApplyStoreUpdateListener); + //订阅多个topic如上面设置 + consumerBean.setSubscriptionTable(commonSubscriptionTable); + return consumerBean; + } + } diff --git a/coolstore-partner-service/src/main/java/com/cool/store/mq/consumer/listener/CloseUpApplyStoreUpdateListener.java b/coolstore-partner-service/src/main/java/com/cool/store/mq/consumer/listener/CloseUpApplyStoreUpdateListener.java new file mode 100644 index 000000000..12307572e --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/mq/consumer/listener/CloseUpApplyStoreUpdateListener.java @@ -0,0 +1,53 @@ +package com.cool.store.mq.consumer.listener; + +import com.aliyun.openservices.ons.api.Action; +import com.aliyun.openservices.ons.api.ConsumeContext; +import com.aliyun.openservices.ons.api.Message; +import com.aliyun.openservices.ons.api.MessageListener; +import com.cool.store.constants.CommonConstants; +import com.cool.store.service.closeup.CloseUpService; +import com.cool.store.utils.RedisUtilPool; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +/** + *

+ * 歇业申请修改门店状态 + *

+ * + * @author wangff + * @since 2026/4/8 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class CloseUpApplyStoreUpdateListener implements MessageListener { + private final RedisUtilPool redisUtilPool; + private final CloseUpService closeUpService; + + @Override + public Action consume(Message message, ConsumeContext consumeContext) { + String text = new String(message.getBody()); + if (StringUtils.isBlank(text)) { + log.info("消息体为空,tag:{},messageId:{}", message.getTag(), message.getMsgID()); + return Action.CommitMessage; + } + String lockKey = "CloseUpApplyStoreUpdateListener:" + message.getMsgID(); + boolean lock = redisUtilPool.setNxExpire(lockKey, message.getMsgID(), CommonConstants.NORMAL_LOCK_TIMES); + if (lock) { + try { + closeUpService.storeStatusAndPlatformUpdate(Long.valueOf(text)); + } catch (Exception e) { + log.error("CloseUpApplyStoreUpdateListener consume error", e); + return Action.ReconsumeLater; + } finally { + redisUtilPool.delKey(lockKey); + } + log.info("消费成功,tag:{},messageId:{},reqBody={}", message.getTag(), message.getMsgID(), text); + return Action.CommitMessage; + } + return Action.ReconsumeLater; + } +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/close/impl/CloseStoreServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/close/impl/CloseStoreServiceImpl.java index 74182e575..24279bb85 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/close/impl/CloseStoreServiceImpl.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/close/impl/CloseStoreServiceImpl.java @@ -294,7 +294,7 @@ public class CloseStoreServiceImpl implements CloseStoreService { for (int i = 0; i < list.size(); i++) { CloseStoreAuditRecordDO auditRecordDO = list.get(i); AuditInfoResponse auditInfo = AuditInfoResponse.builder() - .type(getAuditInfoType(auditRecordDO)) + .type(getAuditInfoType(auditRecordDO.getRecordType(), auditRecordDO.getAuditStatus())) // 0加盟商发起 1云流水发起 2督导审批 3大区经理审批 .execute(i == 0 ? (CloseTypeEnum.INITIATE.getCloseType().equals(closeStoreInfoDO.getCloseType()) ? 0 : 1) : i + 1) .status(CommonConstants.INDEX_ZERO.equals(auditRecordDO.getAuditStatus()) ? 0 : 1) @@ -324,11 +324,11 @@ public class CloseStoreServiceImpl implements CloseStoreService { return result; } - private Integer getAuditInfoType(CloseStoreAuditRecordDO auditRecordDO) { - if (CommonConstants.INDEX_ONE.equals(auditRecordDO.getRecordType())) { + public static Integer getAuditInfoType(Integer recordType, Integer auditStatus) { + if (CommonConstants.INDEX_ONE.equals(recordType)) { return OperationLogAuditEnum.SUBMIT_AUDIT.getCode(); } else { - switch (auditRecordDO.getAuditStatus()) { + switch (auditStatus) { case 0: return OperationLogAuditEnum.WAIT_AUDIT.getCode(); case 1: diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/CloseUpService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/CloseUpService.java new file mode 100644 index 000000000..b679bc889 --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/CloseUpService.java @@ -0,0 +1,87 @@ +package com.cool.store.service.closeup; + +import com.cool.store.request.closeup.*; +import com.cool.store.response.AuditInfoResponse; +import com.cool.store.vo.closeup.CloseUpApplyFormSimpleVO; +import com.cool.store.vo.closeup.CloseUpApplyFormVO; +import com.cool.store.vo.closeup.CloseUpPlatformVO; +import com.github.pagehelper.PageInfo; + +import java.util.List; + +/** + *

+ * 歇业管理 + *

+ * + * @author wangff + * @since 2026/4/8 + */ +public interface CloseUpService { + + /** + * 歇业申请 + */ + Boolean closeUpApply(CloseUpApplyRequest request); + + /** + * 恢复营业申请 + */ + Boolean openApply(CloseUpOpenApplyRequest request); + + /** + * 审批通过 + */ + Boolean auditPass(CloseUpAuditRequest request); + + /** + * 审批拒绝 + */ + Boolean auditRejected(CloseUpAuditRequest request); + + /** + * 小程序歇业申请单分页查询 + */ + PageInfo miniApplyFormList(CloseUpApplySimpleQueryRequest request); + + /** + * 详情 + */ + CloseUpApplyFormVO getDetail(Long applyId); + + /** + * 待办列表 + */ + PageInfo todoList(CloseUpTodoQueryRequest request); + + /** + * 申请列表 + */ + PageInfo applyList(CloseUpQueryRequest request); + + /** + * 根据申请单id查询歇业开业平台账号 + */ + List getPlatformListByApplyId(Long applyId); + + /** + * 查询审批记录 + */ + List getAuditRecordList(Long applyId); + + /** + * 平台待办列表 + */ + PageInfo getPlatformTodoList(CloseUpTodoQueryRequest request); + + /** + * 门店状态变更 + * @param formId 申请单id + */ + void storeStatusAndPlatformUpdate(Long formId); + + /** + * 平台关闭开启处理 + */ + Boolean handlePlatform(CloseUpPlatformHandleRequest request); +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/PlatformAutoStrategy.java b/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/PlatformAutoStrategy.java new file mode 100644 index 000000000..59f94b3c5 --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/PlatformAutoStrategy.java @@ -0,0 +1,18 @@ +package com.cool.store.service.closeup; + +/** + *

+ * 歇业平台自动开闭店 + *

+ * + * @author wangff + * @since 2026/4/8 + */ +public interface PlatformAutoStrategy { + + String getCode(); + + Boolean close(); + + Boolean open(); +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/impl/CloseUpServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/impl/CloseUpServiceImpl.java new file mode 100644 index 000000000..274ae13ea --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/impl/CloseUpServiceImpl.java @@ -0,0 +1,591 @@ +package com.cool.store.service.closeup.impl; + +import cn.hutool.core.collection.CollStreamUtil; +import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson.JSONObject; +import com.cool.store.constants.CommonConstants; +import com.cool.store.context.CurrentUserHolder; +import com.cool.store.context.LoginUserInfo; +import com.cool.store.context.PartnerUserHolder; +import com.cool.store.dao.*; +import com.cool.store.dao.closeup.CloseUpApplyFormDAO; +import com.cool.store.dao.closeup.CloseUpAuditRecordDAO; +import com.cool.store.dao.closeup.CloseUpPlatformDAO; +import com.cool.store.dto.store.StoreMasterIssueDTO; +import com.cool.store.entity.*; +import com.cool.store.entity.closeup.CloseUpApplyFormDO; +import com.cool.store.entity.closeup.CloseUpAuditRecordDO; +import com.cool.store.entity.closeup.CloseUpPlatformDO; +import com.cool.store.enums.*; +import com.cool.store.enums.close.CloseStoreAuditStatusEnum; +import com.cool.store.enums.closeup.CloseUpStatusEnum; +import com.cool.store.exception.ServiceException; +import com.cool.store.mq.producer.SimpleMessageService; +import com.cool.store.request.closeup.*; +import com.cool.store.response.AuditInfoResponse; +import com.cool.store.service.UserAuthMappingService; +import com.cool.store.service.closeup.CloseUpService; +import com.cool.store.service.closeup.PlatformAutoStrategy; +import com.cool.store.service.sms.AliyunSmsService; +import com.cool.store.utils.BeanUtil; +import com.cool.store.vo.PartnerUserInfoVO; +import com.cool.store.vo.closeup.CloseUpApplyFormSimpleVO; +import com.cool.store.vo.closeup.CloseUpApplyFormVO; +import com.cool.store.vo.closeup.CloseUpPlatformVO; +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.apache.commons.collections4.ListUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.stream.Collectors; + +import static com.cool.store.service.close.impl.CloseStoreServiceImpl.getAuditInfoType; +import static com.cool.store.utils.GenerateNoUtil.generateMillsNoWithRandom; + +/** + *

+ * 歇业管理 服务实现类 + *

+ * + * @author wangff + * @since 2026/4/8 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class CloseUpServiceImpl implements CloseUpService { + private final CloseUpApplyFormDAO applyFormDAO; + private final CloseUpAuditRecordDAO auditRecordDAO; + private final CloseUpPlatformDAO platformDAO; + private final UserAuthMappingService userAuthMappingService; + private final RegionDao regionDao; + private final StoreDao storeDao; + private final SimpleMessageService simpleMessageService; + private final PlatformAutoFactory platformAutoFactory; + private final EnterpriseUserRoleDao enterpriseUserRoleDao; + private final LineInfoDAO lineInfoDAO; + private final EnterpriseUserDAO enterpriseUserDAO; + private final AliyunSmsService aliyunSmsService; + + @Value("${mybatis.configuration.variables.enterpriseId}") + private String enterpriseId; + + @Override + @Transactional + public Boolean closeUpApply(CloseUpApplyRequest request) { + // 查询当前当前门店 校验门店状态 + StoreDO store = storeDao.getByStoreId(request.getStoreId()); + if (store == null){ + throw new ServiceException(ErrorCodeEnum.STORE_NOT_EXIST); + } + if (DateUtil.betweenDay(request.getPlanCloseDate(), request.getPlanOpenDate(), true) >= 7 + && StringUtils.isBlank(request.getUrls())) { + throw new ServiceException(ErrorCodeEnum.ERROR_MESSAGE, "歇业时间大于7天,歇业检查清单不能为空"); + } + // 校验是否存在时间交集的申请单(非审批拒绝状态) + if (applyFormDAO.existsTimeOverlap(request.getStoreId(), request.getPlanCloseDate(), request.getPlanOpenDate())) { + throw new ServiceException(ErrorCodeEnum.CLOSE_UP_EXIST_ONGOING_RECORD); + } + PartnerUserInfoVO user = PartnerUserHolder.getUser(); + CloseUpApplyFormDO formDO = BeanUtil.toBean(request, CloseUpApplyFormDO.class); + formDO.setType(0); + formDO.setApplyNo(generateMillsNoWithRandom()); + formDO.setStatus(CloseUpStatusEnum.APPROVAL.getStatus()); + formDO.setLineId(user.getLineId()); + applyFormDAO.insertOrUpdate(formDO); + RegionDO regionDO = regionDao.getRegionByStoreId(request.getStoreId()); + if (Objects.isNull(regionDO)) { + throw new ServiceException(ErrorCodeEnum.REGION_NOT_EXIST); + } + // 运营顾问审批 + List auditUserIds = getAuditUserIds(regionDO.getId(), UserRoleEnum.SUPERVISION); + auditRecordDAO.addRecord(formDO.getId(), formDO.getType(), String.valueOf(user.getLineId()), user.getUsername(), auditUserIds); + return true; + } + + @Override + @Transactional + public Boolean openApply(CloseUpOpenApplyRequest request) { + CloseUpApplyFormDO sourceFormDO = applyFormDAO.getById(request.getSourceApplyId()); + if (Objects.isNull(sourceFormDO)) { + throw new ServiceException(ErrorCodeEnum.CLOSE_UP_FORM_NOT_EXIST); + } + StoreDO store = storeDao.getByStoreId(sourceFormDO.getStoreId()); + if (store == null){ + throw new ServiceException(ErrorCodeEnum.STORE_NOT_EXIST); + } + if (CloseUpStatusEnum.unPass(sourceFormDO.getStatus())) { + throw new ServiceException(ErrorCodeEnum.CLOSE_UP_CLOSED_AUDIT_NOT_PASS); + } + if (applyFormDAO.existOpenApply(request.getSourceApplyId())) { + throw new ServiceException(ErrorCodeEnum.CLOSE_UP_EXIST_OPEN_APPLY); + } + CloseUpApplyFormDO openFormDO = CloseUpApplyFormDO.builder() + .type(1) + .applyNo(generateMillsNoWithRandom()) + .storeId(sourceFormDO.getStoreId()) + .lineId(sourceFormDO.getLineId()) + .status(CloseUpStatusEnum.APPROVAL.getStatus()) + .planCloseDate(sourceFormDO.getPlanCloseDate()) + .actualCloseDate(sourceFormDO.getActualCloseDate()) + .planOpenDate(sourceFormDO.getPlanOpenDate()) + .actualOpenDate(request.getActualOpenDate()) + .reason(request.getReason()) + .sourceApplyId(request.getSourceApplyId()) + .build(); + applyFormDAO.insertOrUpdate(openFormDO); + // 修改源歇业申请单状态 + CloseUpApplyFormDO updateSourceForm = CloseUpApplyFormDO.builder() + .id(sourceFormDO.getId()) + .status(CloseUpStatusEnum.APPLY_OPEN.getStatus()) + .build(); + applyFormDAO.updateByPrimaryKeySelective(updateSourceForm); + PartnerUserInfoVO user = PartnerUserHolder.getUser(); + RegionDO regionDO = regionDao.getRegionByStoreId(sourceFormDO.getStoreId()); + if (Objects.isNull(regionDO)) { + throw new ServiceException(ErrorCodeEnum.REGION_NOT_EXIST); + } + // 运营顾问审批 + List auditUserIds = getAuditUserIds(regionDO.getId(), UserRoleEnum.SUPERVISION); + auditRecordDAO.addRecord(openFormDO.getId(), openFormDO.getType(), String.valueOf(user.getLineId()), user.getUsername(), auditUserIds); + return true; + } + + @Override + @Transactional + public Boolean auditPass(CloseUpAuditRequest request) { + CloseUpAuditRecordDO auditRecord = auditRecordDAO.getById(request.getAuditRecordId()); + if (Objects.isNull(auditRecord)) { + throw new ServiceException(ErrorCodeEnum.CLOSE_UP_AUDIT_RECORD_NOT_EXIST); + } + CloseUpApplyFormDO formDO = applyFormDAO.getById(auditRecord.getApplyId()); + if (Objects.isNull(formDO)) { + throw new ServiceException(ErrorCodeEnum.CLOSE_UP_FORM_NOT_EXIST); + } + if (!CloseUpStatusEnum.APPROVAL.getStatus().equals(formDO.getStatus())) { + throw new ServiceException(ErrorCodeEnum.CLOSE_UP_APPROVED); + } + // 校验审批权限并修改审批单状态 + verifyAuthAndUpdateAuditStatus(auditRecord, CloseStoreAuditStatusEnum.PASS.getStatus(), request.getRemark()); + // 更新申请单状态 + Date actualCloseDate = Objects.nonNull(request.getActualCloseDate()) ? request.getActualCloseDate() : formDO.getPlanCloseDate(); + formDO.setActualCloseDate(actualCloseDate); + CloseUpApplyFormDO updateFormDO = CloseUpApplyFormDO.builder() + .id(formDO.getId()) + .status(CloseUpStatusEnum.PASS.getStatus()) + .actualCloseDate(formDO.getType().equals(0) ? actualCloseDate : null) + .build(); + applyFormDAO.updateByPrimaryKeySelective(updateFormDO); + if (formDO.getType().equals(0)) { + closeExecute(formDO); + } else if (formDO.getType().equals(1)) { + openExecute(formDO); + } + return true; + } + + private void openExecute(CloseUpApplyFormDO formDO) { + // 根据营业时间判断直接修改主数据还是定时任务修改主数据 + if (formDO.getActualOpenDate().after(new Date())) { + // 发送延时任务 + log.info("发送延时任务"); + simpleMessageService.send(String.valueOf(formDO.getId()), RocketMqTagEnum.CLOSE_UP_APPLY_STORE_UPDATE, formDO.getPlanOpenDate().getTime()); + } else { + log.info("直接变更"); + storeStatusAndPlatformUpdate(formDO.getStoreId(), formDO.getId(), formDO.getType(), formDO.getSourceApplyId(), false); + } + // 修改源歇业申请单 + CloseUpApplyFormDO updateSourceForm = CloseUpApplyFormDO.builder() + .id(formDO.getSourceApplyId()) + .actualOpenDate(formDO.getActualOpenDate()) + .status(CloseUpStatusEnum.APPLY_OPEN_PASS.getStatus()) + .build(); + applyFormDAO.updateByPrimaryKeySelective(updateSourceForm); + // 初始化各外卖团购平台账号 + List platformList = platformDAO.init(formDO.getId(), formDO.getType(), formDO.getActualOpenDate()); + // 根据平台类型自动开启 + autoPlatform(formDO.getType(), platformList); + } + + /** + * 歇业执行操作 + */ + private void closeExecute(CloseUpApplyFormDO formDO) { + Date now = new Date(); + // 过去的单据不处理 + if (Objects.nonNull(formDO.getActualOpenDate()) && formDO.getActualOpenDate().before(now) + || Objects.isNull(formDO.getActualOpenDate()) && formDO.getPlanOpenDate().before(now)) { + return; + } + // 根据实际闭店时间判断直接修改主数据还是定时任务修改主数据 + if (formDO.getActualCloseDate().after(now)) { + // 发送延时任务 + log.info("发送延时任务"); + simpleMessageService.send(String.valueOf(formDO.getId()), RocketMqTagEnum.CLOSE_UP_APPLY_STORE_UPDATE, formDO.getActualCloseDate().getTime()); + } else { + log.info("直接变更"); + storeStatusAndPlatformUpdate(formDO.getStoreId(), formDO.getId(), formDO.getType(), formDO.getSourceApplyId(), false); + } + // 初始化各外卖团购平台账号 + List platformList = platformDAO.init(formDO.getId(), formDO.getType(), formDO.getActualCloseDate()); + // 根据平台类型自动关闭 + autoPlatform(formDO.getType(), platformList); + } + + @Override + @Transactional + public Boolean auditRejected(CloseUpAuditRequest request) { + CloseUpAuditRecordDO auditRecord = auditRecordDAO.getById(request.getAuditRecordId()); + if (Objects.isNull(auditRecord)) { + throw new ServiceException(ErrorCodeEnum.CLOSE_UP_AUDIT_RECORD_NOT_EXIST); + } + CloseUpApplyFormDO formDO = applyFormDAO.getById(auditRecord.getApplyId()); + if (Objects.isNull(formDO)) { + throw new ServiceException(ErrorCodeEnum.CLOSE_UP_FORM_NOT_EXIST); + } + if (!CloseUpStatusEnum.APPROVAL.getStatus().equals(formDO.getStatus())) { + throw new ServiceException(ErrorCodeEnum.CLOSE_UP_APPROVED); + } + // 校验审批权限并修改审批单状态 + verifyAuthAndUpdateAuditStatus(auditRecord, CloseStoreAuditStatusEnum.REJECTED.getStatus(), request.getRemark()); + // 修改申请单 + CloseUpApplyFormDO updateFormDO = CloseUpApplyFormDO.builder() + .id(formDO.getId()) + .status(CloseUpStatusEnum.REJECTED.getStatus()) + .build(); + applyFormDAO.updateByPrimaryKeySelective(updateFormDO); + // 营业申请修改源单据状态 + if (formDO.getType().equals(1)) { + CloseUpApplyFormDO updateSourceFormDO = CloseUpApplyFormDO.builder() + .id(formDO.getSourceApplyId()) + .status(CloseUpStatusEnum.APPLY_OPEN_REJECTED.getStatus()) + .build(); + applyFormDAO.updateByPrimaryKeySelective(updateSourceFormDO); + } + return true; + } + + @Override + public PageInfo miniApplyFormList(CloseUpApplySimpleQueryRequest request) { + PartnerUserInfoVO user = PartnerUserHolder.getUser(); + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List list = applyFormDAO.getList(user.getLineId(), 0, request.getStoreId()); + PageInfo page = BeanUtil.toPage(new PageInfo<>(list), CloseUpApplyFormSimpleVO.class); + fillSimpleField(page.getList()); + return page; + } + + @Override + public CloseUpApplyFormVO getDetail(Long applyId) { + CloseUpApplyFormDO formDO = applyFormDAO.getById(applyId); + if (Objects.nonNull(formDO)) { + CloseUpApplyFormVO vo = BeanUtil.toBean(formDO, CloseUpApplyFormVO.class); + LineInfoDO lineInfo = lineInfoDAO.getLineInfo(formDO.getLineId()); + StoreDO storeDO = storeDao.getByStoreId(formDO.getStoreId()); + vo.setApplyName(lineInfo.getUsername()); + vo.setApplyMobile(lineInfo.getMobile()); + vo.setApplyRoleName("加盟商"); + vo.setStoreName(storeDO.getStoreName()); + vo.setStoreNum(storeDO.getStoreNum()); + vo.setJoinBrand(storeDO.getJoinBrand()); + // 查询审批记录 + if (CloseUpStatusEnum.REJECTED.getStatus().equals(formDO.getStatus())) { + CloseUpAuditRecordDO auditRecord = auditRecordDAO.getLatestRecordByStatus(applyId, CloseStoreAuditStatusEnum.REJECTED.getStatus()); + if (Objects.nonNull(auditRecord)) { + vo.setRejectReason(auditRecord.getActionRemark()); + } + } else if (CloseUpStatusEnum.APPLY_OPEN_REJECTED.getStatus().equals(formDO.getStatus())) { + CloseUpApplyFormDO resumeForm = applyFormDAO.getBySourceApplyId(applyId); + CloseUpAuditRecordDO auditRecord = auditRecordDAO.getLatestRecordByStatus(resumeForm.getId(), CloseStoreAuditStatusEnum.REJECTED.getStatus()); + if (Objects.nonNull(auditRecord)) { + vo.setRejectReason(auditRecord.getActionRemark()); + } + } else { + CloseUpAuditRecordDO auditRecord = auditRecordDAO.getOngoingRecordByApplyId(applyId); + if (Objects.nonNull(auditRecord)) { + vo.setAuditId(auditRecord.getId()); + } + } + return vo; + } + return null; + } + + @Override + public PageInfo todoList(CloseUpTodoQueryRequest request) { + LoginUserInfo user = CurrentUserHolder.getUser(); + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List list = auditRecordDAO.getList(user.getUserId(), request.getType(), 0); + PageInfo page = new PageInfo<>(list); + + List applyIds = CollStreamUtil.toList(list, CloseUpAuditRecordDO::getApplyId); + List forms = applyFormDAO.getByIds(applyIds); + Map formMap = CollStreamUtil.toMap(forms, CloseUpApplyFormDO::getId, v -> v); + + List resultList = CollStreamUtil.toList(list, v -> { + CloseUpApplyFormDO formDO = formMap.get(v.getApplyId()); + CloseUpApplyFormSimpleVO vo = BeanUtil.toBean(formDO, CloseUpApplyFormSimpleVO.class); + vo.setAuditId(v.getId()); + return vo; + }); + fillSimpleField(resultList); + return BeanUtil.toPage(page, resultList); + } + + /** + * 填充信息 + */ + private void fillSimpleField(List list) { + Set lineIds = CollStreamUtil.toSet(list, CloseUpApplyFormSimpleVO::getLineId); + Set storeIds = CollStreamUtil.toSet(list, CloseUpApplyFormSimpleVO::getStoreId); + List lines = lineInfoDAO.getByLineIds(new ArrayList<>(lineIds)); + Map lineMap = CollStreamUtil.toMap(lines, LineInfoDO::getId, v -> v); + Map storeMap = storeDao.getStoreMapByStoreIds(new ArrayList<>(storeIds)); + Set sourceApplyIds = list.stream() + .map(CloseUpApplyFormSimpleVO::getSourceApplyId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + List closeUpApplyList = applyFormDAO.getByIds(new ArrayList<>(sourceApplyIds)); + Map sourceApplyMap = CollStreamUtil.toMap(closeUpApplyList, CloseUpApplyFormDO::getId, v -> v); + + for (CloseUpApplyFormSimpleVO vo : list) { + LineInfoDO lineInfoDO = lineMap.get(vo.getLineId()); + if (Objects.nonNull(lineInfoDO)) { + vo.setApplyMobile(lineInfoDO.getMobile()); + vo.setApplyName(lineInfoDO.getUsername()); + vo.setApplyRoleName("加盟商"); + } + StoreDO storeDO = storeMap.get(vo.getStoreId()); + if (Objects.nonNull(storeDO)) { + vo.setStoreName(storeDO.getStoreName()); + vo.setStoreNum(storeDO.getStoreNum()); + vo.setJoinBrand(storeDO.getJoinBrand()); + } + CloseUpApplyFormDO sourceApplyForm = sourceApplyMap.get(vo.getSourceApplyId()); + if (Objects.nonNull(sourceApplyForm)) { + vo.setCloseUpApplyNo(sourceApplyForm.getApplyNo()); + } + } + } + + @Override + public PageInfo applyList(CloseUpQueryRequest request) { + String userId = CurrentUserHolder.getUserId(); + Boolean isAdmin = enterpriseUserRoleDao.checkIsAdmin(userId); + if (!isAdmin) { + List userAuthMappingDOS = userAuthMappingService.listUserAuthMappingByUserId(userId); + if (CollectionUtils.isEmpty(userAuthMappingDOS)) { + return new PageInfo<>(); + } + request.setRegionIds(CollStreamUtil.toList(userAuthMappingDOS, UserAuthMappingDO::getMappingId)); + } + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List list = applyFormDAO.getList(request); + PageInfo page = BeanUtil.toPage(new PageInfo<>(list), CloseUpApplyFormSimpleVO.class); + fillSimpleField(page.getList()); + return page; + } + + @Override + public List getPlatformListByApplyId(Long applyId) { + List list = platformDAO.getList(applyId, null, null); + return BeanUtil.toList(list, CloseUpPlatformVO.class); + } + + @Override + public List getAuditRecordList(Long applyId) { + List list = auditRecordDAO.getListByApplyId(applyId); + Set userIds = new HashSet<>(); + list.forEach(v -> { + if (!CommonConstants.INDEX_ONE.equals(v.getRecordType())) { + userIds.addAll(StringUtils.isNotBlank(v.getHandlerUserIds()) ? Arrays.asList(v.getHandlerUserIds().split(",")) : Collections.emptyList()); + } + }); + Map userMap = enterpriseUserDAO.getUserMap(new ArrayList<>(userIds)); + List result = new ArrayList<>(); + for (int i = 0; i < list.size(); i++) { + CloseUpAuditRecordDO auditRecordDO = list.get(i); + AuditInfoResponse auditInfo = AuditInfoResponse.builder() + .type(getAuditInfoType(auditRecordDO.getRecordType(), auditRecordDO.getAuditStatus())) + // 0加盟商发起 1运营顾问审批 + .execute(CommonConstants.INDEX_ONE.equals(auditRecordDO.getRecordType()) ? 0 : 1) + .status(CommonConstants.INDEX_ZERO.equals(auditRecordDO.getAuditStatus()) ? 0 : 1) + .createTime(auditRecordDO.getCreateTime()) + .remark(auditRecordDO.getActionRemark()) + .actualUserId(auditRecordDO.getHandlerUserId()) + .build(); + List auditUserList = Arrays.stream(auditRecordDO.getHandlerUserIds().split(",")) + .filter(com.cool.store.utils.poi.StringUtils::isNotBlank) + .map(v -> { + String userName = null, avatar = null; + if (CommonConstants.INDEX_ZERO.equals(auditInfo.getExecute())) { + userName = auditRecordDO.getHandlerUserName(); + } else { + EnterpriseUserDO user = userMap.get(v); + if (Objects.nonNull(user)) { + userName = user.getName(); + avatar = user.getAvatar(); + } + } + return new AuditInfoResponse.AuditUserInfoVO(v, userName, avatar); + }) + .collect(Collectors.toList()); + auditInfo.setList(auditUserList); + result.add(auditInfo); + } + return result; + } + + @Override + public PageInfo getPlatformTodoList(CloseUpTodoQueryRequest request) { + PageHelper.startPage(request.getPageNum(), request.getPageSize()); + List applyIds = platformDAO.selectTodoApplyIds(request.getType(), request.getStoreKeyword()); + + List list = applyFormDAO.getByIds(applyIds); + List resultList = BeanUtil.toList(list, CloseUpApplyFormSimpleVO.class); + PageInfo page = BeanUtil.toPage(new PageInfo<>(applyIds), resultList); + fillSimpleField(page.getList()); + return page; + } + + /** + * 校验审批权限并修改审批单状态 + */ + private void verifyAuthAndUpdateAuditStatus(CloseUpAuditRecordDO auditRecord, Integer status, String remark) { + if (!auditRecord.getAuditStatus().equals(0)) { + throw new ServiceException(ErrorCodeEnum.CLOSE_UP_APPROVED); + } + LoginUserInfo user = CurrentUserHolder.getUser(); + Boolean isAdmin = enterpriseUserRoleDao.checkIsAdmin(user.getUserId()); + if (!isAdmin) { + boolean match = Arrays.stream(auditRecord.getHandlerUserIds().split(",")) + .filter(StringUtils::isNotBlank) + .anyMatch(v -> v.equals(user.getUserId())); + if (!match) { + throw new ServiceException(ErrorCodeEnum.CLOSE_UP_AUDIT_ACCESS_DENIED); + } + } + // 更新审批单状态 + CloseUpAuditRecordDO updateAuditRecord = new CloseUpAuditRecordDO(); + updateAuditRecord.setId(auditRecord.getId()); + updateAuditRecord.setAuditStatus(status); + updateAuditRecord.setHandlerUserId(user.getUserId()); + updateAuditRecord.setHandlerUserName(user.getName()); + updateAuditRecord.setActionRemark(remark); + updateAuditRecord.setFinishTaskTime(new Date()); + auditRecordDAO.updateByPrimaryKeySelective(updateAuditRecord); + } + + /** + * 自动开启关闭各平台 + */ + private void autoPlatform(Integer applyType, List list) { + List updateIds = new ArrayList<>(); + for (CloseUpPlatformDO platformDO : list) { + // 待处理且自动关闭 + if (platformDO.getStatus().equals(0) && platformDO.getType().equals(1) && (new Date()).after(platformDO.getTaskStartDate())) { + PlatformAutoStrategy platformAuto = platformAutoFactory.getByCode(platformDO.getCode()); + if (Objects.isNull(platformAuto)) { + log.info("平台不存在实现类, code:{} name:{}", platformDO.getCode(), platformDO.getName()); + } else { + boolean update = false; + if (applyType.equals(0)) { + update = platformAuto.close(); + } else if (applyType.equals(1)) { + update = platformAuto.open(); + } + if (update) { + updateIds.add(platformDO.getId()); + } + } + } + } + if (CollectionUtils.isNotEmpty(updateIds)) { + platformDAO.updateStatusByIds(updateIds, 1); + } + } + + /** + * 根据申请单修改主数据并处理各外卖团购平台开闭店 + */ + @Override + public void storeStatusAndPlatformUpdate(Long formId) { + CloseUpApplyFormDO formDO = applyFormDAO.getById(formId); + if (Objects.nonNull(formDO)) { + storeStatusAndPlatformUpdate(formDO.getStoreId(), formDO.getId(), formDO.getType(), formDO.getSourceApplyId(), true); + } + } + + @Override + public Boolean handlePlatform(CloseUpPlatformHandleRequest request) { + platformDAO.updateStatusByIds(Collections.singletonList(request.getId()), request.getStatus()); + return true; + } + + /** + * 修改主数据并处理各外卖团购平台开闭店 + */ + private void storeStatusAndPlatformUpdate(String storeId, Long applyId, Integer applyType, Long sourceApplyId, boolean autoPlatform) { + StoreDO storeDO = storeDao.getByStoreId(storeId); + if (Objects.isNull(storeDO)) { + return; + } + // 主数据状态修改 + boolean storeUpdate = false; + if (applyType.equals(0)) { + if (StoreStatusEnum.OPEN.getValue().equals(storeDO.getStoreStatus())) { + storeDao.closeUp(storeId, "close_up_special_reason"); + storeUpdate = true; + } else { + log.info("门店不处于在营状态,修改为暂停营业失败"); + } + } else { + if (StoreStatusEnum.CLOSE_UP.getValue().equals(storeDO.getStoreStatus())) { + storeDao.closeUpToOpen(storeId); + storeUpdate = true; + } else { + log.info("门店不处于暂停营业状态,修改为在营失败"); + } + // 删除歇业申请的平台数据 + if (Objects.nonNull(sourceApplyId)) { + platformDAO.deleteByApplyId(sourceApplyId); + } + } + if (autoPlatform) { + // 自动开关平台 + List platformList = platformDAO.getList(applyId, 0, applyType); + autoPlatform(applyType, platformList); + } + if (StringUtils.isNotBlank(storeDO.getTelephone())) { + aliyunSmsService.sendNotice(storeDO.getTelephone(), applyType.equals(0) ? SmsNoticeTypeEnum.CLOSE_UP_CLOSE_NOTICE : SmsNoticeTypeEnum.CLOSE_UP_OPEN_NOTICE); + } + + // 用mq通知主应用下发门店主数据 + if (storeUpdate) { + try { + StoreMasterIssueDTO storeMasterIssueDTO = new StoreMasterIssueDTO(enterpriseId, Collections.singletonList(storeId)); + simpleMessageService.send(JSONObject.toJSONString(storeMasterIssueDTO), RocketMqTagEnum.STORE_MASTER_ISSUE); + } catch (Exception e) { + log.error("mq通知主应用下发门店主数据失败"); + } + } + } + + /** + * 获取拥有区域管辖权限的指定角色用户 + * @param regionId 区域id + * @param userRoleEnum 角色枚举 + * @return 用户id列表 + */ + private List getAuditUserIds(Long regionId, UserRoleEnum userRoleEnum) { + List allUserByRoleEnumAndRegionId = userAuthMappingService.getAllUserByRoleEnumAndRegionId(userRoleEnum, regionId); + return ListUtils.emptyIfNull(allUserByRoleEnumAndRegionId).stream().map(EnterpriseUserDO::getUserId).distinct().collect(Collectors.toList()); + } +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/impl/DefaultPlatformAutoStrategy.java b/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/impl/DefaultPlatformAutoStrategy.java new file mode 100644 index 000000000..00acd6fa4 --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/impl/DefaultPlatformAutoStrategy.java @@ -0,0 +1,30 @@ +package com.cool.store.service.closeup.impl; + +import com.cool.store.service.closeup.PlatformAutoStrategy; +import org.springframework.stereotype.Service; + +/** + *

+ * 默认 + *

+ * + * @author wangff + * @since 2026/4/8 + */ +@Service +public class DefaultPlatformAutoStrategy implements PlatformAutoStrategy { + @Override + public String getCode() { + return ""; + } + + @Override + public Boolean close() { + return null; + } + + @Override + public Boolean open() { + return null; + } +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/impl/PlatformAutoFactory.java b/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/impl/PlatformAutoFactory.java new file mode 100644 index 000000000..fecf652a0 --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/closeup/impl/PlatformAutoFactory.java @@ -0,0 +1,32 @@ +package com.cool.store.service.closeup.impl; + +import com.cool.store.service.closeup.PlatformAutoStrategy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * 歇业平台自动开闭店工厂 + *

+ * + * @author wangff + * @since 2026/4/8 + */ +@Service +public class PlatformAutoFactory { + private final Map map = new HashMap<>(); + + @Autowired + public PlatformAutoFactory(PlatformAutoStrategy[] strategies) { + for (PlatformAutoStrategy platformAutoStrategy : strategies) { + map.put(platformAutoStrategy.getCode(), platformAutoStrategy); + } + } + + public PlatformAutoStrategy getByCode(String code) { + return map.get(code); + } +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/CommonService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/CommonService.java index 061934d79..680971afd 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/CommonService.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/CommonService.java @@ -63,6 +63,10 @@ public class CommonService { // private String qywxUrl1; @Value("${qywx.task.notice.url2}") private String qywxUrl2; + @Value("${aliyun.sms.private.accessKeyId}") + private String smsPrivateAccessKeyId; + @Value("${aliyun.sms.private.accessKeySecret}") + private String smsPrivateAccessKeySecret; public LineFlowService getLineFlowService(Integer workflowSubStage){ WorkflowSubStageEnum workflowSubStageEnum = WorkflowSubStageEnum.getWorkflowSubStageEnum(workflowSubStage); @@ -134,17 +138,36 @@ public class CommonService { } public void sendSms(List poneNumbers, String templateCode, Map templateParamMap){ - log.info("templateCode:{}, request:{}, poneNumbers:{}", templateCode, JSONObject.toJSONString(templateParamMap), JSONObject.toJSONString(poneNumbers)); if(CollectionUtils.isEmpty(poneNumbers)){ return; } + sendSms(poneNumbers, templateCode, "杭州好多店智能科技", templateParamMap, smsAccessKeyId, smsAccessKeySecret); + } + + public void privateSendSms(List poneNumbers, String templateCode, String signName, Map templateParamMap) { + if(CollectionUtils.isEmpty(poneNumbers)){ + return; + } + sendSms(poneNumbers, templateCode, signName, templateParamMap, smsPrivateAccessKeyId, smsPrivateAccessKeySecret); + } + + public void sendSms(List poneNumbers, + String templateCode, + String signName, + Map templateParamMap, + String accessKeyId, + String accessKeySecret) { + log.info("templateCode:{}, signName:{}, request:{}, poneNumbers:{}", templateCode, signName, JSONObject.toJSONString(templateParamMap), JSONObject.toJSONString(poneNumbers)); + if (CollectionUtils.isEmpty(poneNumbers)) { + return; + } List signNameList = new ArrayList<>(); - signNameList.add("杭州好多店智能科技"); + signNameList.add(signName); AsyncClient client = null; try { StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder() - .accessKeyId(smsAccessKeyId) - .accessKeySecret(smsAccessKeySecret) + .accessKeyId(accessKeyId) + .accessKeySecret(accessKeySecret) .build()); client = AsyncClient.builder() .region("cn-hangzhou") @@ -168,7 +191,7 @@ public class CommonService { } catch (ExecutionException e) { e.printStackTrace(); } finally { - if(Objects.isNull(client)){ + if (Objects.isNull(client)) { client.close(); } } diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/sms/AliyunSmsService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/sms/AliyunSmsService.java index 42d0c23c7..cd9ba0595 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/sms/AliyunSmsService.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/sms/AliyunSmsService.java @@ -2,6 +2,7 @@ package com.cool.store.service.sms; import com.cool.store.enums.SmsCodeTypeEnum; +import com.cool.store.enums.SmsNoticeTypeEnum; import com.cool.store.response.ResponseResult; /** @@ -18,4 +19,9 @@ public interface AliyunSmsService { * @param codeType 验证码类型 */ ResponseResult sendSmsCode(String mobile, SmsCodeTypeEnum codeType); + + /** + * 发送通知 + */ + void sendNotice(String mobile, SmsNoticeTypeEnum type); } diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/sms/impl/AliyunSmsServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/sms/impl/AliyunSmsServiceImpl.java index 341ce206a..a76b2841a 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/sms/impl/AliyunSmsServiceImpl.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/sms/impl/AliyunSmsServiceImpl.java @@ -1,6 +1,7 @@ package com.cool.store.service.sms.impl; import com.cool.store.enums.SmsCodeTypeEnum; +import com.cool.store.enums.SmsNoticeTypeEnum; import com.cool.store.response.ResponseResult; import com.cool.store.service.impl.CommonService; import com.cool.store.service.sms.AliyunSmsService; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -42,6 +44,11 @@ public class AliyunSmsServiceImpl implements AliyunSmsService { return ResponseResult.success(true); } + @Override + public void sendNotice(String mobile, SmsNoticeTypeEnum type) { + commonService.privateSendSms(Collections.singletonList(mobile), type.getTemplateCode(), type.getSmsSign().getSignName(), null); + } + public static String getRandNum() { return String.valueOf((int) ((Math.random() * 9 + 1) * Math.pow(10, 5))); } diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/CloseUpController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/CloseUpController.java new file mode 100644 index 000000000..252d65e05 --- /dev/null +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/CloseUpController.java @@ -0,0 +1,91 @@ +package com.cool.store.controller.webb; + +import com.cool.store.request.closeup.CloseUpAuditRequest; +import com.cool.store.request.closeup.CloseUpPlatformHandleRequest; +import com.cool.store.request.closeup.CloseUpQueryRequest; +import com.cool.store.request.closeup.CloseUpTodoQueryRequest; +import com.cool.store.response.AuditInfoResponse; +import com.cool.store.response.ResponseResult; +import com.cool.store.service.closeup.CloseUpService; +import com.cool.store.vo.closeup.CloseUpApplyFormSimpleVO; +import com.cool.store.vo.closeup.CloseUpApplyFormVO; +import com.cool.store.vo.closeup.CloseUpPlatformVO; +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.*; + +import java.util.List; + +/** + *

+ * 歇业管理 前端控制器 + *

+ * + * @author wangff + * @since 2026/4/8 + */ +@Api(tags = "歇业管理") +@RestController +@RequestMapping("/pc/closeup") +@RequiredArgsConstructor +@Validated +public class CloseUpController { + private final CloseUpService closeUpService; + + @ApiOperation("H5歇业开业待办") + @PostMapping("/todoList") + public ResponseResult> todoList(@RequestBody @Validated CloseUpTodoQueryRequest request) { + return ResponseResult.success(closeUpService.todoList(request)); + } + + @ApiOperation("开业歇业申请列表") + @PostMapping("/applyList") + public ResponseResult> applyList(@RequestBody @Validated CloseUpQueryRequest request) { + return ResponseResult.success(closeUpService.applyList(request)); + } + + @ApiOperation("申请单详情") + @GetMapping("/detail") + public ResponseResult getDetail(@RequestParam("applyId") Long applyId) { + return ResponseResult.success(closeUpService.getDetail(applyId)); + } + + @ApiOperation("审批通过") + @PostMapping("/auditPass") + public ResponseResult auditPass(@RequestBody @Validated CloseUpAuditRequest request) { + return ResponseResult.success(closeUpService.auditPass(request)); + } + + @ApiOperation("审批拒绝") + @PostMapping("/auditRejected") + public ResponseResult auditRefuse(@RequestBody @Validated CloseUpAuditRequest request) { + return ResponseResult.success(closeUpService.auditRejected(request)); + } + + @ApiOperation("查询平台账号列表") + @GetMapping("/platformList") + public ResponseResult> getPlatformList(@RequestParam("applyId") Long applyId) { + return ResponseResult.success(closeUpService.getPlatformListByApplyId(applyId)); + } + + @ApiOperation("查询审批记录") + @GetMapping("/auditRecordList") + public ResponseResult> getAuditRecordList(@RequestParam("applyId") Long applyId) { + return ResponseResult.success(closeUpService.getAuditRecordList(applyId)); + } + + @ApiOperation("平台待办记录-工作台") + @GetMapping("/platformTodoList") + public ResponseResult> getPlatformTodoList(@Validated CloseUpTodoQueryRequest request) { + return ResponseResult.success(closeUpService.getPlatformTodoList(request)); + } + + @ApiOperation("平台关闭开启处理") + @PostMapping("/handlePlatform") +public ResponseResult handlePlatform(@RequestBody @Validated CloseUpPlatformHandleRequest request) { + return ResponseResult.success(closeUpService.handlePlatform(request)); + } +} diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniCloseUpController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniCloseUpController.java new file mode 100644 index 000000000..8790200bf --- /dev/null +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniCloseUpController.java @@ -0,0 +1,56 @@ +package com.cool.store.controller.webc; + +import com.cool.store.request.closeup.CloseUpApplyRequest; +import com.cool.store.request.closeup.CloseUpApplySimpleQueryRequest; +import com.cool.store.request.closeup.CloseUpOpenApplyRequest; +import com.cool.store.response.ResponseResult; +import com.cool.store.service.closeup.CloseUpService; +import com.cool.store.vo.closeup.CloseUpApplyFormSimpleVO; +import com.cool.store.vo.closeup.CloseUpApplyFormVO; +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.*; + +/** + *

+ * Mini歇业管理 + *

+ * + * @author wangff + * @since 2026/4/8 + */ +@Api(tags = "Mini歇业管理") +@RestController +@RequestMapping("/mini/closeup") +@RequiredArgsConstructor +@Validated +public class MiniCloseUpController { + private final CloseUpService closeUpService; + + @ApiOperation("歇业申请") + @PostMapping("/apply") + public ResponseResult closeUpApply(@RequestBody @Validated CloseUpApplyRequest request) { + return ResponseResult.success(closeUpService.closeUpApply(request)); + } + + @ApiOperation("恢复营业申请") + @PostMapping("/openApply") + public ResponseResult openApply(@RequestBody @Validated CloseUpOpenApplyRequest request) { + return ResponseResult.success(closeUpService.openApply(request)); + } + + @ApiOperation("申请列表") + @PostMapping("/list") + public ResponseResult> applyList(@RequestBody @Validated CloseUpApplySimpleQueryRequest request) { + return ResponseResult.success(closeUpService.miniApplyFormList(request)); + } + + @ApiOperation("申请单详情") + @GetMapping("/detail") + public ResponseResult getDetail(@RequestParam("applyId") Long applyId) { + return ResponseResult.success(closeUpService.getDetail(applyId)); + } +} diff --git a/coolstore-partner-web/src/main/resources/application-ab.properties b/coolstore-partner-web/src/main/resources/application-ab.properties index 823a03306..a71670c96 100644 --- a/coolstore-partner-web/src/main/resources/application-ab.properties +++ b/coolstore-partner-web/src/main/resources/application-ab.properties @@ -92,6 +92,8 @@ xfsg.url=https://inf-test.xianfengsg.com/InfService aliyun.sms.accessKeyId=LTAI5tAVZ3r9UtSpLGcmGoQn aliyun.sms.accessKeySecret=WIMjO4BjVg3YAHwmplq86yOyS2HMpa aliyun.sms.signName=酷店掌 +aliyun.sms.private.accessKeyId=LTAI5tDp9nFNSca53jjzepE5 +aliyun.sms.private.accessKeySecret=oTWhLJ6t6DeIINFTkAzwlY18ORfyYl mybatis.configuration.variables.enterpriseId=5558ce7a3aa84e3590392fcaa8697ffb enterprise.dingCorpId=dingef2502a50df74ccc35c2f4657eb6378f diff --git a/coolstore-partner-web/src/main/resources/application-hd.properties b/coolstore-partner-web/src/main/resources/application-hd.properties index 2eb87200c..6ead66a2c 100644 --- a/coolstore-partner-web/src/main/resources/application-hd.properties +++ b/coolstore-partner-web/src/main/resources/application-hd.properties @@ -79,6 +79,8 @@ xfsg.url=https://inf-test.xianfengsg.com/InfService aliyun.sms.accessKeyId=LTAI5tAVZ3r9UtSpLGcmGoQn aliyun.sms.accessKeySecret=WIMjO4BjVg3YAHwmplq86yOyS2HMpa aliyun.sms.signName=酷店掌 +aliyun.sms.private.accessKeyId=LTAI5tDp9nFNSca53jjzepE5 +aliyun.sms.private.accessKeySecret=oTWhLJ6t6DeIINFTkAzwlY18ORfyYl mybatis.configuration.variables.enterpriseId=214ac5a3a517472a87268e02a2e6410a enterprise.dingCorpId=wpayJeDAAAklx_q1jGhyGUd4yEh8vV_g diff --git a/coolstore-partner-web/src/main/resources/application-local.properties b/coolstore-partner-web/src/main/resources/application-local.properties index f89b24f70..a076dd7dc 100644 --- a/coolstore-partner-web/src/main/resources/application-local.properties +++ b/coolstore-partner-web/src/main/resources/application-local.properties @@ -88,6 +88,8 @@ xfsg.url=https://inf-test.xianfengsg.com/InfService aliyun.sms.accessKeyId=LTAI5tAVZ3r9UtSpLGcmGoQn aliyun.sms.accessKeySecret=WIMjO4BjVg3YAHwmplq86yOyS2HMpa aliyun.sms.signName=酷店掌 +aliyun.sms.private.accessKeyId=LTAI5tDp9nFNSca53jjzepE5 +aliyun.sms.private.accessKeySecret=oTWhLJ6t6DeIINFTkAzwlY18ORfyYl mybatis.configuration.variables.enterpriseId=5558ce7a3aa84e3590392fcaa8697ffb enterprise.dingCorpId=wpayJeDAAAhGIFgUJpJN-zg39JuNbYhg diff --git a/coolstore-partner-web/src/main/resources/application-online.properties b/coolstore-partner-web/src/main/resources/application-online.properties index 9c3933b4b..30232c226 100644 --- a/coolstore-partner-web/src/main/resources/application-online.properties +++ b/coolstore-partner-web/src/main/resources/application-online.properties @@ -83,6 +83,8 @@ xfsg.url=https://inf.xianfengsg.com/InfService aliyun.sms.accessKeyId=LTAI5tAVZ3r9UtSpLGcmGoQn aliyun.sms.accessKeySecret=WIMjO4BjVg3YAHwmplq86yOyS2HMpa aliyun.sms.signName=酷店掌 +aliyun.sms.private.accessKeyId=LTAI5tDp9nFNSca53jjzepE5 +aliyun.sms.private.accessKeySecret=oTWhLJ6t6DeIINFTkAzwlY18ORfyYl mybatis.configuration.variables.enterpriseId=214ac5a3a517472a87268e02a2e6410a enterprise.dingCorpId=wpayJeDAAAklx_q1jGhyGUd4yEh8vV_g diff --git a/coolstore-partner-web/src/main/resources/application-test.properties b/coolstore-partner-web/src/main/resources/application-test.properties index f86d72b26..b1d3c087e 100644 --- a/coolstore-partner-web/src/main/resources/application-test.properties +++ b/coolstore-partner-web/src/main/resources/application-test.properties @@ -89,6 +89,8 @@ xfsg.url=https://inf-test.xianfengsg.com/InfService aliyun.sms.accessKeyId=LTAI5tAVZ3r9UtSpLGcmGoQn aliyun.sms.accessKeySecret=WIMjO4BjVg3YAHwmplq86yOyS2HMpa aliyun.sms.signName=酷店掌 +aliyun.sms.private.accessKeyId=LTAI5tDp9nFNSca53jjzepE5 +aliyun.sms.private.accessKeySecret=oTWhLJ6t6DeIINFTkAzwlY18ORfyYl mybatis.configuration.variables.enterpriseId=5558ce7a3aa84e3590392fcaa8697ffb enterprise.dingCorpId=wpayJeDAAAhGIFgUJpJN-zg39JuNbYhg