Merge #99 into master from cc_20260408_close_up

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: 王非凡 <accounts_67eba0c5fee9c49c80c8e2b4@mail.teambition.com>
Merged-by: 正新 <accounts_6964c7bcd2a2c377c5bbd01b@mail.teambition.com>

CR-link: https://codeup.aliyun.com/692ea314dec569489f6f167c/hangzhou/java/custom_zxjp/change/99
This commit is contained in:
王非凡
2026-04-15 08:23:40 +00:00
committed by 正新
parent 1b3ae71c3a
commit 19bce915ac
51 changed files with 2502 additions and 9 deletions

View File

@@ -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<Subscription, MessageListener> commonSubscriptionTable = getCommonSubscriptionTable(groupEnum, closeUpApplyStoreUpdateListener);
//订阅多个topic如上面设置
consumerBean.setSubscriptionTable(commonSubscriptionTable);
return consumerBean;
}
}

View File

@@ -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;
/**
* <p>
* 歇业申请修改门店状态
* </p>
*
* @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;
}
}

View File

@@ -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:

View File

@@ -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;
/**
* <p>
* 歇业管理
* </p>
*
* @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<CloseUpApplyFormSimpleVO> miniApplyFormList(CloseUpApplySimpleQueryRequest request);
/**
* 详情
*/
CloseUpApplyFormVO getDetail(Long applyId);
/**
* 待办列表
*/
PageInfo<CloseUpApplyFormSimpleVO> todoList(CloseUpTodoQueryRequest request);
/**
* 申请列表
*/
PageInfo<CloseUpApplyFormSimpleVO> applyList(CloseUpQueryRequest request);
/**
* 根据申请单id查询歇业开业平台账号
*/
List<CloseUpPlatformVO> getPlatformListByApplyId(Long applyId);
/**
* 查询审批记录
*/
List<AuditInfoResponse> getAuditRecordList(Long applyId);
/**
* 平台待办列表
*/
PageInfo<CloseUpApplyFormSimpleVO> getPlatformTodoList(CloseUpTodoQueryRequest request);
/**
* 门店状态变更
* @param formId 申请单id
*/
void storeStatusAndPlatformUpdate(Long formId);
/**
* 平台关闭开启处理
*/
Boolean handlePlatform(CloseUpPlatformHandleRequest request);
}

View File

@@ -0,0 +1,18 @@
package com.cool.store.service.closeup;
/**
* <p>
* 歇业平台自动开闭店
* </p>
*
* @author wangff
* @since 2026/4/8
*/
public interface PlatformAutoStrategy {
String getCode();
Boolean close();
Boolean open();
}

View File

@@ -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;
/**
* <p>
* 歇业管理 服务实现类
* </p>
*
* @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<String> 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<String> 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<CloseUpPlatformDO> 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<CloseUpPlatformDO> 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<CloseUpApplyFormSimpleVO> miniApplyFormList(CloseUpApplySimpleQueryRequest request) {
PartnerUserInfoVO user = PartnerUserHolder.getUser();
PageHelper.startPage(request.getPageNum(), request.getPageSize());
List<CloseUpApplyFormDO> list = applyFormDAO.getList(user.getLineId(), 0, request.getStoreId());
PageInfo<CloseUpApplyFormSimpleVO> 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<CloseUpApplyFormSimpleVO> todoList(CloseUpTodoQueryRequest request) {
LoginUserInfo user = CurrentUserHolder.getUser();
PageHelper.startPage(request.getPageNum(), request.getPageSize());
List<CloseUpAuditRecordDO> list = auditRecordDAO.getList(user.getUserId(), request.getType(), 0);
PageInfo<CloseUpAuditRecordDO> page = new PageInfo<>(list);
List<Long> applyIds = CollStreamUtil.toList(list, CloseUpAuditRecordDO::getApplyId);
List<CloseUpApplyFormDO> forms = applyFormDAO.getByIds(applyIds);
Map<Long, CloseUpApplyFormDO> formMap = CollStreamUtil.toMap(forms, CloseUpApplyFormDO::getId, v -> v);
List<CloseUpApplyFormSimpleVO> 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<CloseUpApplyFormSimpleVO> list) {
Set<Long> lineIds = CollStreamUtil.toSet(list, CloseUpApplyFormSimpleVO::getLineId);
Set<String> storeIds = CollStreamUtil.toSet(list, CloseUpApplyFormSimpleVO::getStoreId);
List<LineInfoDO> lines = lineInfoDAO.getByLineIds(new ArrayList<>(lineIds));
Map<Long, LineInfoDO> lineMap = CollStreamUtil.toMap(lines, LineInfoDO::getId, v -> v);
Map<String, StoreDO> storeMap = storeDao.getStoreMapByStoreIds(new ArrayList<>(storeIds));
Set<Long> sourceApplyIds = list.stream()
.map(CloseUpApplyFormSimpleVO::getSourceApplyId)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
List<CloseUpApplyFormDO> closeUpApplyList = applyFormDAO.getByIds(new ArrayList<>(sourceApplyIds));
Map<Long, CloseUpApplyFormDO> 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<CloseUpApplyFormSimpleVO> applyList(CloseUpQueryRequest request) {
String userId = CurrentUserHolder.getUserId();
Boolean isAdmin = enterpriseUserRoleDao.checkIsAdmin(userId);
if (!isAdmin) {
List<UserAuthMappingDO> 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<CloseUpApplyFormDO> list = applyFormDAO.getList(request);
PageInfo<CloseUpApplyFormSimpleVO> page = BeanUtil.toPage(new PageInfo<>(list), CloseUpApplyFormSimpleVO.class);
fillSimpleField(page.getList());
return page;
}
@Override
public List<CloseUpPlatformVO> getPlatformListByApplyId(Long applyId) {
List<CloseUpPlatformDO> list = platformDAO.getList(applyId, null, null);
return BeanUtil.toList(list, CloseUpPlatformVO.class);
}
@Override
public List<AuditInfoResponse> getAuditRecordList(Long applyId) {
List<CloseUpAuditRecordDO> list = auditRecordDAO.getListByApplyId(applyId);
Set<String> 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<String, EnterpriseUserDO> userMap = enterpriseUserDAO.getUserMap(new ArrayList<>(userIds));
List<AuditInfoResponse> 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<AuditInfoResponse.AuditUserInfoVO> 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<CloseUpApplyFormSimpleVO> getPlatformTodoList(CloseUpTodoQueryRequest request) {
PageHelper.startPage(request.getPageNum(), request.getPageSize());
List<Long> applyIds = platformDAO.selectTodoApplyIds(request.getType(), request.getStoreKeyword());
List<CloseUpApplyFormDO> list = applyFormDAO.getByIds(applyIds);
List<CloseUpApplyFormSimpleVO> resultList = BeanUtil.toList(list, CloseUpApplyFormSimpleVO.class);
PageInfo<CloseUpApplyFormSimpleVO> 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<CloseUpPlatformDO> list) {
List<Long> 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<CloseUpPlatformDO> 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<String> getAuditUserIds(Long regionId, UserRoleEnum userRoleEnum) {
List<EnterpriseUserDO> allUserByRoleEnumAndRegionId = userAuthMappingService.getAllUserByRoleEnumAndRegionId(userRoleEnum, regionId);
return ListUtils.emptyIfNull(allUserByRoleEnumAndRegionId).stream().map(EnterpriseUserDO::getUserId).distinct().collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,30 @@
package com.cool.store.service.closeup.impl;
import com.cool.store.service.closeup.PlatformAutoStrategy;
import org.springframework.stereotype.Service;
/**
* <p>
* 默认
* </p>
*
* @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;
}
}

View File

@@ -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;
/**
* <p>
* 歇业平台自动开闭店工厂
* </p>
*
* @author wangff
* @since 2026/4/8
*/
@Service
public class PlatformAutoFactory {
private final Map<String , PlatformAutoStrategy> 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);
}
}

View File

@@ -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<String> poneNumbers, String templateCode, Map<String, String> 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<String> poneNumbers, String templateCode, String signName, Map<String, String> templateParamMap) {
if(CollectionUtils.isEmpty(poneNumbers)){
return;
}
sendSms(poneNumbers, templateCode, signName, templateParamMap, smsPrivateAccessKeyId, smsPrivateAccessKeySecret);
}
public void sendSms(List<String> poneNumbers,
String templateCode,
String signName,
Map<String, String> 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<String> 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();
}
}

View File

@@ -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);
}

View File

@@ -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)));
}