Merge #52 into master from cc_20260121_store_type

Merge branch 'cc_20260126_pingan_wallet' into cc_20260121_store_type

* cc_20260121_store_type: (100 commits squashed)

  - Merge branch 'master' into cc_20251208_visit

  - feat:订单列表

  - feat:订单列表

  - fix:拜访记录导出

  - feat:列表处理

  - Merge branch 'cc_20251208_visit' into cc_20260121_store_type
    
    # Conflicts:
    #	coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java

  - feat:标准店接口处理

  - feat:标准店接口处理

  - feat:标准店接口处理

  - feat:标准店接口处理

  - feat:标准店接口处理

  - fix:加盟缴费调整

  - feat:标准店接口处理

  - fix:加盟缴费调整

  - Merge branch 'cc_20260126_pingan_wallet' into cc_20260121_store_type
    
    # Conflicts:
    #	coolstore-partner-model/src/main/java/com/cool/store/dto/wallet/BatchTransferDTO.java
    #	coolstore-partner-model/src/main/java/com/cool/store/request/wallet/BatchTransferRequest.java

  - feat:冲突解决

  - feat:接口处理

  - feat:shopInfo

  - fix:PC缴费信息列表过滤已完成缴费信息

  - fix:测试接口修改

  - Merge branch 'refs/heads/cc_20260126_pingan_wallet' into cc_20260121_store_type

  - fix:测试接口修改

  - feat:接口

  - feat:接口调整

  - feat:注释调整

  - feat:key 调整

  - feat:订单ID

  - feat:日志打印

  - feat:选择标准店型

  - feat:useStandardStore

  - feat:标准店没有缴费阶段

  - feat:标准店没有缴费阶段

  - feat:标准店没有缴费阶段

  - feat:标准店没有缴费阶段

  - feat:阶段调整

  - fix:修复加盟缴费流程流转错误

  - feat:费用类型ID

  - feat:锁释放

  - feat:分账状态

  - fix:加盟签约合同数据补充

  - feat:排序

  - feat:选项单位

  - feat:选项单位

  - feat:选项单位

  - feat:选项单位

  - feat:option_unit

  - feat:option_unit

  - feat:更新调整

  - feat:视频非必填

  - feat:optionUnit

  - fix:转义

  - Merge branch 'master' into cc_20260126_pingan_wallet
    
    # Conflicts:
    #	coolstore-partner-common/src/main/java/com/cool/store/constants/RedisConstant.java

  - feat:同一配置项下只能设置一个默认选项

  - feat:数量支持小数,新增首次订货字段

  - fix:提交及修改校验合计缴费金额和分账总金额是否相同

  - feat:queryPage

  - feat:defaultQuantity 改为 BigDecimal

  - feat:defaultQuantity 改为 BigDecimal

  - feat:门店预约到店

  - feat:门店预约到店 取消预约

  - feat:门店预约到店 手机号

  - feat:添加原价

  - feat:添加原价

  - feat:添加原价

  - feat:字典表 remark

  - Merge branch 'master' into cc_20260121_store_type
    
    # Conflicts:
    #	coolstore-partner-common/src/main/java/com/cool/store/constants/RedisConstant.java
    #	coolstore-partner-common/src/main/java/com/cool/store/enums/FileTypeEnum.java
    #	coolstore-partner-model/src/main/java/com/cool/store/vo/dict/DictColumnSimpleVO.java
    #	coolstore-partner-service/src/main/java/com/cool/store/service/ExportRealizeService.java
    #	coolstore-partner-service/src/main/java/com/cool/store/service/ExportService.java
    #	coolstore-partner-service/src/main/java/com/cool/store/service/impl/ExportRealizeServiceImpl.java
    #	coolstore-partner-service/src/main/java/com/cool/store/service/impl/ExportServiceImpl.java
    #	coolstore-partner-web/src/main/java/com/cool/store/controller/webb/ExportController.java

  - feat:字典表 remark

  - feat:服务人员手机号

  - feat:价格计算调整店型优惠价*默认数量 + 原价 *(选择数量-默认数量)

  - fix:补充钱包账单推送新管家流程

  - fix:账单推送钱包支付类型payWay由1改为2

  - feat:同一配置项下只能设置一个默认选项 限制去掉

  - fix:平安钱包分账信息改为非必填

  - feat:同一配置项只能选择一个选项 限制去掉

  - feat:心愿单

  - feat:心愿单

  - feat:心愿单接口调整

  - feat:心愿单接口调整

  - feat:心愿单接口调整

  - feat:批量更新数据

  - feat:查询店型已配置的选项绑定 新增顶部预览图

  - feat:查询店型已配置的选项绑定 新增顶部预览图

  - feat:查询店型已配置的选项绑定 新增顶部预览图

  - feat:配置大类

  - feat:配置大类

  - feat:价格优化

  - feat:阶段审批处理

  - fix:删除设计费-立规

  - feat:配置大项 配置项接口改造

  - feat:配置大项 配置项接口改造

  - feat:handleAudit

  - feat:新增code

  - feat:categoryId

  - feat:心愿单接口更新

  - feat:心愿单接口更新

  - feat:心愿单接口更新

  - feat:心愿单接口更新

  - feat:心愿单接口更新

  - Merge branch 'cc_20260126_pingan_wallet' into cc_20260121_store_type
    
    # Conflicts:
    #	coolstore-partner-common/src/main/java/com/cool/store/constants/RedisConstant.java

  - Merge branch 'master' into cc_20260121_store_type
    
    # Conflicts:
    #	coolstore-partner-service/src/main/java/com/cool/store/service/impl/SignFranchiseServiceImpl.java

Signed-off-by: 正新 <accounts_6964c7bcd2a2c377c5bbd01b@mail.teambition.com>
Merged-by: 正新 <accounts_6964c7bcd2a2c377c5bbd01b@mail.teambition.com>

CR-link: https://codeup.aliyun.com/692ea314dec569489f6f167c/hangzhou/java/custom_zxjp/change/52
This commit is contained in:
正新
2026-03-10 14:13:03 +00:00
parent 5c49337e1f
commit 489d72f06f
264 changed files with 13194 additions and 99 deletions

View File

@@ -157,6 +157,8 @@ public class WalletHttpClientRest {
// 700-799为平安银行错误
if (code >= 700 && code <= 799) {
throw new ServiceException(ErrorCodeEnum.WALLET_API_ERROR, msg);
} else if (code == 610 || msg.equals("支付密码不正确")) {
throw new ServiceException(ErrorCodeEnum.PASSWORD_ERROR);
} else {
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,
"code: " + code + ", msg: " + msg);

View File

@@ -85,13 +85,20 @@ public interface DeskService {
PageInfo<PreparationCommonPendingVO> payFranchiseFeesPendingList(DeskRequest deskRequest, LoginUserInfo user );
/**
* 加盟合同签约待处理数据
* @param user
* @return
*/
PageInfo<PreparationCommonPendingVO> signingOfFranchiseContractPendingList(DeskRequest deskRequest, LoginUserInfo user );
/**
* 店型选配 代处理数据
* @param deskRequest
* @param user
* @return
*/
PageInfo<PreparationCommonPendingVO> standardStorePendingList(DeskRequest deskRequest, LoginUserInfo user );
/**
* 发票回传待处理数据

View File

@@ -1,14 +1,12 @@
package com.cool.store.service;
import com.cool.store.dto.Preparation.PreparationDTO;
import com.cool.store.dto.pre.fry.ApplyManagementDTO;
import com.cool.store.entity.ImportTaskDO;
import com.cool.store.entity.LineInfoDO;
import com.cool.store.entity.PointInfoDO;
import com.cool.store.request.AllPointPageRequest;
import com.cool.store.request.FranchiseReportRequest;
import com.cool.store.request.PointPageRequest;
import com.cool.store.request.order.PCStoreOrderQueryRequest;
import com.cool.store.request.visit.VisitRecordQueryRequest;
import com.cool.store.request.PointPageRequest;
import com.cool.store.response.BranchShopResponse;
import com.cool.store.response.FranchiseReportResponse;
import com.cool.store.response.ShopReportResponse;
@@ -35,6 +33,7 @@ public interface ExportRealizeService {
void exportZxjpOpenShopReport(List<FranchiseReportResponse> list, ImportTaskDO importTaskDO, FranchiseReportRequest request);
void exportZxjpOpenShopReportPage(List<ShopReportResponse> list, ImportTaskDO importTaskDO, FranchiseReportRequest request);
void exportPreFryQualificationApply(List<ApplyManagementDTO> list, ImportTaskDO importTaskDO);
/**
@@ -42,6 +41,7 @@ public interface ExportRealizeService {
*/
void exportVisitRecord(VisitRecordQueryRequest request, ImportTaskDO importTaskDO);
void exportOrderRecord(PCStoreOrderQueryRequest request, ImportTaskDO importTaskDO);
void exportPoint(AllPointPageRequest request, ImportTaskDO importTaskDO);
void myExportPoint(PointPageRequest request, String userId, ImportTaskDO importTaskDO);

View File

@@ -5,6 +5,8 @@ import com.cool.store.context.LoginUserInfo;
import com.cool.store.dto.pre.fry.ApplyManagementQueryDTO;
import com.cool.store.enums.FileTypeEnum;
import com.cool.store.request.*;
import com.cool.store.request.order.PCStoreOrderQueryRequest;
import com.cool.store.request.visit.VisitRecordQueryRequest;
import com.cool.store.request.visit.VisitRecordQueryRequest;
/**
@@ -53,6 +55,13 @@ public interface ExportService {
*/
Long exportVisitRecord(VisitRecordQueryRequest request, LoginUserInfo user);
/**
* 导出标准店订单记录
* @param request
* @param user
* @return
*/
Long exportStandardStoreOrderRecord(PCStoreOrderQueryRequest request, LoginUserInfo user);
/**
* 全部铺位导出
* @param request 查询Request

View File

@@ -3,6 +3,7 @@ package com.cool.store.service;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.request.AuditFranchiseFeeRequest;
import com.cool.store.request.FranchiseFeeRequest;
import com.cool.store.request.FranchisePayTypeUpdateRequest;
import com.cool.store.request.xgj.FranchiseFeeCallBackRequest;
import com.cool.store.response.FranchiseFeeResponse;
import com.cool.store.response.bigdata.ApiResponse;
@@ -33,4 +34,11 @@ public interface FranchiseFeeService {
Boolean auditFranchiseFee(AuditFranchiseFeeRequest request, LoginUserInfo user);
ApiResponse<Boolean> changePaymentStatus(FranchiseFeeCallBackRequest request);
/**
* 修改付款方式
* @param request 加盟费支付方式修改Request
* @return 是否成功
*/
Boolean updatePayType(FranchisePayTypeUpdateRequest request);
}

View File

@@ -0,0 +1,20 @@
package com.cool.store.service.config;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.request.config.ConfigItemCategoryQueryRequest;
import com.cool.store.request.config.ConfigItemCategoryUpdateRequest;
import com.cool.store.vo.config.ConfigItemCategoryVO;
import com.github.pagehelper.PageInfo;
import java.util.List;
public interface ConfigItemCategoryService {
Boolean add(ConfigItemCategoryUpdateRequest request, LoginUserInfo userInfo);
Boolean update(ConfigItemCategoryUpdateRequest request,LoginUserInfo userInfo);
PageInfo<ConfigItemCategoryVO> queryPage(ConfigItemCategoryQueryRequest request);
Boolean deleteByIds(List<Long> ids);
}

View File

@@ -0,0 +1,22 @@
package com.cool.store.service.config;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.request.config.ConfigItemQueryRequest;
import com.cool.store.request.config.ConfigItemUpdateRequest;
import com.cool.store.vo.config.ConfigItemVO;
import com.github.pagehelper.PageInfo;
import java.util.List;
public interface ConfigItemService {
Boolean add(ConfigItemUpdateRequest request, LoginUserInfo userInfo);
Boolean update(ConfigItemUpdateRequest request, LoginUserInfo userInfo);
PageInfo<ConfigItemVO> queryPage(ConfigItemQueryRequest request);
List<ConfigItemVO> listByCategoryId(Long categoryId);
Boolean deleteByIds(List<Long> ids);
}

View File

@@ -0,0 +1,27 @@
package com.cool.store.service.config;
import com.cool.store.request.config.ConfigOptionQueryRequest;
import com.cool.store.request.config.ConfigOptionTreeQueryRequest;
import com.cool.store.request.config.ConfigOptionUpdateRequest;
import com.cool.store.vo.config.ConfigOptionTreeVO;
import com.cool.store.vo.config.ConfigOptionVO;
import com.github.pagehelper.PageInfo;
import java.util.List;
public interface ConfigOptionService {
Boolean add(ConfigOptionUpdateRequest request);
Boolean update(ConfigOptionUpdateRequest request);
PageInfo<ConfigOptionVO> queryPage(ConfigOptionQueryRequest request);
/**
* 获取所有的选项 三层结构
* 查询激活的配置选项三层结构:配置类型 -> 配置项 -> 配置选项
*/
List<ConfigOptionTreeVO> listActiveTree();
Boolean deleteByIds(List<Long> ids);
}

View File

@@ -0,0 +1,89 @@
package com.cool.store.service.config.impl;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.config.ConfigItemCategoryDAO;
import com.cool.store.dao.config.ConfigItemDAO;
import com.cool.store.entity.config.ConfigItemCategoryDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.config.ConfigItemCategoryQueryRequest;
import com.cool.store.request.config.ConfigItemCategoryUpdateRequest;
import com.cool.store.service.config.ConfigItemCategoryService;
import com.cool.store.utils.StringUtil;
import com.cool.store.utils.UUIDUtils;
import com.cool.store.vo.config.ConfigItemCategoryVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.Date;
import java.util.List;
@Service
@RequiredArgsConstructor
public class ConfigItemCategoryServiceImpl implements ConfigItemCategoryService {
private final ConfigItemCategoryDAO configItemCategoryDAO;
private final ConfigItemDAO configItemDAO;
@Override
public Boolean add(ConfigItemCategoryUpdateRequest request, LoginUserInfo userInfo) {
if (StringUtil.isEmpty(request.getCategoryCode())){
request.setCategoryCode(UUIDUtils.get8UUID());
}
if (configItemDAO.existsItemCode(request.getCategoryCode(),request.getId())){
throw new ServiceException(ErrorCodeEnum.CODE_EXIST);
}
ConfigItemCategoryDO entity = new ConfigItemCategoryDO();
entity.setCategoryCode(request.getCategoryCode());
entity.setCategoryName(request.getCategoryName());
entity.setSortNo(request.getSortNo());
entity.setImageUrl(request.getImageUrl());
entity.setVideoUrl(request.getVideoUrl());
entity.setStatus(request.getStatus());
entity.setRemark(request.getRemark());
entity.setCreatedTime(new Date());
entity.setCreatedUserId(userInfo.getUserId());
entity.setIsDeleted(0);
return configItemCategoryDAO.insertSelective(entity);
}
@Override
public Boolean update(ConfigItemCategoryUpdateRequest request,LoginUserInfo userInfo) {
if (StringUtil.isNotEmpty(request.getCategoryCode())&&configItemDAO.existsItemCode(request.getCategoryCode(),request.getId())){
throw new ServiceException(ErrorCodeEnum.CODE_EXIST);
}
ConfigItemCategoryDO entity = new ConfigItemCategoryDO();
entity.setId(request.getId());
entity.setCategoryName(request.getCategoryName());
entity.setSortNo(request.getSortNo());
entity.setImageUrl(request.getImageUrl());
entity.setVideoUrl(request.getVideoUrl());
entity.setStatus(request.getStatus());
entity.setRemark(request.getRemark());
entity.setUpdatedTime(new Date());
entity.setUpdatedUserId(userInfo.getUserId());
return configItemCategoryDAO.updateSelective(entity);
}
@Override
public PageInfo<ConfigItemCategoryVO> queryPage(ConfigItemCategoryQueryRequest request) {
PageHelper.startPage(request.getPageNum(), request.getPageSize());
List<ConfigItemCategoryVO> list = configItemCategoryDAO.queryByCondition(request.getCategoryName(), request.getStatus());
return new PageInfo<>(list);
}
@Override
public Boolean deleteByIds(List<Long> ids) {
if (CollectionUtils.isEmpty(ids)) {
return false;
}
if (configItemDAO.countByCategoryIds(ids) > 0) {
return false;
}
return configItemCategoryDAO.softDeleteByIds(ids);
}
}

View File

@@ -0,0 +1,93 @@
package com.cool.store.service.config.impl;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.config.ConfigItemCategoryDAO;
import com.cool.store.dao.config.ConfigItemDAO;
import com.cool.store.entity.config.ConfigItemDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.config.ConfigItemQueryRequest;
import com.cool.store.request.config.ConfigItemUpdateRequest;
import com.cool.store.service.config.ConfigItemService;
import com.cool.store.utils.StringUtil;
import com.cool.store.utils.UUIDUtils;
import com.cool.store.vo.config.ConfigItemVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@Service
@RequiredArgsConstructor
public class ConfigItemServiceImpl implements ConfigItemService {
private final ConfigItemDAO configItemDAO;
private final ConfigItemCategoryDAO configItemCategoryDAO;
@Override
public Boolean add(ConfigItemUpdateRequest request, LoginUserInfo userInfo) {
if (StringUtil.isEmpty(request.getItemCode())){
request.setItemCode(UUIDUtils.get8UUID());
}
if (StringUtil.isNotEmpty(request.getItemCode())&&configItemDAO.existsItemCode(request.getItemCode(),request.getId())){
throw new ServiceException(ErrorCodeEnum.CODE_EXIST);
}
ConfigItemDO entity = new ConfigItemDO();
entity.setItemName(request.getItemName());
entity.setItemCode(request.getItemCode());
entity.setCategoryId(request.getCategoryId());
entity.setSortNo(request.getSortNo());
entity.setStatus(request.getStatus());
entity.setRemark(request.getRemark());
entity.setCreatedTime(new Date());
entity.setCreatedUserId(userInfo.getUserId());
entity.setIsDeleted(0);
return configItemDAO.insertSelective(entity);
}
@Override
public Boolean update(ConfigItemUpdateRequest request, LoginUserInfo userInfo) {
if (request.getId()==null){
throw new ServiceException(ErrorCodeEnum.ERROR_MESSAGE);
}
if (StringUtil.isNotEmpty(request.getItemCode())&&configItemDAO.existsItemCode(request.getItemCode(),request.getId())){
throw new ServiceException(ErrorCodeEnum.CODE_EXIST);
}
ConfigItemDO entity = new ConfigItemDO();
entity.setId(request.getId());
entity.setItemName(request.getItemName());
entity.setCategoryId(request.getCategoryId());
entity.setSortNo(request.getSortNo());
entity.setStatus(request.getStatus());
entity.setRemark(request.getRemark());
entity.setUpdatedTime(new Date());
entity.setUpdatedUserId(userInfo.getUserId());
return configItemDAO.updateSelective(entity);
}
@Override
public PageInfo<ConfigItemVO> queryPage(ConfigItemQueryRequest request) {
PageHelper.startPage(request.getPageNum(), request.getPageSize());
List<ConfigItemVO> list = configItemDAO.queryByCondition(request.getItemName(), request.getItemCode(), request.getCategoryId(), request.getStatus());
return new PageInfo<>(list);
}
@Override
public List<ConfigItemVO> listByCategoryId(Long categoryId) {
return configItemDAO.queryByCondition(null, null, categoryId,1);
}
@Override
public Boolean deleteByIds(List<Long> ids) {
if (CollectionUtils.isEmpty(ids)) {
return false;
}
return configItemDAO.softDeleteByIds(ids);
}
}

View File

@@ -0,0 +1,193 @@
package com.cool.store.service.config.impl;
import com.cool.store.dao.config.ConfigItemCategoryDAO;
import com.cool.store.dao.config.ConfigItemDAO;
import com.cool.store.dao.config.ConfigOptionDAO;
import com.cool.store.dao.dict.SysDictTableDAO;
import com.cool.store.dao.store.StoreTypeOptionDAO;
import com.cool.store.entity.config.ConfigOptionDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.config.ConfigOptionQueryRequest;
import com.cool.store.request.config.ConfigOptionUpdateRequest;
import com.cool.store.request.dict.DictColumnQueryRequest;
import com.cool.store.service.config.ConfigOptionService;
import com.cool.store.service.dict.DictColumnService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.UUIDUtils;
import com.cool.store.vo.config.*;
import com.cool.store.vo.dict.DictColumnVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class ConfigOptionServiceImpl implements ConfigOptionService {
private final ConfigOptionDAO configOptionDAO;
private final StoreTypeOptionDAO storeTypeOptionDAO;
private final DictColumnService dictColumnService;
private final SysDictTableDAO dictTableInfoDAO;
private final ConfigItemCategoryDAO configItemCategoryDAO;
private final ConfigItemDAO configItemDAO;
@Override
public Boolean add(ConfigOptionUpdateRequest request) {
if (request.getSortOrder() != null && configOptionDAO.existsSortOrder(request.getSortOrder(), null)) {
throw new ServiceException(ErrorCodeEnum.CURRENT_BRAND_SORT_NUMBER_EXIST);
}
ConfigOptionDO entity = BeanUtil.toBean(request, ConfigOptionDO.class);
entity.setOptionCode(UUIDUtils.get8UUID());
return configOptionDAO.insertSelective(entity);
}
@Override
public Boolean update(ConfigOptionUpdateRequest request) {
if (request.getSortOrder() != null) {
ConfigOptionDO old = configOptionDAO.getById(request.getId());
boolean sortChanged = old == null || old.getSortOrder() == null || !old.getSortOrder().equals(request.getSortOrder());
if (sortChanged && configOptionDAO.existsSortOrder(request.getSortOrder(), request.getId())) {
throw new ServiceException(ErrorCodeEnum.CURRENT_BRAND_SORT_NUMBER_EXIST);
}
}
ConfigOptionDO entity = BeanUtil.toBean(request, ConfigOptionDO.class);
return configOptionDAO.updateSelective(entity);
}
@Override
public PageInfo<ConfigOptionVO> queryPage(ConfigOptionQueryRequest request) {
PageHelper.startPage(request.getPageNum(), request.getPageSize());
List<ConfigOptionDO> list = configOptionDAO.query(request.getCategoryCode(), request.getItemCode(), request.getActive(), request.getOptionName());
return BeanUtil.toPage(new PageInfo<>(list), ConfigOptionVO.class);
}
@Override
public List<ConfigOptionTreeVO> listActiveTree() {
// 1) 查询配置类型表:决定第一层顺序
List<ConfigItemCategoryBaseInfoVO> typeDictList = configItemCategoryDAO.queryAllList();
// 2) 查询配置项表:决定第二层顺序 & 名称
List<ConfigItemVO> itemDictList = configItemDAO.queryByCondition("", "", null, 1);
Map<String, ConfigItemVO> itemDictMap = itemDictList.stream()
.filter(v -> v.getItemCode() != null)
.collect(Collectors.toMap(ConfigItemVO::getItemCode, Function.identity(), (a, b) -> a));
// 3) 一次性查询所有激活的配置选项(可选模糊名称)
List<ConfigOptionDO> options = configOptionDAO.query(null, null, 1, null);
if (CollectionUtils.isEmpty(options)) {
return Collections.emptyList();
}
// 4) 按 categoryCode -> itemCode 分组
Map<String, Map<String, List<ConfigOptionDO>>> groupMap = options.stream()
.filter(v -> Boolean.TRUE.equals(v.getActive()))
.collect(Collectors.groupingBy(
ConfigOptionDO::getCategoryCode,
Collectors.groupingBy(ConfigOptionDO::getItemCode)
));
// 5) 组装三层结构:第一层按 type 字典顺序;第二层按 item 字典顺序;第三层按 sortOrder
List<ConfigOptionTreeVO> result = new ArrayList<>();
for (ConfigItemCategoryBaseInfoVO typeDict : typeDictList) {
String categoryCode = typeDict.getCategoryCode();
Map<String, List<ConfigOptionDO>> itemOptionsMap = groupMap.get(categoryCode);
if (itemOptionsMap == null || itemOptionsMap.isEmpty()) {
continue;
}
ConfigOptionTreeVO typeVO = new ConfigOptionTreeVO();
typeVO.setCategoryCode(categoryCode);
typeVO.setCategoryName(typeDict.getCategoryName());
List<ConfigOptionTreeVO.ConfigItemVO> itemVOList = new ArrayList<>();
for (ConfigItemVO itemDict : itemDictList) {
String itemCode = itemDict.getItemCode();
List<ConfigOptionDO> optionList = itemOptionsMap.get(itemCode);
if (CollectionUtils.isEmpty(optionList)) {
continue;
}
ConfigOptionTreeVO.ConfigItemVO itemVO = new ConfigOptionTreeVO.ConfigItemVO();
itemVO.setItemCode(itemCode);
itemVO.setItemName(itemDict.getItemName());
List<ConfigOptionVO> optionVOList = optionList.stream()
.sorted(Comparator.comparing(ConfigOptionDO::getSortOrder, Comparator.nullsLast(Integer::compareTo)))
.map(v -> BeanUtil.toBean(v, ConfigOptionVO.class))
.collect(Collectors.toList());
itemVO.setOptions(optionVOList);
itemVOList.add(itemVO);
}
// 如果 itemCode 没在字典表11里比如数据脏了补在最后
Set<String> knownItemCodes = itemDictMap.keySet();
List<String> unknownItemCodes = itemOptionsMap.keySet().stream()
.filter(v -> v != null && !knownItemCodes.contains(v))
.sorted()
.collect(Collectors.toList());
for (String itemCode : unknownItemCodes) {
List<ConfigOptionDO> optionList = itemOptionsMap.get(itemCode);
if (CollectionUtils.isEmpty(optionList)) {
continue;
}
ConfigOptionTreeVO.ConfigItemVO itemVO = new ConfigOptionTreeVO.ConfigItemVO();
itemVO.setItemCode(itemCode);
itemVO.setItemName(itemCode);
List<ConfigOptionVO> optionVOList = optionList.stream()
.sorted(Comparator.comparing(ConfigOptionDO::getSortOrder, Comparator.nullsLast(Integer::compareTo)))
.map(v -> BeanUtil.toBean(v, ConfigOptionVO.class))
.collect(Collectors.toList());
itemVO.setOptions(optionVOList);
itemVOList.add(itemVO);
}
if (CollectionUtils.isEmpty(itemVOList)) {
continue;
}
typeVO.setItems(itemVOList);
result.add(typeVO);
}
return result;
}
private List<DictColumnVO> listOpenDictColumns(Long dictTableId) {
DictColumnQueryRequest dictReq = DictColumnQueryRequest.builder()
.dictTableId(dictTableId)
.openStatus(1)
.build();
dictReq.setPageSize(10000);
dictReq.setPageNum(1);
PageInfo<DictColumnVO> page = dictColumnService.getPage(dictReq);
return page == null ? Collections.emptyList() : Optional.ofNullable(page.getList()).orElse(Collections.emptyList());
}
@Override
public Boolean deleteByIds(List<Long> ids) {
if (CollectionUtils.isEmpty(ids)) {
return false;
}
for (Long id : ids) {
int usedCount = storeTypeOptionDAO.countByOptionId(id);
if (usedCount > 0) {
throw new ServiceException(ErrorCodeEnum.CONFIG_OPTION_USED);
}
ConfigOptionDO update = new ConfigOptionDO();
update.setId(id);
update.setActive(false);
configOptionDAO.updateSelective(update);
}
return true;
}
}

View File

@@ -155,6 +155,7 @@ public class DictService {
Map<String, Field> fieldMap = CollStreamUtil.toMap(Arrays.asList(fields), Field::getName, v -> v);
List<Pair<Field, Field>> dictFields = new ArrayList<>();
for (Field field : fields) {
// 这里需要优化,对象类型字段也需要转义,注意可能出现的循环嵌套问题
DictField dictField = field.getAnnotation(DictField.class);
if (Objects.nonNull(dictField)) {
field.setAccessible(true);

View File

@@ -0,0 +1,29 @@
package com.cool.store.service.fees;
import com.cool.store.request.fees.FeeStandardConfigAddRequest;
import com.cool.store.request.fees.FeeStandardConfigPageRequest;
import com.cool.store.vo.fees.FeeStandardConfigVO;
import com.github.pagehelper.PageInfo;
import java.util.List;
/**
* 加盟费用标准收费额配置Service
*/
public interface FeeStandardConfigService {
Boolean add(FeeStandardConfigAddRequest request);
Boolean update(FeeStandardConfigAddRequest request);
PageInfo<FeeStandardConfigVO> page(FeeStandardConfigPageRequest request);
/**
* 根据门店id查询配置
* @param shopId 门店id
* @return 加盟费用标准收费额配置VO
*/
List<FeeStandardConfigVO> getByShopId(Long shopId);
}

View File

@@ -0,0 +1,28 @@
package com.cool.store.service.fees;
import com.cool.store.request.fees.PayeeBankConfigAddRequest;
import com.cool.store.request.fees.PayeeBankConfigPageRequest;
import com.cool.store.vo.fees.PayeeBankConfigVO;
import com.github.pagehelper.PageInfo;
/**
* 线下收款银行配置Service
*/
public interface PayeeBankConfigService {
Boolean add(PayeeBankConfigAddRequest request);
Boolean update(PayeeBankConfigAddRequest request);
PageInfo<PayeeBankConfigVO> page(PayeeBankConfigPageRequest request);
/**
* 根据门店id查询线下收款银行配置
* @param shopId 门店id
* @param payType 支付方式
* @return 线下收款银行配置VO
*/
PayeeBankConfigVO getByShopId(Long shopId, Integer payType);
}

View File

@@ -0,0 +1,41 @@
package com.cool.store.service.fees;
import com.cool.store.entity.fees.ShopAllocationInfoDO;
import com.cool.store.request.fees.ShopAllocationInfoRequest;
import com.cool.store.vo.fees.ShopAllocationSimpleVO;
import java.util.List;
/**
* <p>
* 门店平安钱包分账信息服务类
* </p>
*
* @author wangff
* @since 2026/1/29
*/
public interface ShopAllocationInfoService {
/**
* 根据门店id查询门店分账信息不存在时获取默认数据
* @param shopId 门店id
* @return 门店平安钱包分账信息列表
*/
List<ShopAllocationInfoDO> getOrDefault(Long shopId);
/**
* 根据门店id查询门店分账信息
* @param shopId 门店id
* @return 门店平安钱包分账信息列表
*/
List<ShopAllocationSimpleVO> getSimpleInfo(Long shopId);
/**
* 批量新增
*/
void insertBatch(Long shopId, List<ShopAllocationInfoRequest> list);
/**
* 批量更新
*/
void updateBatch(Long shopId, List<ShopAllocationInfoRequest> list);
}

View File

@@ -0,0 +1,47 @@
package com.cool.store.service.fees;
import com.cool.store.request.fees.WalletCompanyQueryRequest;
import com.cool.store.request.fees.WalletAllocationConfigAddRequest;
import com.cool.store.request.fees.WalletAllocationConfigPageRequest;
import com.cool.store.vo.fees.InvestDivisionRegionVO;
import com.cool.store.vo.fees.WalletAllocationCompanyVO;
import com.cool.store.vo.fees.WalletAllocationConfigVO;
import com.github.pagehelper.PageInfo;
import java.util.List;
/**
* 分账配置服务接口
*
* @author system
*/
public interface WalletAllocationConfigService {
/**
* 新增分账配置
*/
Boolean add(WalletAllocationConfigAddRequest request);
/**
* 编辑分账配置
*/
Boolean update(WalletAllocationConfigAddRequest request);
/**
* 分页查询分账配置
*/
PageInfo<WalletAllocationConfigVO> page(WalletAllocationConfigPageRequest request);
/**
* 获取招商分部列表
*/
List<InvestDivisionRegionVO> getInvestDivisionRegionList();
/**
* 公司列表
* @param request 收款公司查询Request
* @return 分页对象
*/
PageInfo<WalletAllocationCompanyVO> companyPage(WalletCompanyQueryRequest request);
}

View File

@@ -0,0 +1,54 @@
package com.cool.store.service.fees;
import com.cool.store.request.fees.WalletCancelPayRequest;
import com.cool.store.request.fees.WalletPayRequest;
import com.cool.store.request.fees.WalletRepayRequest;
import com.cool.store.vo.fees.WalletPayInfoVO;
import java.util.List;
/**
* <p>
* 钱包加盟缴费服务类
* </p>
*
* @author wangff
* @since 2026/1/30
*/
public interface WalletPayInfoService {
/**
* 支付
* @param request 钱包支付Request
* @param oldPayNo 重新支付订单号
* @return 是否成功
*/
Boolean pay(WalletPayRequest request, String oldPayNo);
/**
* 重新支付
* @param request 钱包重新支付Request
* @return 是否成功
*/
Boolean rePay(WalletRepayRequest request);
/**
* 取消支付
* @param request 钱包取消支付Request
* @return 是否成功
*/
Boolean cancelPay(WalletCancelPayRequest request);
/**
* 根据门店id查询缴费信息列表
* @param shopId 门店id
* @return 钱包加盟缴费信息VO列表
*/
List<WalletPayInfoVO> payInfoList(Long shopId, Integer payStatus);
/**
* 重新推送账单到新管家
* @param walletPayInfoId 支付信息
*/
void rePushReceipt(Long walletPayInfoId);
}

View File

@@ -0,0 +1,94 @@
package com.cool.store.service.fees.impl;
import cn.hutool.core.collection.CollStreamUtil;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.dao.EnterpriseUserDAO;
import com.cool.store.dao.ShopInfoDAO;
import com.cool.store.dao.fees.FeeStandardConfigDAO;
import com.cool.store.dao.modify.ModifyRecordDAO;
import com.cool.store.entity.ShopInfoDO;
import com.cool.store.entity.fees.FeeStandardConfigDO;
import com.cool.store.enums.BusinessModuleEnum;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.fees.FeeStandardConfigAddRequest;
import com.cool.store.request.fees.FeeStandardConfigPageRequest;
import com.cool.store.service.dict.impl.DictService;
import com.cool.store.service.fees.FeeStandardConfigService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.vo.fees.FeeStandardConfigVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
/**
* 加盟费用标准收费额配置Service实现
*/
@Service
@RequiredArgsConstructor
public class FeeStandardConfigServiceImpl implements FeeStandardConfigService {
private final FeeStandardConfigDAO feeStandardConfigDAO;
private final ModifyRecordDAO modifyRecordDAO;
private final DictService dictService;
private final EnterpriseUserDAO enterpriseUserDAO;
private final ShopInfoDAO shopInfoDAO;
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean add(FeeStandardConfigAddRequest request) {
verifyUnique(request.getJoinBrand(), request.getExpenseType(), null);
FeeStandardConfigDO configDO = BeanUtil.toBean(request, FeeStandardConfigDO.class);
configDO.setCreateUserId(CurrentUserHolder.getUserId());
feeStandardConfigDAO.insertSelective(configDO);
return true;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean update(FeeStandardConfigAddRequest request) {
verifyUnique(request.getJoinBrand(), request.getExpenseType(), request.getId());
FeeStandardConfigDO updateDO = BeanUtil.toBean(request, FeeStandardConfigDO.class);
feeStandardConfigDAO.updateByPrimaryKeySelective(updateDO);
modifyRecordDAO.insertRecord(BusinessModuleEnum.FEE_STANDARD_CONFIG, request.getId(), CurrentUserHolder.getUserId());
return true;
}
@Override
public PageInfo<FeeStandardConfigVO> page(FeeStandardConfigPageRequest request) {
PageHelper.startPage(request.getPageNum(), request.getPageSize());
List<FeeStandardConfigDO> list = feeStandardConfigDAO.selectByCondition(request.getJoinBrand(), request.getExpenseType());
PageInfo<FeeStandardConfigDO> page = new PageInfo<>(list);
Set<String> userIds = CollStreamUtil.toSet(list, FeeStandardConfigDO::getCreateUserId);
Map<String, String> userNameMap = enterpriseUserDAO.getUserNameMap(new ArrayList<>(userIds));
PageInfo<FeeStandardConfigVO> newPage = BeanUtil.toPage(page, FeeStandardConfigVO.class);
newPage.getList().forEach(v -> v.setCreateUserName(userNameMap.get(v.getCreateUserId())));
dictService.fillDictField(newPage.getList());
return newPage;
}
@Override
public List<FeeStandardConfigVO> getByShopId(Long shopId) {
ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
if (Objects.isNull(shopInfo)) {
throw new ServiceException(ErrorCodeEnum.SHOP_NOT_EXIST);
}
List<FeeStandardConfigDO> list = feeStandardConfigDAO.selectByCondition(Integer.valueOf(shopInfo.getFranchiseBrand()), null);
return BeanUtil.toList(list, FeeStandardConfigVO.class);
}
private void verifyUnique(Integer joinBrand, String expenseType, Long excludeId) {
if (feeStandardConfigDAO.existJoinBrandAndExpenseType(joinBrand, expenseType.trim(), excludeId)) {
throw new ServiceException(ErrorCodeEnum.FEE_STANDARD_UNIQUE_KEY_EXISTS);
}
}
}

View File

@@ -0,0 +1,122 @@
package com.cool.store.service.fees.impl;
import cn.hutool.core.collection.CollStreamUtil;
import com.cool.store.constants.RedisConstant;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.dao.EnterpriseUserDAO;
import com.cool.store.dao.FranchiseFeeDAO;
import com.cool.store.dao.RegionDao;
import com.cool.store.dao.ShopInfoDAO;
import com.cool.store.dao.modify.ModifyRecordDAO;
import com.cool.store.dao.fees.PayeeBankConfigDAO;
import com.cool.store.entity.FranchiseFeeDO;
import com.cool.store.entity.RegionDO;
import com.cool.store.entity.ShopInfoDO;
import com.cool.store.entity.fees.PayeeBankConfigDO;
import com.cool.store.enums.BusinessModuleEnum;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.fees.PayeeBankConfigAddRequest;
import com.cool.store.request.fees.PayeeBankConfigPageRequest;
import com.cool.store.service.fees.PayeeBankConfigService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.RedisUtilPool;
import com.cool.store.vo.fees.PayeeBankConfigVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
/**
* 线下收款银行配置Service实现
*/
@Service
@RequiredArgsConstructor
public class PayeeBankConfigServiceImpl implements PayeeBankConfigService {
private final PayeeBankConfigDAO payeeBankConfigDAO;
private final RedisUtilPool redisUtilPool;
private final ModifyRecordDAO modifyRecordDAO;
private final EnterpriseUserDAO enterpriseUserDAO;
private final ShopInfoDAO shopInfoDAO;
private final FranchiseFeeDAO franchiseFeeDAO;
private final RegionDao regionDao;
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean add(PayeeBankConfigAddRequest request) {
verify(request.getJoinBrand(), request.getInvestDivisionId(), request.getPayType(), null);
String userId = CurrentUserHolder.getUserId();
PayeeBankConfigDO configDO = BeanUtil.toBean(request, PayeeBankConfigDO.class);
configDO.setCreateUserId(userId);
payeeBankConfigDAO.insertSelective(configDO);
return true;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean update(PayeeBankConfigAddRequest request) {
verify(request.getJoinBrand(), request.getInvestDivisionId(), request.getPayType(), request.getId());
PayeeBankConfigDO updateDO = BeanUtil.toBean(request, PayeeBankConfigDO.class);
payeeBankConfigDAO.updateByPrimaryKeySelective(updateDO);
// 新增业务修改记录
modifyRecordDAO.insertRecord(BusinessModuleEnum.PAYEE_BANK_CONFIG, request.getId(), CurrentUserHolder.getUserId());
return true;
}
@Override
public PageInfo<PayeeBankConfigVO> page(PayeeBankConfigPageRequest request) {
PageHelper.startPage(request.getPageNum(), request.getPageSize());
List<PayeeBankConfigDO> list = payeeBankConfigDAO.selectByCondition(
request.getJoinBrand(),
request.getInvestDivisionId(),
request.getPayType()
);
PageInfo<PayeeBankConfigDO> page = new PageInfo<>(list);
PageInfo<PayeeBankConfigVO> newPage = BeanUtil.toPage(page, PayeeBankConfigVO.class);
Set<String> userIds = CollStreamUtil.toSet(list, PayeeBankConfigDO::getCreateUserId);
Map<String, String> userNameMap = enterpriseUserDAO.getUserNameMap(new ArrayList<>(userIds));
newPage.getList().forEach(v -> {
v.setInvestDivisionName(redisUtilPool.hashGet(RedisConstant.WALLET_ALLOCATION_CONFIG_INVEST_DIVISION, String.valueOf(v.getInvestDivisionId())));
v.setCreateUserName(userNameMap.get(v.getCreateUserId()));
});
return newPage;
}
@Override
public PayeeBankConfigVO getByShopId(Long shopId, Integer payType) {
ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
if (Objects.isNull(shopInfo)) {
throw new ServiceException(ErrorCodeEnum.SHOP_NOT_EXIST);
}
FranchiseFeeDO franchiseFeeDO = franchiseFeeDAO.selectByShopId(shopId);
if (Objects.isNull(payType) && (Objects.isNull(franchiseFeeDO) || Objects.isNull(franchiseFeeDO.getPayType()))) {
throw new ServiceException(ErrorCodeEnum.NO_PAYMENT_METHOD_IS_SET);
}
RegionDO regionDO = regionDao.getRegionById(shopInfo.getInvestRegionId());
PayeeBankConfigDO configDO = payeeBankConfigDAO.getByUniqueKey(Integer.valueOf(shopInfo.getFranchiseBrand()), Long.valueOf(regionDO.getParentId()), Objects.nonNull(payType) ? payType : franchiseFeeDO.getPayType());
return BeanUtil.toBean(configDO, PayeeBankConfigVO.class);
}
/**
* 校验:
* 1) 加盟品牌+招商分部+付款方式唯一
* 2) 同品牌同支付方式只能存在分部或全部
*/
private void verify(Integer joinBrand, Long investDivisionId, Integer payType, Long excludeId) {
if (payeeBankConfigDAO.existOtherInvestType(joinBrand, payType, investDivisionId, excludeId)) {
throw new ServiceException(ErrorCodeEnum.BANK_CONFIG_INVEST_TYPE_EXISTS);
}
if (payeeBankConfigDAO.existUniqueKey(joinBrand, investDivisionId, payType, excludeId)) {
throw new ServiceException(ErrorCodeEnum.BANK_CONFIG_UNIQUE_KEY_EXISTS);
}
}
}

View File

@@ -0,0 +1,144 @@
package com.cool.store.service.fees.impl;
import cn.hutool.core.collection.CollStreamUtil;
import com.cool.store.constants.DictConstants;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.dao.RegionDao;
import com.cool.store.dao.ShopInfoDAO;
import com.cool.store.dao.dict.SysDictColumnDAO;
import com.cool.store.dao.fees.*;
import com.cool.store.entity.RegionDO;
import com.cool.store.entity.ShopInfoDO;
import com.cool.store.entity.fees.*;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.fees.AllocationPayStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.fees.ShopAllocationInfoRequest;
import com.cool.store.service.dict.impl.DictService;
import com.cool.store.service.fees.ShopAllocationInfoService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.vo.dict.DictColumnSimpleVO;
import com.cool.store.vo.fees.ShopAllocationSimpleVO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
* <p>
* 门店平安钱包分账信息服务实现类
* </p>
*
* @author wangff
* @since 2026/1/29
*/
@Service
@RequiredArgsConstructor
public class ShopAllocationInfoServiceImpl implements ShopAllocationInfoService {
private final ShopAllocationInfoDAO shopAllocationInfoDAO;
private final SysDictColumnDAO dictColumnDAO;
private final WalletAllocationConfigDAO walletAllocationConfigDAO;
private final WalletAllocationCompanyDAO walletAllocationCompanyDAO;
private final FeeStandardConfigDAO feeStandardConfigDAO;
private final ShopInfoDAO shopInfoDAO;
private final RegionDao regionDao;
private final WalletPayInfoDAO walletPayInfoDAO;
private final DictService dictService;
@Override
public List<ShopAllocationInfoDO> getOrDefault(Long shopId) {
List<ShopAllocationInfoDO> list = shopAllocationInfoDAO.getByShopId(shopId);
if (CollectionUtils.isEmpty(list)) {
list = getDefault(shopId);
}
return list;
}
@Override
public List<ShopAllocationSimpleVO> getSimpleInfo(Long shopId) {
List<ShopAllocationInfoDO> list = shopAllocationInfoDAO.getByShopId(shopId);
List<ShopAllocationSimpleVO> result = BeanUtil.toList(list, ShopAllocationSimpleVO.class);
dictService.fillDictField(result);
result.forEach(v -> v.setGroupName(v.getExpenseType()));
return result;
}
@Override
public void insertBatch(Long shopId, List<ShopAllocationInfoRequest> list) {
if (CollectionUtils.isEmpty(list)) {
return;
}
List<ShopAllocationInfoDO> infoList = BeanUtil.toList(list, ShopAllocationInfoDO.class);
String userId = CurrentUserHolder.getUserId();
infoList.forEach(v -> {
v.setShopId(shopId);
v.setCreateUserId(userId);
v.setUpdateUserId(userId);
v.setStatus(AllocationPayStatusEnum.PAYING.getStatus());
});
shopAllocationInfoDAO.insertOrUpdateBatch(infoList);
}
@Override
public void updateBatch(Long shopId, List<ShopAllocationInfoRequest> list) {
// 存在缴费信息则无法更改
if (walletPayInfoDAO.existPayInfo(shopId)) {
throw new ServiceException(ErrorCodeEnum.EXIST_PAY_INFO);
}
if (CollectionUtils.isEmpty(list)) {
return;
}
List<ShopAllocationInfoDO> infoList = BeanUtil.toList(list, ShopAllocationInfoDO.class);
String userId = CurrentUserHolder.getUserId();
infoList.forEach(v -> {
v.setShopId(shopId);
v.setUpdateUserId(userId);
});
shopAllocationInfoDAO.insertOrUpdateBatch(infoList);
}
/**
* 获取默认配置
* @param shopId 门店id
* @return 分账信息列表
*/
public List<ShopAllocationInfoDO> getDefault(Long shopId) {
List<DictColumnSimpleVO> expenseTypes = dictColumnDAO.getOpenColumnListByTableCode(Collections.singletonList(DictConstants.EXPENSE_TYPE));
ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
if (Objects.isNull(shopInfo)) {
throw new ServiceException(ErrorCodeEnum.SHOP_NOT_EXIST);
}
RegionDO regionDO = regionDao.getRegionById(shopInfo.getInvestRegionId());
Integer joinBrand = Integer.valueOf(shopInfo.getFranchiseBrand());
// 查询分账公司配置
List<WalletAllocationConfigDO> allocationConfigList = walletAllocationConfigDAO.selectByBrandAndInvest(joinBrand, Long.valueOf(regionDO.getParentId()));
List<Long> allocationConfigIds = CollStreamUtil.toList(allocationConfigList, WalletAllocationConfigDO::getId);
Map<Long, List<WalletAllocationCompanyDO>> allocationCompanyMap = walletAllocationCompanyDAO.selectGroupByConfigIds(allocationConfigIds);
Map<String, WalletAllocationCompanyDO> allocationCompanyConfig = CollStreamUtil.toMap(allocationConfigList, WalletAllocationConfigDO::getExpenseType, v -> allocationCompanyMap.getOrDefault(v.getId(), Collections.emptyList())
.stream()
.findFirst()
.orElse(null)
);
// 查询加盟费用标准收费额配置
Map<String, FeeStandardConfigDO> standardConfigMap = feeStandardConfigDAO.getStandardConfigMap(joinBrand);
// 查询配置
return expenseTypes.stream()
.filter(v -> DictConstants.PING_AN_DEFAULT_ALLOCATION_EXPENSE_TYPE_CODES.contains(v.getColumnCode()))
.map(v -> {
FeeStandardConfigDO standardConfigDO = standardConfigMap.get(v.getColumnCode());
WalletAllocationCompanyDO allocationCompanyDO = allocationCompanyConfig.get(v.getColumnCode());
return ShopAllocationInfoDO.builder()
.shopId(shopId)
.expenseType(v.getColumnCode())
.payeeName(Objects.nonNull(allocationCompanyDO) ? allocationCompanyDO.getPayeeName() : null)
.payeeCode(Objects.nonNull(allocationCompanyDO) ? allocationCompanyDO.getPayeeCode() : null)
.amount(Objects.nonNull(standardConfigDO) ? standardConfigDO.getAmount() : BigDecimal.ZERO)
.status(AllocationPayStatusEnum.PAYING.getStatus())
.build();
})
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,170 @@
package com.cool.store.service.fees.impl;
import cn.hutool.core.collection.CollStreamUtil;
import com.cool.store.constants.RedisConstant;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.dao.EnterpriseUserDAO;
import com.cool.store.dao.modify.ModifyRecordDAO;
import com.cool.store.dao.fees.WalletAllocationCompanyDAO;
import com.cool.store.dao.fees.WalletAllocationConfigDAO;
import com.cool.store.dto.wallet.CompanyListDTO;
import com.cool.store.entity.fees.WalletAllocationCompanyDO;
import com.cool.store.entity.fees.WalletAllocationConfigDO;
import com.cool.store.enums.BusinessModuleEnum;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.fees.WalletCompanyQueryRequest;
import com.cool.store.request.fees.WalletAllocationCompanyRequest;
import com.cool.store.request.fees.WalletAllocationConfigAddRequest;
import com.cool.store.request.fees.WalletAllocationConfigPageRequest;
import com.cool.store.request.wallet.*;
import com.cool.store.service.dict.impl.DictService;
import com.cool.store.service.fees.WalletAllocationConfigService;
import com.cool.store.service.wallet.WalletApiService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.RedisUtilPool;
import com.cool.store.vo.fees.InvestDivisionRegionVO;
import com.cool.store.vo.fees.WalletAllocationCompanyVO;
import com.cool.store.vo.fees.WalletAllocationConfigVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
import static com.cool.store.service.wallet.impl.WalletServiceImpl.toPageInfo;
/**
* 分账配置服务实现类
*
* @author system
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class WalletAllocationConfigServiceImpl implements WalletAllocationConfigService {
private final WalletAllocationConfigDAO walletAllocationConfigDAO;
private final WalletAllocationCompanyDAO walletAllocationCompanyDAO;
private final ModifyRecordDAO modifyRecordDAO;
private final RedisUtilPool redisUtilPool;
private final DictService dictService;
private final WalletApiService walletApiService;
private final EnterpriseUserDAO enterpriseUserDAO;
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean add(WalletAllocationConfigAddRequest request) {
verify(request.getJoinBrand(), request.getExpenseType(), request.getInvestDivisionId(), request.getId());
String userId = CurrentUserHolder.getUserId();
WalletAllocationConfigDO configDO = BeanUtil.toBean(request, WalletAllocationConfigDO.class);
configDO.setCreateUserId(userId);
walletAllocationConfigDAO.insertSelective(configDO);
// 保存分账公司配置
insertCompanyList(request.getCompanyList(), configDO.getId(), userId);
return true;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean update(WalletAllocationConfigAddRequest request) {
verify(request.getJoinBrand(), request.getExpenseType(), request.getInvestDivisionId(), request.getId());
WalletAllocationConfigDO configDO = BeanUtil.toBean(request, WalletAllocationConfigDO.class);
walletAllocationConfigDAO.updateByPrimaryKeySelective(configDO);
String userId = CurrentUserHolder.getUserId();
walletAllocationCompanyDAO.deleteByConfigId(request.getId());
// 保存分账公司配置
insertCompanyList(request.getCompanyList(), configDO.getId(), userId);
// 新增业务修改记录
modifyRecordDAO.insertRecord(BusinessModuleEnum.WALLET_ALLOCATION_CONFIG, request.getId(), userId);
return true;
}
public void insertCompanyList(List<WalletAllocationCompanyRequest> companyList, Long configId, String userId) {
if (CollectionUtils.isNotEmpty(companyList)) {
List<WalletAllocationCompanyDO> list = BeanUtil.toList(companyList, WalletAllocationCompanyDO.class);
list.forEach(v -> {
v.setConfigId(configId);
v.setCreateUserId(userId);
});
walletAllocationCompanyDAO.insertBatch(list);
}
}
@Override
public PageInfo<WalletAllocationConfigVO> page(WalletAllocationConfigPageRequest request) {
List<Long> configIds = null;
if (Objects.nonNull(request.getPayeeCode())) {
List<WalletAllocationCompanyDO> companyList = walletAllocationCompanyDAO.selectByPayeeCode(request.getPayeeCode());
if (CollectionUtils.isEmpty(companyList)) {
return new PageInfo<>();
}
configIds = CollStreamUtil.toList(companyList, WalletAllocationCompanyDO::getConfigId);
}
PageHelper.startPage(request.getPageNum(), request.getPageSize());
// 查询分账配置
List<WalletAllocationConfigDO> configList = walletAllocationConfigDAO.selectByCondition(
request.getJoinBrand(),
request.getInvestDivisionId(),
request.getExpenseType(),
configIds
);
PageInfo<WalletAllocationConfigDO> page = new PageInfo<>(configList);
PageInfo<WalletAllocationConfigVO> newPage = BeanUtil.toPage(page, WalletAllocationConfigVO.class);
List<Long> resultConfigIds = CollStreamUtil.toList(configList, WalletAllocationConfigDO::getId);
Set<String> userIds = CollStreamUtil.toSet(configList, WalletAllocationConfigDO::getCreateUserId);
Map<Long, List<WalletAllocationCompanyDO>> companyGroup = walletAllocationCompanyDAO.selectGroupByConfigIds(resultConfigIds);
Map<String, String> userNameMap = enterpriseUserDAO.getUserNameMap(new ArrayList<>(userIds));
newPage.getList().forEach(v -> {
v.setInvestDivisionName(redisUtilPool.hashGet(RedisConstant.WALLET_ALLOCATION_CONFIG_INVEST_DIVISION, String.valueOf(v.getInvestDivisionId())));
List<WalletAllocationCompanyDO> companyList = companyGroup.getOrDefault(v.getId(), Collections.emptyList());
v.setCompanyList(BeanUtil.toList(companyList, WalletAllocationCompanyVO.class));
v.setCreateUserName(userNameMap.get(v.getCreateUserId()));
});
dictService.fillDictField(newPage.getList());
return newPage;
}
@Override
public List<InvestDivisionRegionVO> getInvestDivisionRegionList() {
Map<String, String> map = redisUtilPool.hashGetAll(RedisConstant.WALLET_ALLOCATION_CONFIG_INVEST_DIVISION);
return map.entrySet().stream()
.map(v -> new InvestDivisionRegionVO(Long.valueOf(v.getKey()), v.getValue()))
.collect(Collectors.toList());
}
@Override
public PageInfo<WalletAllocationCompanyVO> companyPage(WalletCompanyQueryRequest request) {
FindPageCompanyRequest apiRequest = new FindPageCompanyRequest();
apiRequest.setCompanyName(request.getCompanyName());
apiRequest.setCompanyCode(request.getCompanyCode());
apiRequest.setPage(new WalletBasicPageInfo(request.getPageNum(), request.getPageSize()));
CompanyListDTO companyInfo = walletApiService.getCompanyInfo(apiRequest);
List<WalletAllocationCompanyVO> list = CollStreamUtil.toList(companyInfo.getPageData(), v -> new WalletAllocationCompanyVO(v.getCompanyName(), v.getCompanyCode()));
return toPageInfo(list, WalletAllocationCompanyVO.class, companyInfo.getPage());
}
/**
* 校验同种费用只允许配置分部或者全部,存在另一种时报错
*/
private void verify(Integer joinBrand, String expenseType, Long investDivisionId, Long excludeId) {
if (walletAllocationConfigDAO.existOtherInvestType(joinBrand, expenseType, investDivisionId, excludeId)) {
throw new ServiceException(ErrorCodeEnum.WALLET_INVEST_TYPE_EXISTS);
}
if (walletAllocationConfigDAO.existUniqueKey(joinBrand, investDivisionId, expenseType, excludeId)) {
throw new ServiceException(ErrorCodeEnum.WALLET_UNIQUE_KEY_EXISTS);
}
}
}

View File

@@ -0,0 +1,344 @@
package com.cool.store.service.fees.impl;
import cn.hutool.core.collection.CollStreamUtil;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.CommonConstants;
import com.cool.store.constants.DictConstants;
import com.cool.store.constants.RedisConstant;
import com.cool.store.context.PartnerUserHolder;
import com.cool.store.dao.FranchiseFeeDAO;
import com.cool.store.dao.ShopInfoDAO;
import com.cool.store.dao.ShopStageInfoDAO;
import com.cool.store.dao.dict.SysDictColumnDAO;
import com.cool.store.dao.fees.ShopAllocationInfoDAO;
import com.cool.store.dao.fees.WalletPayInfoDAO;
import com.cool.store.dao.wallet.WalletTradeDAO;
import com.cool.store.dto.wallet.AccountInfoDTO;
import com.cool.store.dto.wallet.BatchTransferDTO;
import com.cool.store.request.wallet.BatchTransferRequest;
import com.cool.store.dto.wallet.TransferDTO;
import com.cool.store.entity.FranchiseFeeDO;
import com.cool.store.entity.ShopInfoDO;
import com.cool.store.entity.ShopStageInfoDO;
import com.cool.store.entity.fees.ShopAllocationInfoDO;
import com.cool.store.entity.fees.WalletPayInfoDO;
import com.cool.store.entity.wallet.WalletTradeDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.fees.AllocationPayStatusEnum;
import com.cool.store.enums.fees.PayTypeEnum;
import com.cool.store.enums.fees.WalletFeeItemEnum;
import com.cool.store.enums.point.ShopSubStageEnum;
import com.cool.store.enums.point.ShopSubStageStatusEnum;
import com.cool.store.enums.wallet.WalletTradeModuleEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.fees.WalletCancelPayRequest;
import com.cool.store.request.fees.WalletPayRequest;
import com.cool.store.request.fees.WalletRepayRequest;
import com.cool.store.request.wallet.OutStoreIdRequest;
import com.cool.store.request.wallet.TransferRequest;
import com.cool.store.request.xgj.ReceiptRequest;
import com.cool.store.service.PushService;
import com.cool.store.service.fees.WalletPayInfoService;
import com.cool.store.service.wallet.WalletApiService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.GenerateNoUtil;
import com.cool.store.utils.RedisUtil;
import com.cool.store.vo.PartnerUserInfoVO;
import com.cool.store.vo.fees.WalletPayInfoVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* <p>
* 钱包加盟缴费服务实现类
* </p>
*
* @author wangff
* @since 2026/1/30
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class WalletPayInfoServiceImpl implements WalletPayInfoService {
private final WalletPayInfoDAO walletPayInfoDAO;
private final FranchiseFeeDAO franchiseFeeDAO;
private final SysDictColumnDAO sysDictColumnDAO;
private final ShopAllocationInfoDAO shopAllocationInfoDAO;
private final ShopInfoDAO shopInfoDAO;
private final WalletApiService walletApiService;
private final SysDictColumnDAO dictColumnDAO;
private final WalletTradeDAO walletTradeDAO;
private final RedisUtil redisUtil;
private final ShopStageInfoDAO shopStageInfoDAO;
private final PushService pushService;
@Override
@Transactional
public Boolean pay(WalletPayRequest request, String oldPayNo) {
log.info("钱包缴费开始,参数:{}", JSONObject.toJSONString(request));
if (StringUtils.isNotBlank(oldPayNo) && CollectionUtils.isNotEmpty(request.getExpenseTypes()) && request.getExpenseTypes().size() > 1) {
// 重新支付不支持批量
throw new ServiceException(ErrorCodeEnum.WALLET_RE_PAY_FAIL);
}
ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(request.getShopId());
if (Objects.isNull(shopInfo)) {
throw new ServiceException(ErrorCodeEnum.SHOP_NOT_EXIST);
}
String lockKey = MessageFormat.format(RedisConstant.WALLET_ALLOCATION_PAY_LOCK_KEY, shopInfo.getId());
Boolean lock = redisUtil.tryLock(lockKey, lockKey, 600, TimeUnit.SECONDS);
if (!Boolean.TRUE.equals(lock)) {
throw new ServiceException(ErrorCodeEnum.THE_USER_IS_PAYING);
}
try {
// 查询所有费用
List<ShopAllocationInfoDO> list = shopAllocationInfoDAO.getByShopId(request.getShopId());
Map<String, BigDecimal> allocationAmountMap = CollStreamUtil.toMap(list, ShopAllocationInfoDO::getExpenseType, ShopAllocationInfoDO::getAmount);
Map<String, ShopAllocationInfoDO> allocationInfoMap = CollStreamUtil.toMap(list, ShopAllocationInfoDO::getExpenseType, v -> v);
// 支付校验
verifyPay(request, shopInfo, allocationAmountMap);
// 批量发起转账
PartnerUserInfoVO user = PartnerUserHolder.getUser();
List<ShopAllocationInfoDO> updateAllocationInfoList = new ArrayList<>();
List<WalletPayInfoDO> walletPayInfoList = new ArrayList<>();
List<WalletPayInfoDO> walletRePayInfoList = new ArrayList<>();
List<WalletTradeDO> walletTradeList = new ArrayList<>();
// 构建批量请求对象
List<BatchTransferRequest.TransDataRequest> transDataList = CollStreamUtil.toList(request.getExpenseTypes(), expenseType -> {
ShopAllocationInfoDO shopAllocationInfoDO = allocationInfoMap.get(expenseType);
BigDecimal payAmount = allocationAmountMap.get(expenseType);
String payNo = StringUtils.isNotBlank(oldPayNo) ? oldPayNo : GenerateNoUtil.generateMillsNoWithRandom();
WalletFeeItemEnum feeItem = WalletFeeItemEnum.getByExpenseType(expenseType);
assert feeItem != null;
return new BatchTransferRequest.TransDataRequest(payNo, feeItem.getFeeItemId(), shopAllocationInfoDO.getPayeeCode(), null, payAmount.toString(), feeItem.getDesc());
});
BatchTransferRequest transRequest = new BatchTransferRequest(shopInfo.getStoreId(), request.getPayPwd(), transDataList);
BatchTransferDTO batchTransferDTO = walletApiService.batchTransfer(transRequest);
if (CollectionUtils.isEmpty(batchTransferDTO.getTransArray())) {
throw new ServiceException(ErrorCodeEnum.WALLET_TRANS_FAIL);
}
for (BatchTransferDTO.TransDataRequest transResult : batchTransferDTO.getTransArray()) {
WalletFeeItemEnum feeItemEnum = WalletFeeItemEnum.getByFeeItemId(transResult.getFeeItemId());
assert feeItemEnum != null;
WalletPayInfoDO walletPayInfoDO = new WalletPayInfoDO(
WalletTradeModuleEnum.FRANCHISE_PAY.getModule(), request.getShopId(), transResult.getReqNo(), user.getUsername(), new BigDecimal(transResult.getAmount()), feeItemEnum.getExpenseType(), user.getPartnerId(), String.valueOf(transResult.getTradeId())
);
// 这里只返回成功或失败
walletPayInfoDO.setPayStatus(batchTransferDTO.getTradeStatus());
if (StringUtils.isNotBlank(oldPayNo)) {
walletRePayInfoList.add(walletPayInfoDO);
} else {
walletPayInfoList.add(walletPayInfoDO);
}
// 分账信息
ShopAllocationInfoDO shopAllocationInfoDO = allocationInfoMap.get(feeItemEnum.getExpenseType());
shopAllocationInfoDO.setStatus(batchTransferDTO.getTradeStatus());
updateAllocationInfoList.add(shopAllocationInfoDO);
// 钱包交易单
WalletTradeDO walletTradeDO = walletPayInfoDO.convertToTradeDO(WalletTradeModuleEnum.FRANCHISE_PAY.getModule());
walletTradeList.add(walletTradeDO);
}
if (CollectionUtils.isNotEmpty(walletPayInfoList)) {
walletPayInfoDAO.insertBatch(walletPayInfoList);
}
if (CollectionUtils.isNotEmpty(walletRePayInfoList)) {
walletPayInfoDAO.updateByPayNo(walletRePayInfoList.get(0));
}
if (CollectionUtils.isNotEmpty(updateAllocationInfoList)) {
shopAllocationInfoDAO.updateBatch(updateAllocationInfoList);
}
if (CollectionUtils.isNotEmpty(walletTradeList)) {
walletTradeDAO.insertBatch(walletTradeList);
}
// 支付成功
if (AllocationPayStatusEnum.PAID.getStatus().equals(batchTransferDTO.getTradeStatus())) {
// 校验并流转流程
verifyAndProcessFlow(shopInfo.getId());
// 推送缴费单数据到新管家
if (CollectionUtils.isNotEmpty(walletPayInfoList)) {
pushReceiptRequest(walletPayInfoList, shopInfo);
}
if (CollectionUtils.isNotEmpty(walletRePayInfoList)) {
pushReceiptRequest(walletRePayInfoList, shopInfo);
}
}
} finally {
redisUtil.unlock(lockKey);
}
return true;
}
/**
* 推送账单到新管家
*/
private void pushReceiptRequest(List<WalletPayInfoDO> payInfoList, ShopInfoDO shopInfoDO) {
if (CollectionUtils.isEmpty(payInfoList)) {
return;
}
FranchiseFeeDO franchiseFeeDO = franchiseFeeDAO.selectByShopId(shopInfoDO.getId());
for (WalletPayInfoDO payInfo : payInfoList) {
ReceiptRequest receiptRequest = new ReceiptRequest(shopInfoDO.getId(), franchiseFeeDO.getId().intValue(), payInfo, Integer.valueOf(shopInfoDO.getFranchiseBrand()));
try {
pushService.pushReceiptToXGJ(receiptRequest);
} catch (Exception e) {
log.error("钱包账单推送新管家失败, walletPayInfoId:{}", payInfo.getId(), e);
}
}
}
/**
* 校验并流转阶段
*/
private void verifyAndProcessFlow(Long shopId) {
ShopStageInfoDO shopStage = shopStageInfoDAO.getByShopIdAndSubStage(shopId, ShopSubStageEnum.SHOP_STAGE_7.getShopSubStage());
if (Objects.nonNull(shopStage) && ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_71.getShopSubStageStatus().equals(shopStage.getShopSubStageStatus())) {
List<ShopAllocationInfoDO> allocationList = shopAllocationInfoDAO.getByShopId(shopId);
boolean allPaid = allocationList.stream().allMatch(v -> AllocationPayStatusEnum.PAID.getStatus().equals(v.getStatus()));
// 已全部支付流程改为对账中
if (allPaid) {
shopStageInfoDAO.updateShopStageInfo(shopId, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_72);
}
}
}
/**
* 支付校验
*/
private void verifyPay(WalletPayRequest request, ShopInfoDO shopInfo, Map<String, BigDecimal> allocationAmountMap) {
// 校验费用类型
for (String expenseType : request.getExpenseTypes()) {
if (!DictConstants.PING_AN_DEFAULT_ALLOCATION_EXPENSE_TYPE_CODES.contains(expenseType)) {
throw new ServiceException(ErrorCodeEnum.NONSUPPORT_EXPENSE_TYPE);
}
}
// 校验付款方式
FranchiseFeeDO franchiseFeeDO = franchiseFeeDAO.selectByShopId(request.getShopId());
if (Objects.isNull(franchiseFeeDO) || !PayTypeEnum.PING_AN.getType().equals(franchiseFeeDO.getPayType())) {
throw new ServiceException(ErrorCodeEnum.PAY_TYPE_UNEQUAL_TO_PING_AN_WALLET);
}
Map<String, String> nameMap = sysDictColumnDAO.getNameMapByCodes(DictConstants.PING_AN_DEFAULT_ALLOCATION_EXPENSE_TYPE_CODES);
// 校验费用类型是否已缴纳
List<WalletPayInfoDO> paidList = walletPayInfoDAO.getPaidByShopId(request.getShopId(), WalletTradeModuleEnum.FRANCHISE_PAY.getModule());
String paidExpenseTypes = paidList.stream()
.flatMap(v -> Arrays.stream(v.getExpenseTypes().split(",")))
.filter(v -> request.getExpenseTypes().contains(v))
.map(nameMap::get)
.collect(Collectors.joining(CommonConstants.COMMA));
if (StringUtils.isNotBlank(paidExpenseTypes)) {
throw new ServiceException(ErrorCodeEnum.EXPENSE_TYPE_HAS_PAID, paidExpenseTypes);
}
// 校验金额是否一致
BigDecimal totalAmount = BigDecimal.valueOf(0);
for (String expenseType : request.getExpenseTypes()) {
BigDecimal amount = allocationAmountMap.get(expenseType);
if (Objects.isNull(amount)) {
throw new ServiceException(ErrorCodeEnum.THERE_IS_NO_PAYMENT_INFORMATION);
}
totalAmount = totalAmount.add(amount);
}
if (totalAmount.compareTo(request.getAmount()) != 0) {
throw new ServiceException(ErrorCodeEnum.EXPENSE_CHANGED);
}
// 校验余额
List<AccountInfoDTO> accountInfo = walletApiService.getAccountInfo(new OutStoreIdRequest(shopInfo.getStoreId()));
AccountInfoDTO accountInfoDTO = accountInfo.stream().filter(v -> CommonConstants.INDEX_ONE.equals(v.getWalletType()) && CommonConstants.INDEX_ZERO.equals(v.getLabelingStatus())).findFirst().orElse(null);
if (Objects.isNull(accountInfoDTO)) {
throw new ServiceException(ErrorCodeEnum.NOT_EXIST_PING_AN_ACCOUNT);
}
if (new BigDecimal(accountInfoDTO.getTotalAmount()).compareTo(totalAmount) < 0) {
throw new ServiceException(ErrorCodeEnum.NOT_ENOUGH_BALANCE);
}
}
@Override
@Transactional
public Boolean rePay(WalletRepayRequest request) {
WalletPayInfoDO payInfoDO = walletPayInfoDAO.getById(request.getPayInfoId());
if (Objects.isNull(payInfoDO)) {
throw new ServiceException(ErrorCodeEnum.THERE_IS_NO_PAYMENT_INFORMATION);
}
WalletPayRequest payRequest = new WalletPayRequest();
payRequest.setShopId(payInfoDO.getShopId());
payRequest.setExpenseTypes(Collections.singletonList(payInfoDO.getExpenseTypes()));
payRequest.setAmount(payInfoDO.getPayAmount());
payRequest.setPayPwd(request.getPayPwd());
return pay(payRequest, payInfoDO.getPayNo());
}
@Override
public Boolean cancelPay(WalletCancelPayRequest request) {
WalletPayInfoDO payInfoDO = walletPayInfoDAO.getById(request.getPayInfoId());
if (Objects.isNull(payInfoDO)) {
throw new ServiceException(ErrorCodeEnum.THERE_IS_NO_PAYMENT_INFORMATION);
}
if (!AllocationPayStatusEnum.FAIL.getStatus().equals(payInfoDO.getPayStatus())) {
throw new ServiceException(ErrorCodeEnum.WALLET_PAY_CANNOT_CANCEL);
}
WalletPayInfoDO updateInfo = new WalletPayInfoDO();
updateInfo.setId(request.getPayInfoId());
updateInfo.setPayStatus(AllocationPayStatusEnum.CANCEL.getStatus());
walletPayInfoDAO.updateByPrimaryKeySelective(updateInfo);
return true;
}
@Override
public List<WalletPayInfoVO> payInfoList(Long shopId, Integer payStatus) {
List<WalletPayInfoDO> list = walletPayInfoDAO.getByShopId(shopId, WalletTradeModuleEnum.FRANCHISE_PAY.getModule(), payStatus);
List<String> expenseTypes = list.stream()
.flatMap(v -> Arrays.stream(v.getExpenseTypes().split(",")))
.distinct()
.collect(Collectors.toList());
Map<String, String> nameMap = dictColumnDAO.getNameMapByCodes(expenseTypes);
List<WalletPayInfoVO> result = BeanUtil.toList(list, WalletPayInfoVO.class);
result.forEach(v -> {
String expenseTypeName = Arrays.stream(v.getExpenseTypes().split(",")).map(nameMap::get).collect(Collectors.joining(CommonConstants.COMMA));
v.setExpenseTypeName(expenseTypeName);
});
return result;
}
@Override
public void rePushReceipt(Long walletPayInfoId) {
WalletPayInfoDO payInfoDO = walletPayInfoDAO.getById(walletPayInfoId);
ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(payInfoDO.getShopId());
pushReceiptRequest(Collections.singletonList(payInfoDO), shopInfo);
}
/**
* 调用营帐通转账接口进行
* @param expenseType 费用类型
* @param amount 转账金额
* @param payPwd 支付密码
* @param storeId 门店id
* @param payNo 付款单号
* @param companyCode 公司code
* @return 转账结果DTO
*/
public TransferDTO pay(String expenseType, BigDecimal amount, String payPwd, String storeId, String payNo, String companyCode) {
WalletFeeItemEnum feeItem = WalletFeeItemEnum.getByExpenseType(expenseType);
if (Objects.isNull(feeItem)) {
throw new ServiceException(ErrorCodeEnum.NONSUPPORT_EXPENSE_TYPE);
}
TransferRequest request = new TransferRequest();
request.setOutStoreId(storeId);
request.setPayPwd(payPwd);
request.setReqNo(payNo);
request.setFeeItemId(feeItem.getFeeItemId());
request.setCompanyCode(companyCode);
request.setAmount(amount.toString());
request.setRemark(feeItem.getDesc());
return walletApiService.transfer(request);
}
}

View File

@@ -289,7 +289,7 @@ public class DataHandleServiceImpl implements DataHandleService {
ShopStageEnum shopStageEnum = shopSubStageEnum.getShopStageEnum();
shopStageInfo.setShopStage(shopStageEnum.getShopStage());
shopStageInfo.setShopSubStage(shopSubStageEnum.getShopSubStage());
ShopSubStageStatusEnum initStatus = shopSubStageEnum.getInitStatus();
ShopSubStageStatusEnum initStatus = shopSubStageEnum.getInitStatus(1);
if (ShopSubStageEnum.SHOP_STAGE_15.equals(shopSubStageEnum)&&flag){
initStatus = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_150;
}

View File

@@ -312,12 +312,46 @@ public class DeskServiceImpl implements DeskService {
if (userRoleIds.contains(UserRoleEnum.FINANCE.getCode())) {
subStageStatusList.add(SHOP_SUB_STAGE_STATUS_83_5.getShopSubStageStatus());
}
if (CollectionUtils.isEmpty(subStageStatusList)) {
return new PageInfo<>();
}
PageInfo<PreparationCommonPendingVO> pageInfo = commonPendingVOPageInfo(deskRequest, user, ShopSubStageEnum.SHOP_STAGE_8,
subStageStatusList, Boolean.TRUE);
return pageInfo;
}
@Override
public PageInfo<PreparationCommonPendingVO> standardStorePendingList(DeskRequest deskRequest, LoginUserInfo user) {
List<Integer> subStageStatusList = new ArrayList<>();
List<Long> userRoleIds = enterpriseUserRoleMapper.getUserRoleIds(user.getUserId());
//两个角色都包含
if (userRoleIds.contains(UserRoleEnum.HEAD_OF_DESIGN.getCode())&&userRoleIds.contains(UserRoleEnum.FINANCE.getCode())){
subStageStatusList.add(SHOP_SUB_STAGE_STATUS_281.getShopSubStageStatus());
subStageStatusList.add(SHOP_SUB_STAGE_STATUS_282.getShopSubStageStatus());
}
//加盟内勤 待确认
if (userRoleIds.contains(UserRoleEnum.HEAD_OF_DESIGN.getCode())){
subStageStatusList.add(SHOP_SUB_STAGE_STATUS_281.getShopSubStageStatus());
}
//如果是财务 待财务确认
if (userRoleIds.contains(UserRoleEnum.FINANCE.getCode())){
subStageStatusList.add(SHOP_SUB_STAGE_STATUS_282.getShopSubStageStatus());
}
if (userRoleIds.contains(UserRoleEnum.INVESTMENT_MANGER.getCode())){
subStageStatusList.add(SHOP_SUB_STAGE_STATUS_281_5.getShopSubStageStatus());
return commonPendingVOPageInfo(deskRequest, user,
ShopSubStageEnum.SHOP_STAGE_28, subStageStatusList, Boolean.FALSE);
}
if (CollectionUtils.isEmpty(subStageStatusList)){
return new PageInfo<>();
}
Boolean isAdmin = sysRoleService.checkIsAdmin(user.getUserId());
PageInfo<PreparationCommonPendingVO> pageInfo = commonPendingVOPageInfo(deskRequest, isAdmin ? null : user,
ShopSubStageEnum.SHOP_STAGE_28, subStageStatusList, isAdmin ? Boolean.FALSE : Boolean.TRUE);
return pageInfo;
}
@Override
public PageInfo<PreparationCommonPendingVO> invoiceReturnPendingList(DeskRequest deskRequest, LoginUserInfo user) {
return commonPendingVOPageInfo(deskRequest, null, ShopSubStageEnum.SHOP_STAGE_8_5,

View File

@@ -14,12 +14,17 @@ import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.*;
import com.cool.store.request.AllPointPageRequest;
import com.cool.store.request.FranchiseReportRequest;
import com.cool.store.request.order.PCStoreOrderQueryRequest;
import com.cool.store.request.visit.VisitRecordQueryRequest;
import com.cool.store.request.PointPageRequest;
import com.cool.store.request.visit.VisitRecordQueryRequest;
import com.cool.store.response.BranchShopResponse;
import com.cool.store.response.FranchiseReportResponse;
import com.cool.store.response.ShopReportResponse;
import com.cool.store.service.*;
import com.cool.store.service.order.MiniStoreOrderService;
import com.cool.store.service.order.impl.MiniStoreOrderServiceImpl;
import com.cool.store.service.visit.VisitRecordService;
import com.cool.store.service.visit.VisitRecordService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.JSONUtils;
@@ -28,6 +33,8 @@ import com.cool.store.utils.easyExcel.EasyExcelUtil;
import com.cool.store.utils.poi.DateUtils;
import com.cool.store.utils.poi.StringUtils;
import com.cool.store.vo.order.PCStoreOrderListVO;
import com.cool.store.vo.visit.VisitRecordListVO;
import com.cool.store.vo.point.PointExportVO;
import com.cool.store.vo.point.PointPageVO;
import com.cool.store.vo.visit.VisitRecordListVO;
@@ -115,6 +122,8 @@ public class ExportRealizeServiceImpl implements ExportRealizeService {
@Resource
private VisitRecordService visitRecordService;
@Resource
MiniStoreOrderService miniStoreOrderService;
@Resource
private PointService pointService;
@Resource
private PointFinancialDataDAO pointFinancialDataDAO;
@@ -734,6 +743,29 @@ public class ExportRealizeServiceImpl implements ExportRealizeService {
}
}
@Override
@Async("generalThreadPool")
public void exportOrderRecord(PCStoreOrderQueryRequest request, ImportTaskDO importTaskDO) {
String url = "";
try {
url = easyExcelUtil.exportExcelInBatches(PCStoreOrderListVO.class,
(pageNum, pageSize) -> {
request.setPageNum(pageNum);
request.setPageSize(pageSize);
return miniStoreOrderService.list(request).getList();
},
FileTypeEnum.ORDER_RECORD_EXPORT.getDesc(),
FileTypeEnum.ORDER_RECORD_EXPORT.getDesc());
importTaskDO.setStatus(ImportStatusEnum.success.getCode());
} catch (Exception e) {
log.error("拜访记录导出失败", e);
importTaskDO.setStatus(ImportStatusEnum.fail.getCode());
} finally {
importTaskDO.setFileUrl(url);
importTaskMapper.update(eid, importTaskDO);
}
}
@Override
@Async("generalThreadPool")
public void exportVisitRecord(VisitRecordQueryRequest request, ImportTaskDO importTaskDO) {

View File

@@ -8,6 +8,10 @@ import com.cool.store.dao.HyOpenAreaInfoDAO;
import com.cool.store.dao.LineInfoDAO;
import com.cool.store.dao.PreFryQualificationApplyDAO;
import com.cool.store.dao.ShopInfoDAO;
import com.cool.store.dao.order.StoreOrderDAO;
import com.cool.store.dao.visit.VisitRecordDAO;
import com.cool.store.dto.Preparation.PreparationDTO;
import com.cool.store.dto.Preparation.ScheduleDTO;
import com.cool.store.dao.visit.VisitRecordDAO;
import com.cool.store.dto.pre.fry.ApplyManagementDTO;
import com.cool.store.dto.pre.fry.ApplyManagementQueryDTO;
@@ -19,6 +23,8 @@ import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.ImportTaskMapper;
import com.cool.store.mapper.PointInfoMapper;
import com.cool.store.request.*;
import com.cool.store.request.order.PCStoreOrderQueryRequest;
import com.cool.store.request.visit.VisitRecordQueryRequest;
import com.cool.store.request.visit.VisitRecordQueryRequest;
import com.cool.store.response.BranchShopResponse;
import com.cool.store.response.FranchiseReportResponse;
@@ -33,6 +39,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -212,6 +219,33 @@ public class ExportServiceImpl implements ExportService {
return (long) list.size();
}
@Resource
StoreOrderDAO storeOrderDAO;
@Override
public Long exportStandardStoreOrderRecord(PCStoreOrderQueryRequest request, LoginUserInfo user) {
Long count = storeOrderDAO.count(request);
if (count.intValue() > CommonConstants.MAX_EXPORT_SIZE_PRO) {
throw new ServiceException(ErrorCodeEnum.EXPORT_LIMIT_100000);
}
if (count==0){
log.error("导出数据为空");
return 0L;
}
ImportTaskDO importTaskDO = new ImportTaskDO();
importTaskDO.setStatus(ImportStatusEnum.Ongoing.getCode());
importTaskDO.setFileName(FileTypeEnum.ORDER_RECORD_EXPORT.getDesc() + DateUtils.parseDateToStr(DateUtils.SPECIAL_DATE_START_1, new Date()));
importTaskDO.setIsImport(Boolean.FALSE);
importTaskDO.setFileType(FileTypeEnum.ORDER_RECORD_EXPORT.getFileType());
importTaskDO.setCreateUserId(user.getUserId());
importTaskDO.setCreateTime(new Date().getTime());
importTaskDO.setCreateName(user.getName());
importTaskMapper.insert(eid, importTaskDO);
exportRealizeService.exportOrderRecord(request, importTaskDO);
return count;
}
@Override
public Long exportVisitRecord(VisitRecordQueryRequest request, LoginUserInfo user) {
Long count = visitRecordDAO.getVisitRecordCount(request);

View File

@@ -1,19 +1,24 @@
package com.cool.store.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.RedisConstant;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.FranchiseFeeDAO;
import com.cool.store.dao.PointDetailInfoDAO;
import com.cool.store.dao.PointInfoDAO;
import com.cool.store.dao.ShopStageInfoDAO;
import com.cool.store.entity.*;
import com.cool.store.entity.fees.ShopAllocationInfoDO;
import com.cool.store.enums.*;
import com.cool.store.enums.point.PayBusinessTypeEnum;
import com.cool.store.enums.fees.PayTypeEnum;
import com.cool.store.enums.point.ShopSubStageEnum;
import com.cool.store.enums.point.ShopSubStageStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.*;
import com.cool.store.request.AuditFranchiseFeeRequest;
import com.cool.store.request.FranchiseFeeRequest;
import com.cool.store.request.FranchisePayTypeUpdateRequest;
import com.cool.store.request.fees.ShopAllocationInfoRequest;
import com.cool.store.request.xgj.FranchiseFeeCallBackRequest;
import com.cool.store.request.xgj.PushFranchiseFeeRequest;
import com.cool.store.response.FranchiseFeeResponse;
@@ -21,15 +26,26 @@ import com.cool.store.response.bigdata.ApiResponse;
import com.cool.store.service.FranchiseFeeService;
import com.cool.store.service.PushService;
import com.cool.store.service.UserAuthMappingService;
import com.cool.store.service.dict.impl.DictService;
import com.cool.store.service.fees.PayeeBankConfigService;
import com.cool.store.service.fees.ShopAllocationInfoService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.CommonUtil;
import com.cool.store.utils.RedisUtil;
import com.cool.store.utils.poi.constant.Constants;
import com.cool.store.vo.fees.PayeeBankConfigSimpleVO;
import com.cool.store.vo.fees.PayeeBankConfigVO;
import com.cool.store.vo.fees.ShopAllocationInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static com.cool.store.enums.point.ShopSubStageStatusEnum.*;
@@ -66,6 +82,16 @@ public class FranchiseFeeServiceImpl implements FranchiseFeeService {
UserAuthMappingService userAuthMappingService;
@Resource
PushService pushService;
@Resource
private FranchiseFeeDAO franchiseFeeDAO;
@Resource
private PayeeBankConfigService payeeBankConfigService;
@Resource
private ShopAllocationInfoService shopAllocationInfoService;
@Resource
private DictService dictService;
@Resource
private RedisUtil redisUtil;
@Override
@Transactional(rollbackFor = Exception.class)
@@ -75,6 +101,7 @@ public class FranchiseFeeServiceImpl implements FranchiseFeeService {
if (!shopStageInfo.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_70.getShopSubStageStatus())){
throw new ServiceException(ErrorCodeEnum.NOT_ALLOW_OPERATE);
}
verifyAllocationTotalFee(request);
ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(request.getShopId());
// 三明治前端没有改这块代码,还是会传这三个字段,因此后端这三个字段置空
if (Integer.valueOf(shopInfoDO.getFranchiseBrand()).equals(FranchiseBrandEnum.ZXSMZ.getCode())) {
@@ -96,6 +123,9 @@ public class FranchiseFeeServiceImpl implements FranchiseFeeService {
franchiseFeeDO.setCreateTime(new Date());
franchiseFeeMapper.insertSelective(franchiseFeeDO);
}
// 新增钱包分账信息
shopAllocationInfoService.insertBatch(request.getShopId(), request.getShopAllocationInfoList());
LineInfoDO lineInfoDO = lineInfoMapper.getByLineId(shopInfoDO.getLineId());
commonService.sendSms(lineInfoDO.getMobile(), SMSMsgEnum.PAY_FRANCHISE_FEES);
//推送加盟费信息到新管家
@@ -105,6 +135,22 @@ public class FranchiseFeeServiceImpl implements FranchiseFeeService {
return true;
}
/**
* 校验合计缴费金额和分账总金额是否相同
*/
private void verifyAllocationTotalFee(FranchiseFeeRequest request) {
if (CollectionUtils.isNotEmpty(request.getShopAllocationInfoList())) {
BigDecimal totalFee = CommonUtil.addAll(request.getYearFranchiseFee(), request.getLoanMargin(), request.getFirstYearFee(), request.getFirstYearManageFee(), request.getPerformanceBond());
BigDecimal allocationTotalFee = request.getShopAllocationInfoList().stream()
.map(ShopAllocationInfoRequest::getAmount)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
if (totalFee.compareTo(allocationTotalFee) != 0) {
throw new ServiceException(ErrorCodeEnum.TOTAL_FEES_NEED_EQUAL);
}
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean update(FranchiseFeeRequest request) {
@@ -114,18 +160,32 @@ public class FranchiseFeeServiceImpl implements FranchiseFeeService {
// }
FranchiseFeeDO franchiseFeeDO = request.toFranchiseFeeDO();
FranchiseFeeDO franchiseFeeDO1 = franchiseFeeMapper.selectByShopId(request.getShopId());
verifyAllocationTotalFee(request);
if (Objects.nonNull(franchiseFeeDO1)) {
franchiseFeeDO.setId(franchiseFeeDO1.getId());
franchiseFeeMapper.updateByPrimaryKeySelective(franchiseFeeDO);
//推送数据
ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(request.getShopId());
LineInfoDO lineInfoDO = lineInfoMapper.getByLineId(shopInfoDO.getLineId());
//推送加盟费信息到新管家
franchiseFeeDO.setCreateTime(franchiseFeeDO1.getCreateTime());
PushFranchiseFeeRequest feeRequest = new PushFranchiseFeeRequest(shopInfoDO.getId(), lineInfoDO.getUsername(), franchiseFeeDO);
feeRequest.setJoinBrand(Integer.valueOf(shopInfoDO.getFranchiseBrand()));
pushService.pushFranchiseFeeToXGJ(feeRequest);
return true;
// 加锁,防止用户支付过程中发生编辑
String lockKey = MessageFormat.format(RedisConstant.WALLET_ALLOCATION_PAY_LOCK_KEY, franchiseFeeDO1.getShopId());
Boolean lock = redisUtil.tryLock(lockKey, lockKey, 600, TimeUnit.SECONDS);
if (!Boolean.TRUE.equals(lock)) {
throw new ServiceException(ErrorCodeEnum.THE_USER_IS_PAYING_UNABLE_UPDATE);
}
try {
franchiseFeeDO.setId(franchiseFeeDO1.getId());
franchiseFeeMapper.updateByPrimaryKeySelective(franchiseFeeDO);
//推送数据
ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(request.getShopId());
LineInfoDO lineInfoDO = lineInfoMapper.getByLineId(shopInfoDO.getLineId());
// 更新钱包分账信息
shopAllocationInfoService.updateBatch(request.getShopId(), request.getShopAllocationInfoList());
//推送加盟费信息到新管家
franchiseFeeDO.setCreateTime(franchiseFeeDO1.getCreateTime());
PushFranchiseFeeRequest feeRequest = new PushFranchiseFeeRequest(shopInfoDO.getId(), lineInfoDO.getUsername(), franchiseFeeDO);
feeRequest.setJoinBrand(Integer.valueOf(shopInfoDO.getFranchiseBrand()));
pushService.pushFranchiseFeeToXGJ(feeRequest);
return true;
} finally {
redisUtil.unlock(lockKey);
}
}
return false;
}
@@ -133,8 +193,16 @@ public class FranchiseFeeServiceImpl implements FranchiseFeeService {
@Override
public FranchiseFeeResponse getDetail(Long shopId) {
FranchiseFeeDO result = franchiseFeeMapper.selectByShopId(shopId);
List<ShopAllocationInfoDO> allocationInfoList = shopAllocationInfoService.getOrDefault(shopId);
List<ShopAllocationInfoVO> allocationVOList = BeanUtil.toList(allocationInfoList, ShopAllocationInfoVO.class);
PayeeBankConfigVO bankConfig = payeeBankConfigService.getByShopId(shopId, PayTypeEnum.OFFLINE.getType());
PayeeBankConfigSimpleVO bankConfigVO = BeanUtil.toBean(bankConfig, PayeeBankConfigSimpleVO.class);
dictService.fillDictField(allocationVOList);
if (Objects.isNull(result)){
return new FranchiseFeeResponse();
FranchiseFeeResponse resp = new FranchiseFeeResponse();
resp.setShopAllocationInfoList(allocationVOList);
resp.setBankConfig(bankConfigVO);
return resp;
}
FranchiseFeeResponse resp = FranchiseFeeResponse.from(result);
ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(shopId);
@@ -144,6 +212,9 @@ public class FranchiseFeeServiceImpl implements FranchiseFeeService {
resp.setPointArea(pointInfoDO.getPointArea());
resp.setMonthRent(pointDetailInfoDO.getMonthRent());
}
resp.setBankConfig(bankConfigVO);
resp.setShopAllocationInfoList(allocationVOList);
resp.setStoreId(shopInfoDO.getStoreId());
return resp;
}
@@ -265,4 +336,13 @@ public class FranchiseFeeServiceImpl implements FranchiseFeeService {
return ApiResponse.success(Boolean.TRUE);
}
@Override
public Boolean updatePayType(FranchisePayTypeUpdateRequest request) {
FranchiseFeeDO franchiseFeeDO = franchiseFeeMapper.selectByShopId(request.getShopId());
if (Objects.nonNull(franchiseFeeDO.getPayType())) {
throw new ServiceException(ErrorCodeEnum.FRANCHISE_FEE_PAY_TYPE_ERROR);
}
return franchiseFeeDAO.updatePayType(request.getShopId(), request.getPayType());
}
}

View File

@@ -92,6 +92,7 @@ public class JoinIntentionServiceImpl extends LineFlowService implements JoinInt
lineInfoParam.setFranchiseBrand(String.valueOf(FranchiseBrandEnum.ZXJP.getCode()));
lineInfoParam.setLineStatus(1);
}
lineInfoParam.setUseStandardStore(request.getUseStandardStore());
lineInfoDAO.insertOrUpdate(lineInfoParam);
QualificationsInfoDO qualificationsInfoDO = request.toQualificationsInfoDO();
qualificationsInfoDAO.insertOrUpdate(qualificationsInfoDO);

View File

@@ -1,13 +1,16 @@
package com.cool.store.service.impl;
import com.cool.store.constants.CommonConstants;
import com.cool.store.dao.PosAndOrderInfoDAO;
import com.cool.store.dao.ShopAccountDAO;
import com.cool.store.dao.ShopInfoDAO;
import com.cool.store.dao.ShopStageInfoDAO;
import com.cool.store.dao.fees.WalletPayInfoDAO;
import com.cool.store.dto.BatchStatusRefreshDTO;
import com.cool.store.dto.StatusRefreshDTO;
import com.cool.store.entity.ShopAccountDO;
import com.cool.store.entity.ShopInfoDO;
import com.cool.store.entity.fees.WalletPayInfoDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.OpenStatusEnum;
import com.cool.store.enums.PosAndOrderEnum;
@@ -58,6 +61,8 @@ public class OpenApiServiceImpl implements OpenApiService {
LinePayService linePayService;
@Resource
FranchiseFeeService franchiseFeeService;
@Resource
WalletPayInfoDAO walletPayInfoDAO;
@Override
@Transactional(rollbackFor = Exception.class)
@@ -99,7 +104,12 @@ public class OpenApiServiceImpl implements OpenApiService {
@Override
public ApiResponse<Boolean> changeReceiptStatus(ReceiptCallBackRequest request) {
return linePayService.ReceiptCallBack(request);
if (Objects.nonNull(request.getPayWay()) && CommonConstants.INDEX_TWO.equals(request.getPayWay())) {
walletPayInfoDAO.updateClaimStatusByPayNo(request.getReceiptId(), request.getClaimStatus());
return ApiResponse.success(Boolean.TRUE);
} else {
return linePayService.ReceiptCallBack(request);
}
}
@Override

View File

@@ -1295,28 +1295,10 @@ public class PointServiceImpl implements PointService {
}
updateShop.setShopManagerUserId(shopManagerUserId);
shopInfoDAO.updateShopInfo(updateShop);
//如果是通过 将缴费状态从未开始改为已开始 已开始的不需要处理
ShopStageInfoDO payStage = shopStageInfoDAO.getShopSubStageInfo(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_7);
if (ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_00.getShopSubStageStatus().equals(payStage.getShopSubStageStatus())) {
shopStageInfoDAO.updateShopStageInfo(request.getShopId(),ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_70);
Set<String> publishFranchiseFeeUsers = new HashSet<>();
List<EnterpriseUserDO> joinUser = userAuthMappingService.getAllUserByRoleEnumAndRegionId(UserRoleEnum.JOIN_OFFICE, lineInfo.getRegionId());
if (Objects.nonNull(joinUser)) {
Set<String> joinUserIds = joinUser.stream().map(EnterpriseUserDO::getUserId).collect(Collectors.toSet());
publishFranchiseFeeUsers.addAll(joinUserIds);
}
List<EnterpriseUserDO> regionUser = userAuthMappingService.getAllUserByRoleEnumAndRegionId(UserRoleEnum.REGION_OFFICE, lineInfo.getRegionId());
if (Objects.nonNull(regionUser)) {
Set<String> regionUserIds = regionUser.stream().map(EnterpriseUserDO::getUserId).collect(Collectors.toSet());
publishFranchiseFeeUsers.addAll(regionUserIds);
}
HashMap<String, String> map = new HashMap<>();
map.put("partnerUsername", lineInfo.getUsername());
map.put("partnerMobile", lineInfo.getMobile());
//发送工作通知
commonService.sendQWMessage(new ArrayList<>(publishFranchiseFeeUsers),
MessageEnum.MESSAGE_23,
map);
//如果是通过 将钱包阶段状态从未开始改为已开始 已开始的不需要处理
ShopStageInfoDO walletStage = shopStageInfoDAO.getShopSubStageInfo(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_6);
if (ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_00.getShopSubStageStatus().equals(walletStage.getShopSubStageStatus())) {
shopStageInfoDAO.updateShopStageInfo(request.getShopId(),ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_60);
}
}
shopStageInfoDAO.updateShopStageAndAuditInfo(shopId, subStageStatus, auditId);

View File

@@ -148,13 +148,14 @@ public class ShopServiceImpl implements ShopService {
shopInfo.setSupervisorUserId(lineInfo.getInvestmentManager());
shopInfo.setShopName("店铺" + NumberConverter.convertArabicToChinese(i + 1));
shopInfo.setCreateTime(new Date());
shopInfo.setUseStandardStore(lineInfo.getUseStandardStore());
shopInfo.setInvestmentManager(lineInfo.getInvestmentManager());
shopInfo.setInvestRegionId(lineInfo.getInvestRegionId());
addShopList.add(shopInfo);
}
shopInfoDAO.batchAddShop(addShopList);
List<Long> shopIds = addShopList.stream().map(ShopInfoDO::getId).collect(Collectors.toList());
Integer result = shopStageInfoDAO.initShopStageInfo(lineInfo.getId(), addShopList, true);
Integer result = shopStageInfoDAO.initShopStageInfo(lineInfo, addShopList, true);
//初始化平台账号
HyPartnerUserInfoDO hyPartnerUserInfoDO = hyPartnerUserInfoDAO.selectByPartnerId(lineInfo.getPartnerId());
shopAccountDAO.initShopAccount(hyPartnerUserInfoDO, shopIds);
@@ -233,9 +234,11 @@ public class ShopServiceImpl implements ShopService {
// //进入选址不允许删除操作
// throw new ServiceException(ErrorCodeEnum.NOT_ALLOW_OPERATE);
// }
ShopStageInfoDO shopSubStageInfo = shopStageInfoDAO.getShopSubStageInfo(shopInfo.getId(), ShopSubStageEnum.SHOP_STAGE_7);
if (ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_73.getShopSubStageStatus().equals(shopSubStageInfo.getShopSubStageStatus())) {
throw new ServiceException(ErrorCodeEnum.IS_EXIST_CLAIM);
if (shopInfo.getUseStandardStore()==0){
ShopStageInfoDO shopSubStageInfo = shopStageInfoDAO.getShopSubStageInfo(shopInfo.getId(), ShopSubStageEnum.SHOP_STAGE_7);
if (ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_73.getShopSubStageStatus().equals(shopSubStageInfo.getShopSubStageStatus())) {
throw new ServiceException(ErrorCodeEnum.IS_EXIST_CLAIM);
}
}
List<LinePayDO> franchiseFeePayInfoByShopId = linePayDAO.getFranchiseFeePayInfoByShopId(request.getShopId());
if (ListUtils.emptyIfNull(franchiseFeePayInfoByShopId)
@@ -288,11 +291,12 @@ public class ShopServiceImpl implements ShopService {
addShop.setSupervisorUserId(lineInfo.getInvestmentManager());
addShop.setInvestmentManager(lineInfo.getInvestmentManager());
addShop.setDevelopmentManager(lineInfo.getInvestmentManager());
addShop.setUseStandardStore(lineInfo.getUseStandardStore());
addShopList.add(addShop);
}
shopInfoDAO.batchAddShop(addShopList);
List<Long> shopIds = addShopList.stream().map(ShopInfoDO::getId).collect(Collectors.toList());
shopStageInfoDAO.initShopStageInfo(lineInfo.getId(), addShopList, true);
shopStageInfoDAO.initShopStageInfo(lineInfo, addShopList, true);
return 1L;
}
@@ -349,8 +353,10 @@ public class ShopServiceImpl implements ShopService {
}
shopInfoDO.setCreateUserId(userId);
Long shopId = shopInfoDAO.addShopInfo(shopInfoDO);
//只赋值 不更新
lineInfo.setUseStandardStore(request.getUseStandardStore());
if (lineInfo.getWorkflowSubStageStatus().equals(WorkflowSubStageStatusEnum.SIGN_INTENT_AGREEMENT_125.getCode())) {
shopStageInfoDAO.initShopStageInfo(request.getLineId(), Collections.singletonList(shopInfoDO), true);
shopStageInfoDAO.initShopStageInfo(lineInfo, Collections.singletonList(shopInfoDO), true);
HashMap<String, String> map = new HashMap<>();
map.put("partnerUsername", lineInfo.getUsername());
map.put("partnerMobile", lineInfo.getMobile());
@@ -372,7 +378,7 @@ public class ShopServiceImpl implements ShopService {
MessageEnum.MESSAGE_21,
map);
} else {
shopStageInfoDAO.initShopStageInfo(request.getLineId(), Collections.singletonList(shopInfoDO), false);
shopStageInfoDAO.initShopStageInfo(lineInfo, Collections.singletonList(shopInfoDO), false);
}
//初始化平台账号
HyPartnerUserInfoDO hyPartnerUserInfoDO = hyPartnerUserInfoDAO.selectByPartnerId(lineInfo.getPartnerId());
@@ -397,6 +403,7 @@ public class ShopServiceImpl implements ShopService {
if (shopInfo.getManagerRegionId()!=null) {
response.setManagerRegionName(regionMap.getOrDefault(shopInfo.getManagerRegionId(),new RegionDO()).getName());
}
response.setUseStandardStore(shopInfo.getUseStandardStore());
response.setUsername(lineInfo.getUsername());
response.setMobile(lineInfo.getMobile());
response.setShopId(shopId);
@@ -440,15 +447,18 @@ public class ShopServiceImpl implements ShopService {
if(StringUtils.isNotEmpty(request.getShopCode())&&this.checkShopCodeRepeat(request.getShopCode(), request.getShopId())){
throw new ServiceException(ErrorCodeEnum.SHOP_CODE_EXIST);
}
//新增校验 缴费阶段之后 不能修改加盟模式
ShopStageInfoDO shopSubStageInfo = shopStageInfoDAO.getShopSubStageInfo(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_7);
//缴费阶段之后 加盟模式不能切换为直营店 直营店也不能切换为其他店
ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(request.getShopId());
String oldShopCode = shopInfo.getShopCode();
if (shopSubStageInfo.getShopSubStageStatus()>ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_70.getShopSubStageStatus()){
if (request.getJoinMode()!=shopInfo.getJoinMode()&&
(request.getJoinMode()==JoinModeEnum.FLAGSHIP_STORE.getCode()||shopInfo.getJoinMode()==JoinModeEnum.FLAGSHIP_STORE.getCode())){
throw new ServiceException(ErrorCodeEnum.NOT_FLAGSHIP_STORE_NOT_EXIST);
//0-不是使用标准店型
if (shopInfo.getUseStandardStore()==0){
//新增校验 缴费阶段之后 不能修改加盟模式
ShopStageInfoDO shopSubStageInfo = shopStageInfoDAO.getShopSubStageInfo(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_7);
//缴费阶段之后 加盟模式不能切换为直营店 直营店也不能切换为其他店
String oldShopCode = shopInfo.getShopCode();
if (shopSubStageInfo.getShopSubStageStatus()>ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_70.getShopSubStageStatus()){
if (request.getJoinMode()!=shopInfo.getJoinMode()&&
(request.getJoinMode()==JoinModeEnum.FLAGSHIP_STORE.getCode()||shopInfo.getJoinMode()==JoinModeEnum.FLAGSHIP_STORE.getCode())){
throw new ServiceException(ErrorCodeEnum.NOT_FLAGSHIP_STORE_NOT_EXIST);
}
}
}
shopInfo.setUpdateUserId(userId);
@@ -542,7 +552,7 @@ public class ShopServiceImpl implements ShopService {
throw new ServiceException(ErrorCodeEnum.PARAMS_VALIDATE_ERROR);
}
Integer completionCount = shopStageInfoDAO.getCompletionCount(shopId);
if (completionCount.equals(ShopSubStageEnum.getTotalStageIsLocationAndPreparation())) {
if (completionCount.equals(ShopSubStageEnum.getTotalStageIsLocationAndPreparation(shopInfo.getUseStandardStore()))) {
shopInfo.setShopStatus(ShopStatusEnum.DONE.getCode());
} else {
shopInfo.setShopStatus(ShopStatusEnum.ING.getCode());
@@ -608,6 +618,7 @@ public class ShopServiceImpl implements ShopService {
response.setUsername(dto.getUsername());
response.setMobile(dto.getMobile());
response.setStoreId(dto.getStoreId());
response.setUseStandardStore(dto.getUseStandardStore());
response.setShopName(dto.getShopName());
response.setShopCode(dto.getShopCode());
response.setRegionName(regionNameMap.getOrDefault(dto.getRegionId(), ""));
@@ -864,6 +875,10 @@ public class ShopServiceImpl implements ShopService {
case SHOP_SUB_STAGE_STATUS_222:
case SHOP_SUB_STAGE_STATUS_250:
case SHOP_SUB_STAGE_STATUS_254:
case SHOP_SUB_STAGE_STATUS_60:
case SHOP_SUB_STAGE_STATUS_280:
case SHOP_SUB_STAGE_STATUS_283:
case SHOP_SUB_STAGE_STATUS_284:
return Collections.singletonList(new UserDTO(lineInfo.getUsername(), lineInfo.getMobile()));
case SHOP_SUB_STAGE_STATUS_11:
@@ -894,6 +909,7 @@ public class ShopServiceImpl implements ShopService {
return getUsersByRolesAndRegion(Collections.singletonList(FINANCE), shopInfo.getRegionId());
case SHOP_SUB_STAGE_STATUS_85_1:
case SHOP_SUB_STAGE_STATUS_282:
return getUsersByRole(FINANCE);
case SHOP_SUB_STAGE_STATUS_861:
@@ -967,6 +983,8 @@ public class ShopServiceImpl implements ShopService {
return getUsersByRoleAndRegion(OPERATION_GENERAL_CONSULTANT, shopInfo.getRegionId());
case SHOP_SUB_STAGE_STATUS_172:
return getUsersByRoleAndRegion(ORDER_GROUP, shopInfo.getRegionId());
case SHOP_SUB_STAGE_STATUS_281:
return getUsersByRolesAndRegion(Arrays.asList(JOIN_OFFICE), shopInfo.getInvestRegionId());
default:
return Collections.emptyList();
}

View File

@@ -7,6 +7,7 @@ import com.cool.store.constants.RedisConstant;
import com.cool.store.constants.DictConstants;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.*;
import com.cool.store.dao.fees.WalletPayInfoDAO;
import com.cool.store.dto.ContractInformationDTO;
import com.cool.store.dao.decoration.DecorationTeamConfigDAO;
import com.cool.store.dao.decoration.ShopDecorationAssignDAO;
@@ -18,11 +19,15 @@ import com.cool.store.entity.*;
import com.cool.store.entity.decoration.DecorationTeamConfigDO;
import com.cool.store.entity.decoration.ShopDecorationAssignDO;
import com.cool.store.entity.decoration.TeamAreaMappingDO;
import com.cool.store.entity.fees.WalletPayInfoDO;
import com.cool.store.enums.*;
import com.cool.store.enums.Decoration.DecorationDescStatus;
import com.cool.store.enums.fees.AllocationPayStatusEnum;
import com.cool.store.enums.fees.PayTypeEnum;
import com.cool.store.enums.Decoration.DecorationUseSystemEnum;
import com.cool.store.enums.point.ShopSubStageEnum;
import com.cool.store.enums.point.ShopSubStageStatusEnum;
import com.cool.store.enums.wallet.WalletTradeModuleEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.*;
import com.cool.store.mq.producer.SimpleMessageService;
@@ -42,6 +47,7 @@ import com.google.protobuf.StringValue;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.font.Decoration;
@@ -159,6 +165,8 @@ public class SignFranchiseServiceImpl implements SignFranchiseService, AuditResu
@Resource
private DictService dictService;
@Resource
private WalletPayInfoDAO walletPayInfoDAO;
@Resource
private SignFranchiseService signFranchiseService;
@@ -840,6 +848,7 @@ public class SignFranchiseServiceImpl implements SignFranchiseService, AuditResu
@Override
@Transactional
public Boolean assignOperationConsultant(AssignOperationConsultantRequest request) {
log.info("assignOperationConsultant:{}",JSONObject.toJSONString(request));
//查询分配信息
@@ -892,7 +901,13 @@ public class SignFranchiseServiceImpl implements SignFranchiseService, AuditResu
//线索id
Long lineId = shopInfoDO.getLineId();
//缴款信息
List<LinePayDO> linePayList = linePayMapper.getFranchiseFeePayInfoByShopId(shopId);
List<LinePayDO> linePayList = null;
List<WalletPayInfoDO> payInfoList = null;
if (PayTypeEnum.OFFLINE.getType().equals(franchiseFeeDO.getPayType())) {
linePayList = linePayMapper.getFranchiseFeePayInfoByShopId(shopId);
} else {
payInfoList = walletPayInfoDAO.getByShopId(shopId, WalletTradeModuleEnum.FRANCHISE_PAY.getModule(), AllocationPayStatusEnum.PAID.getStatus());
}
// //铺位信息
// PointInfoDO pointInfoDO = pointInfoMapper.getDataByShopIdAndLineId(lineId, shopId);
//证照办理
@@ -977,6 +992,19 @@ public class SignFranchiseServiceImpl implements SignFranchiseService, AuditResu
.orElse(null);
addSignFranchiseResponse.setPayDate(earliestPayTime);
}
if(CollectionUtils.isNotEmpty(payInfoList)){
Set<String> payNameSet = new HashSet<>();
List<Date> payTimeList = new ArrayList<>();
for (WalletPayInfoDO payInfoDO : payInfoList){
payNameSet.add(payInfoDO.getPayUserName());
payTimeList.add(payInfoDO.getPayTime());
}
addSignFranchiseResponse.setPayName(new ArrayList<>(payNameSet));
Date earliestPayTime = payTimeList.stream().filter(Objects::nonNull)
.min(Comparator.naturalOrder())
.orElse(null);
addSignFranchiseResponse.setPayDate(earliestPayTime);
}
if (Objects.nonNull(licenseTransactDO)) {
addSignFranchiseResponse.setLicenseName(licenseTransactDO.getBusinessLicense());
addSignFranchiseResponse.setOpeAddress(licenseTransactDO.getLicenseAddress());

View File

@@ -196,8 +196,8 @@ public class SyncMainSysServerImpl implements SyncMainSysServer {
}
storeMasterDTO.setSignerInfo(signerInfo);
simpleMessageService.send(JSONObject.toJSONString(storeMasterDTO), RocketMqTagEnum.ZXJP_CREATE_STORE);
// TODO: 临时关闭,推送营帐通
// pushStoreToYzt(shopInfo, lineInfoDO);
// 推送营帐通
pushStoreToYzt(shopInfo, lineInfoDO);
} catch (Exception e) {
log.info("asdStore_error:{},shopId:{}", e.getMessage(), shopId.toString());
}

View File

@@ -0,0 +1,24 @@
package com.cool.store.service.modify;
import com.cool.store.vo.modify.ModifyRecordVO;
import java.util.List;
/**
* <p>
* 业务修改记录服务类
* </p>
*
* @author wangff
* @since 2026/1/27
*/
public interface ModifyRecordService {
/**
* 查询修改记录
* @param module 模块code
* @param businessId 业务id
* @return 业务修改记录VO列表
*/
List<ModifyRecordVO> getModifyRecorsList(String module, Long businessId);
}

View File

@@ -0,0 +1,35 @@
package com.cool.store.service.modify.impl;
import cn.hutool.core.collection.CollStreamUtil;
import com.cool.store.dao.EnterpriseUserDAO;
import com.cool.store.dao.modify.ModifyRecordDAO;
import com.cool.store.entity.modify.ModifyRecordDO;
import com.cool.store.service.modify.ModifyRecordService;
import com.cool.store.vo.modify.ModifyRecordVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* <p>
* 业务修改记录 服务实现类
* </p>
*
* @author wangff
* @since 2026/1/27
*/
@Service
@RequiredArgsConstructor
public class ModifyRecordServiceImpl implements ModifyRecordService {
private final ModifyRecordDAO modifyRecordDAO;
private final EnterpriseUserDAO enterpriseUserDAO;
@Override
public List<ModifyRecordVO> getModifyRecorsList(String module, Long businessId) {
List<ModifyRecordDO> list = modifyRecordDAO.getListByBusinessId(module, businessId);
Set<String> userIds = CollStreamUtil.toSet(list, ModifyRecordDO::getUpdateUserId);
Map<String, String> userNameMap = enterpriseUserDAO.getUserNameMap(new ArrayList<>(userIds));
return CollStreamUtil.toList(list, v -> new ModifyRecordVO(userNameMap.get(v.getUpdateUserId()), v.getUpdateTime()));
}
}

View File

@@ -0,0 +1,57 @@
package com.cool.store.service.order;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.request.order.*;
import com.cool.store.vo.PartnerUserInfoVO;
import com.cool.store.vo.order.MiniStoreOrderDetailVO;
import com.cool.store.vo.order.MiniStoreOrderListVO;
import com.cool.store.vo.order.MiniStoreWishlistDetailVO;
import com.cool.store.vo.order.MiniStoreWishlistListVO;
import com.cool.store.vo.order.PCStoreOrderListVO;
import com.cool.store.vo.order.WalletPayVO;
import com.github.pagehelper.PageInfo;
import com.sun.org.apache.xpath.internal.operations.Bool;
import java.util.List;
public interface MiniStoreOrderService {
Long createOrder(MiniStoreOrderCreateRequest request,PartnerUserInfoVO userInfoVO);
MiniStoreOrderDetailVO getDetail(Long orderId);
MiniStoreOrderDetailVO getCurrentShopDraft(Long shopId);
MiniStoreOrderDetailVO getLatestOrderByShopId(Long shopId);
PageInfo<MiniStoreOrderListVO> queryPage(MiniStoreOrderQueryRequest request);
Long updateOrder(MiniStoreOrderUpdateRequest request,PartnerUserInfoVO user);
Boolean withdraw(Long orderId);
Boolean cancel(Long orderId);
PageInfo<MiniStoreOrderListVO> queryPageByLineId(MiniStoreOrderLineQueryRequest request);
Boolean passOrder(OrderAuditRecordRequest request,LoginUserInfo userInfo);
Boolean rejectOrder(OrderAuditRecordRequest request,LoginUserInfo userInfo);
Boolean payOrder(MiniStoreOrderPayRequest request, PartnerUserInfoVO userInfo);
PageInfo<PCStoreOrderListVO> list(PCStoreOrderQueryRequest request);
List<WalletPayVO> payList(Long shopId);
Boolean batchUpdateOptionQuantity(PCStoreOrderOptionQuantityUpdateRequest request);
Boolean saveOrUpdateWishlist(MiniStoreWishlistSaveRequest request, PartnerUserInfoVO userInfoVO);
Boolean deleted(MiniStoreWishlistDelRequest miniStoreWishlistDelRequest,PartnerUserInfoVO userInfoVO);
MiniStoreWishlistDetailVO wishlistDetail(Long storeTypeId,String versionNo, PartnerUserInfoVO userInfoVO);
List<MiniStoreWishlistListVO> wishlistList(PartnerUserInfoVO userInfoVO);
}

View File

@@ -0,0 +1,24 @@
package com.cool.store.service.store;
import com.cool.store.entity.order.PreAllocationRecordDO;
import com.cool.store.request.store.PreAllocationQueryShopRequest;
import com.cool.store.request.store.PreAllocationSaveRequest;
import com.cool.store.vo.order.PreAllocationRecordVO;
import com.github.pagehelper.PageInfo;
import java.util.List;
/**
* @Auther zx_szh
* @Date 2026/2/4 15:56
* @Version 1.0
*/
public interface PreAllocationRecordService {
Boolean saveBatch(PreAllocationSaveRequest req);
List<PreAllocationRecordVO> queryByShop(Long shopId);
List<PreAllocationRecordDO> listDOByShop(Long shopId);
}

View File

@@ -0,0 +1,47 @@
package com.cool.store.service.store;
import com.cool.store.request.store.StoreTypeOptionSaveRequest;
import com.cool.store.request.store.StoreTypeQueryRequest;
import com.cool.store.request.store.StoreTypeUpdateRequest;
import com.cool.store.vo.store.StoreTypeOptionVO;
import com.cool.store.vo.store.StoreTypeVO;
import com.github.pagehelper.PageInfo;
import java.util.List;
/**
* 店型 Service
*/
public interface StoreTypeService {
Boolean add(StoreTypeUpdateRequest request);
Boolean update(StoreTypeUpdateRequest request);
PageInfo<StoreTypeVO> queryPage(StoreTypeQueryRequest request);
/**
* 删除(软删除):仅停用状态允许删除
*/
Boolean deleteByIds(List<Long> ids);
/**
* 启用/停用
*/
Boolean changeActive(Long id, Boolean active);
/**
* 保存店型可用配置选项
*/
Boolean saveStoreTypeOptions(StoreTypeOptionSaveRequest request);
/**
* 查询店型已配置的选项绑定
*/
List<StoreTypeOptionVO> listStoreTypeOptions(Long storeTypeId);
/**
* 小程序:按门店类型查询启用的店型
*/
List<StoreTypeVO> listActiveByStoreType(Integer storeType);
}

View File

@@ -0,0 +1,125 @@
package com.cool.store.service.store.impl;
import com.cool.store.dao.ShopStageInfoDAO;
import com.cool.store.dao.fees.WalletPayInfoDAO;
import com.cool.store.dao.order.PreAllocationRecordDAO;
import com.cool.store.dao.order.StoreOrderDAO;
import com.cool.store.entity.fees.WalletPayInfoDO;
import com.cool.store.entity.order.PreAllocationRecordDO;
import com.cool.store.entity.order.StoreOrderDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.order.StoreOrderStatusEnum;
import com.cool.store.enums.point.ShopSubStageStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.store.PreAllocationSaveRequest;
import com.cool.store.service.dict.impl.DictService;
import com.cool.store.service.store.PreAllocationRecordService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.RedisUtil;
import com.cool.store.utils.StringUtil;
import com.cool.store.vo.order.PreAllocationRecordVO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* @Auther zx_szh
* @Date 2026/2/4 15:56
* @Version 1.0
*/
@Service
@RequiredArgsConstructor
public class PreAllocationRecordServiceImpl implements PreAllocationRecordService {
private final PreAllocationRecordDAO dao;
private final RedisUtil redisUtil;
private final DictService dictService;
private final StoreOrderDAO storeOrderDAO;
private final ShopStageInfoDAO shopStageInfoDAO;
private final WalletPayInfoDAO walletPayInfoDAO;
@Transactional
@Override
public Boolean saveBatch(PreAllocationSaveRequest req){
String lockKey = "order:lock:" + req.getOrderId();
String uuid = UUID.randomUUID().toString();
if(!Boolean.TRUE.equals(redisUtil.tryLock(lockKey, uuid,30, TimeUnit.SECONDS))){
throw new ServiceException(ErrorCodeEnum.ORDER_PAYING_CANT_ADJUST);
}
try{
//查询订单
StoreOrderDO storeOrder = storeOrderDAO.getById(req.getOrderId());
//订单不存在
if (Objects.isNull(storeOrder)){
throw new ServiceException(ErrorCodeEnum.STORE_ORDER_NOT_FOUND);
}
BigDecimal totalAmount = storeOrder.getTotalAmount() == null ? BigDecimal.ZERO : storeOrder.getTotalAmount();
BigDecimal sumPayAmount = req.getItems() == null ? BigDecimal.ZERO : req.getItems().stream()
.filter(i -> i != null)
.map(i -> i.getPayAmount() == null ? BigDecimal.ZERO : i.getPayAmount())
.reduce(BigDecimal.ZERO, BigDecimal::add);
//订单金额与分账金额对不上 抛出异常
if (sumPayAmount.compareTo(totalAmount) != 0) {
throw new ServiceException(ErrorCodeEnum.FEE_NOT_CONSISTENT);
}
dao.deleteByShopId(req.getShopId());
List<PreAllocationRecordDO> list = req.getItems().stream().map(i ->
PreAllocationRecordDO.builder()
.orderId(req.getOrderId())
.shopId(req.getShopId())
.expenseType(i.getExpenseType())
.payeeName(i.getPayeeName())
.payeeCode(i.getPayeeCode())
.payAmount(i.getPayAmount())
.allocationStatus(0)
.build()
).collect(Collectors.toList());
dao.insertBatch(list);
shopStageInfoDAO.updateShopStageInfo(req.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_284);
storeOrder.setStatus(StoreOrderStatusEnum.WAIT_PAY.getCode());
storeOrderDAO.updateSelective(storeOrder);
return Boolean.TRUE;
}finally{
redisUtil.unlock(lockKey);
}
}
@Override
public List<PreAllocationRecordVO> queryByShop(Long shopId){
List<PreAllocationRecordDO> list = dao.queryPageByShopId(shopId);
if (CollectionUtils.isEmpty(list)){
return new ArrayList<>();
}
List<String> payNoList = list.stream().filter(x-> StringUtil.isNotEmpty(x.getPayNo())).map(PreAllocationRecordDO::getPayNo).collect(Collectors.toList());
Map<String, WalletPayInfoDO> map = new HashMap<>();
if (CollectionUtils.isNotEmpty(payNoList)){
List<WalletPayInfoDO> wallet = walletPayInfoDAO.getByPayNoList(payNoList);
map = wallet.stream().collect(Collectors.toMap(WalletPayInfoDO::getPayNo, data -> data));
}
List<PreAllocationRecordVO> preAllocationRecordVOS = BeanUtil.copyToList(list, PreAllocationRecordVO.class);
for (PreAllocationRecordVO preAllocationRecordVO : preAllocationRecordVOS) {
WalletPayInfoDO walletPayInfoDO = map.get(preAllocationRecordVO.getPayNo());
if (!Objects.isNull(walletPayInfoDO)){
preAllocationRecordVO.setClaimStatus(walletPayInfoDO.getClaimStatus());
}
}
dictService.fillDictField(preAllocationRecordVOS);
return preAllocationRecordVOS;
}
@Override
public List<PreAllocationRecordDO> listDOByShop(Long shopId) {
return dao.queryPageByShopId(shopId);
}
}

View File

@@ -0,0 +1,225 @@
package com.cool.store.service.store.impl;
import com.cool.store.dao.config.ConfigOptionDAO;
import com.cool.store.dao.store.StoreTypeDAO;
import com.cool.store.dao.store.StoreTypeOptionDAO;
import com.cool.store.entity.config.ConfigOptionDO;
import com.cool.store.entity.store.StoreTypeDO;
import com.cool.store.entity.store.StoreTypeOptionDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.store.StoreTypeOptionSaveRequest;
import com.cool.store.request.store.StoreTypeQueryRequest;
import com.cool.store.request.store.StoreTypeUpdateRequest;
import com.cool.store.service.store.StoreTypeService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.UUIDUtils;
import com.cool.store.vo.store.StoreTypeOptionVO;
import com.cool.store.vo.store.StoreTypeVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 店型 Service impl
*/
@Service
@RequiredArgsConstructor
public class StoreTypeServiceImpl implements StoreTypeService {
private final StoreTypeDAO storeTypeDAO;
private final StoreTypeOptionDAO storeTypeOptionDAO;
private final ConfigOptionDAO configOptionDAO;
@Override
public Boolean add(StoreTypeUpdateRequest request) {
if (request.getSortOrder() != null && storeTypeDAO.existsSortOrder(request.getSortOrder(), null)) {
throw new ServiceException(ErrorCodeEnum.CURRENT_BRAND_SORT_NUMBER_EXIST);
}
if (request.getId()!=null){
throw new ServiceException(ErrorCodeEnum.CURRENT_STORE_TYPE_EXIST);
}
StoreTypeDO entity = BeanUtil.toBean(request, StoreTypeDO.class);
entity.setStoreTypeCode(UUIDUtils.get8UUID());
entity.setDeleted(false);
return storeTypeDAO.insertSelective(entity);
}
@Override
public Boolean update(StoreTypeUpdateRequest request) {
if (request.getSortOrder() != null && storeTypeDAO.existsSortOrder(request.getSortOrder(), request.getId())) {
throw new ServiceException(ErrorCodeEnum.CURRENT_BRAND_SORT_NUMBER_EXIST);
}
if (request.getId()==null){
throw new ServiceException(ErrorCodeEnum.CURRENT_STORE_TYPE_NOT_EXIST);
}
StoreTypeDO entity = BeanUtil.toBean(request, StoreTypeDO.class);
return storeTypeDAO.updateSelective(entity);
}
@Override
public PageInfo<StoreTypeVO> queryPage(StoreTypeQueryRequest request) {
PageHelper.startPage(request.getPageNum(), request.getPageSize());
List<StoreTypeDO> list = storeTypeDAO.queryByCondition(request.getKeyword(), request.getActive(), request.getBrand());
return BeanUtil.toPage(new PageInfo<>(list), StoreTypeVO.class);
}
@Override
public Boolean deleteByIds(List<Long> ids) {
if (CollectionUtils.isEmpty(ids)) {
return false;
}
//目前没有批量
for (Long id : ids) {
StoreTypeDO storeType = storeTypeDAO.getById(id);
if (storeType == null) {
continue;
}
if (Boolean.TRUE.equals(storeType.getActive())) {
throw new ServiceException(ErrorCodeEnum.STORE_TYPE_MUST_DISABLE_BEFORE_DELETE);
}
}
//将配置改为不可以状态
storeTypeOptionDAO.softDeleteByStoreTypeId(ids);
return storeTypeDAO.softDeleteByIds(ids);
}
@Override
public Boolean changeActive(Long id, Boolean active) {
if (id == null || active == null) {
return false;
}
StoreTypeDO storeType = storeTypeDAO.getById(id);
if (storeType == null) {
return false;
}
return storeTypeDAO.updateActiveById(id, active);
}
@Override
public Boolean saveStoreTypeOptions(StoreTypeOptionSaveRequest request) {
if (request == null || request.getStoreTypeId() == null) {
return false;
}
if (CollectionUtils.isEmpty(request.getOptions())) {
// 没有传配置项,清空即可
storeTypeOptionDAO.deleteByStoreTypeId(request.getStoreTypeId());
return true;
}
// 校验:相同 itemCode 下只能有一个默认
// Map<String, Integer> defaultCountMap = new HashMap<>();
// for (StoreTypeOptionSaveRequest.StoreTypeOptionItemRequest item : request.getOptions()) {
// if (item == null || item.getItemCode() == null||item.getCategoryCode()==null) {
// continue;
// }
// if (item.getIsDefault() != null && item.getIsDefault() == 1) {
// String key = item.getCategoryCode() + item.getItemCode();
// defaultCountMap.merge(key, 1, Integer::sum);
// }
// }
// for (Map.Entry<String, Integer> e : defaultCountMap.entrySet()) {
// if (e.getValue() != null && e.getValue() > 1) {
// throw new ServiceException(ErrorCodeEnum.STORE_TYPE_OPTION_DEFAULT_DUPLICATE);
// }
// }
// 先删除旧绑定
storeTypeOptionDAO.deleteByStoreTypeId(request.getStoreTypeId());
Date now = new Date();
List<StoreTypeOptionDO> list = new ArrayList<>(request.getOptions().size());
List<Long> optionIds = request.getOptions().stream()
.filter(Objects::nonNull)
.map(StoreTypeOptionSaveRequest.StoreTypeOptionItemRequest::getOptionId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
Map<Long, ConfigOptionDO> configOptionMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(optionIds)) {
List<ConfigOptionDO> optionList = configOptionDAO.listActiveByIds(optionIds);
configOptionMap = optionList.stream().collect(Collectors.toMap(ConfigOptionDO::getId, Function.identity(), (a, b) -> a));
}
for (StoreTypeOptionSaveRequest.StoreTypeOptionItemRequest item : request.getOptions()) {
ConfigOptionDO configOption = configOptionMap.get(item.getOptionId());
StoreTypeOptionDO entity = StoreTypeOptionDO.builder()
.storeTypeId(request.getStoreTypeId())
.optionId(item.getOptionId())
.categoryCode(item.getCategoryCode())
.itemCode(item.getItemCode())
.isDefault(item.getIsDefault())
.defaultQuantity(item.getDefaultQuantity())
.allowQuantityEdit(item.getAllowQuantityEdit())
.sortOrder(item.getSortOrder())
.optionPrice(item.getOptionPrice()==null?configOption.getOptionPrice():item.getOptionPrice())
.topPreviewImage(item.getTopPreviewImage())
.createTime(now)
.updateTime(now)
.build();
list.add(entity);
}
return storeTypeOptionDAO.insertBatchSelective(list);
}
@Override
public List<StoreTypeOptionVO> listStoreTypeOptions(Long storeTypeId) {
if (storeTypeId == null) {
return new ArrayList<>();
}
List<StoreTypeOptionDO> list = storeTypeOptionDAO.listByStoreTypeId(storeTypeId);
if (CollectionUtils.isEmpty(list)) {
return new ArrayList<>();
}
List<Long> optionIds = list.stream()
.map(StoreTypeOptionDO::getOptionId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
Map<Long, ConfigOptionDO> optionMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(optionIds)) {
List<ConfigOptionDO> options = configOptionDAO.listActiveByIds(optionIds);
optionMap = options.stream()
.collect(Collectors.toMap(ConfigOptionDO::getId, Function.identity(), (a, b) -> a));
}
List<StoreTypeOptionVO> vos = BeanUtil.toList(list, StoreTypeOptionVO.class);
for (StoreTypeOptionVO vo : vos) {
if (vo == null || vo.getOptionId() == null) {
continue;
}
ConfigOptionDO opt = optionMap.get(vo.getOptionId());
if (opt == null) {
continue;
}
vo.setOptionImageUrl(opt.getImageUrl());
vo.setOptionPrice(vo.getOptionPrice());
vo.setOriginalOptionPrice(opt.getOriginalOptionPrice());
vo.setOptionRemark(opt.getOptionRemark());
vo.setOptionName(opt.getOptionName());
vo.setOptionDescription(opt.getOptionDescription());
vo.setOptionUnit(opt.getOptionUnit());
}
return vos;
}
@Override
public List<StoreTypeVO> listActiveByStoreType(Integer storeType) {
if (storeType == null) {
return new ArrayList<>();
}
List<StoreTypeDO> list = storeTypeDAO.listActiveByStoreType(storeType);
return BeanUtil.toList(list, StoreTypeVO.class);
}
}

View File

@@ -0,0 +1,24 @@
package com.cool.store.service.visit;
import com.cool.store.request.visit.*;
import com.cool.store.vo.visit.StoreVisitReservationVO;
import com.github.pagehelper.PageInfo;
import java.util.List;
public interface StoreVisitReservationService {
Long create(StoreVisitReservationCreateRequest request);
StoreVisitReservationVO detail(Long id);
List<StoreVisitReservationVO> myReservations(String mobile,Integer status);
PageInfo<StoreVisitReservationVO> adminPage(StoreVisitReservationAdminQueryRequest request);
Boolean arrived(StoreVisitReservationIdRequest request);
Boolean assignServiceUser(StoreVisitReservationAssignServiceRequest request);
Boolean cancel(StoreVisitReservationCancelRequest request);
}

View File

@@ -0,0 +1,179 @@
package com.cool.store.service.visit.impl;
import com.cool.store.dao.EnterpriseUserDAO;
import com.cool.store.dao.HyOpenAreaInfoDAO;
import com.cool.store.dao.store.StoreTypeDAO;
import com.cool.store.dao.visit.StoreVisitReservationDAO;
import com.cool.store.entity.EnterpriseUserDO;
import com.cool.store.entity.HyOpenAreaInfoDO;
import com.cool.store.entity.store.StoreTypeDO;
import com.cool.store.entity.visit.StoreVisitReservationDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.visit.StoreVisitReservationStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.visit.*;
import com.cool.store.service.visit.StoreVisitReservationService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.StringUtil;
import com.cool.store.vo.visit.StoreVisitReservationVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class StoreVisitReservationServiceImpl implements StoreVisitReservationService {
private final StoreVisitReservationDAO storeVisitReservationDAO;
private final StoreTypeDAO storeTypeDAO;
private final HyOpenAreaInfoDAO hyOpenAreaInfoDAO;
private final EnterpriseUserDAO enterpriseUserDAO;
@Override
public Long create(StoreVisitReservationCreateRequest request) {
checkIntentCityExists(request.getIntentCityId());
StoreVisitReservationDO reservationDO = BeanUtil.toBean(request, StoreVisitReservationDO.class);
reservationDO.setStatus(StoreVisitReservationStatusEnum.WAIT_CONFIRM.getStatus());
reservationDO.setDeleted(0);
storeVisitReservationDAO.insertSelective(reservationDO);
return reservationDO.getId();
}
@Override
public StoreVisitReservationVO detail(Long id) {
StoreVisitReservationDO reservationDO = getAvailableById(id);
if (reservationDO==null){
return new StoreVisitReservationVO();
}
StoreVisitReservationVO storeVisitReservationVO = BeanUtil.toBean(reservationDO, StoreVisitReservationVO.class);
if (storeVisitReservationVO.getIntentCityId()!=null){
HyOpenAreaInfoDO hyOpenAreaInfoDO = hyOpenAreaInfoDAO.selectById(storeVisitReservationVO.getIntentCityId());
storeVisitReservationVO.setIntentCityPath(hyOpenAreaInfoDO.getAreaPath());
storeVisitReservationVO.setIntentCityName(hyOpenAreaInfoDO.getAreaName());
}
if (storeVisitReservationVO.getServiceUserId()!=null){
EnterpriseUserDO user = enterpriseUserDAO.getUserInfoById(storeVisitReservationVO.getServiceUserId());
storeVisitReservationVO.setServiceUserName(user.getName());
storeVisitReservationVO.setServiceUserMobile(user.getMobile());
}
return storeVisitReservationVO;
}
@Override
public List<StoreVisitReservationVO> myReservations(String mobile,Integer status) {
List<StoreVisitReservationVO> list = BeanUtil.toList(storeVisitReservationDAO.listByMobile(mobile, status), StoreVisitReservationVO.class);
List<String> userIdList = list.stream().filter(o -> StringUtils.isNotBlank(o.getServiceUserId()))
.map(StoreVisitReservationVO::getServiceUserId).collect(Collectors.toList());
Map<String, EnterpriseUserDO> userNameMap = enterpriseUserDAO.getUserMap(userIdList);
List<Long> intentCityList = list.stream().filter(o -> o.getIntentCityId() != null)
.map(StoreVisitReservationVO::getIntentCityId).collect(Collectors.toList());
Map<Long, HyOpenAreaInfoDO> cityMap = hyOpenAreaInfoDAO.getCityMap(intentCityList);
list.forEach(x->{
EnterpriseUserDO enterpriseUserDO = userNameMap.get(x.getServiceUserId());
if (enterpriseUserDO!=null){
x.setServiceUserName(enterpriseUserDO.getName());
x.setServiceUserMobile(enterpriseUserDO.getMobile());
}
HyOpenAreaInfoDO hyOpenAreaInfoDO = cityMap.get(x.getIntentCityId());
if (hyOpenAreaInfoDO!=null){
x.setIntentCityName(hyOpenAreaInfoDO.getAreaName());
x.setIntentCityPath(hyOpenAreaInfoDO.getAreaPath());
}
});
return list;
}
@Override
public PageInfo<StoreVisitReservationVO> adminPage(StoreVisitReservationAdminQueryRequest request) {
Integer pageNum = request.getPageNum() == null ? 1 : request.getPageNum();
Integer pageSize = request.getPageSize() == null ? 10 : request.getPageSize();
PageHelper.startPage(pageNum, pageSize);
List<StoreVisitReservationVO> list = storeVisitReservationDAO.adminPage(request);
List<String> userIdList = list.stream().filter(o -> StringUtils.isNotBlank(o.getServiceUserId()))
.map(StoreVisitReservationVO::getServiceUserId).collect(Collectors.toList());
Map<String, EnterpriseUserDO> userNameMap = enterpriseUserDAO.getUserMap(userIdList);
List<Long> intentCityList = list.stream().filter(o -> o.getIntentCityId() != null)
.map(StoreVisitReservationVO::getIntentCityId).collect(Collectors.toList());
Map<Long, HyOpenAreaInfoDO> cityMap = hyOpenAreaInfoDAO.getCityMap(intentCityList);
list.forEach(x->{
EnterpriseUserDO enterpriseUserDO = userNameMap.get(x.getServiceUserId());
if (enterpriseUserDO!=null){
x.setServiceUserName(enterpriseUserDO.getName());
x.setServiceUserMobile(enterpriseUserDO.getMobile());
}
HyOpenAreaInfoDO hyOpenAreaInfoDO = cityMap.get(x.getIntentCityId());
if (hyOpenAreaInfoDO!=null){
x.setIntentCityName(hyOpenAreaInfoDO.getAreaName());
x.setIntentCityPath(hyOpenAreaInfoDO.getAreaPath());
}
});
return new PageInfo<>(list);
}
@Override
public Boolean arrived(StoreVisitReservationIdRequest request) {
StoreVisitReservationDO old = getAvailableById(request.getId());
if (StoreVisitReservationStatusEnum.CANCELED.getStatus().equals(old.getStatus())) {
throw new ServiceException(ErrorCodeEnum.NOT_ALLOW_OPERATE);
}
StoreVisitReservationDO update = new StoreVisitReservationDO();
update.setId(old.getId());
update.setStatus(StoreVisitReservationStatusEnum.ARRIVED.getStatus());
update.setUpdateTime(new Date());
return storeVisitReservationDAO.updateSelective(update);
}
@Override
public Boolean assignServiceUser(StoreVisitReservationAssignServiceRequest request) {
StoreVisitReservationDO old = getAvailableById(request.getId());
StoreVisitReservationDO update = new StoreVisitReservationDO();
update.setId(old.getId());
update.setServiceUserId(request.getServiceUserId());
if (StoreVisitReservationStatusEnum.WAIT_CONFIRM.getStatus().equals(old.getStatus())) {
update.setStatus(StoreVisitReservationStatusEnum.WAIT_VISIT.getStatus());
}
update.setUpdateTime(new Date());
return storeVisitReservationDAO.updateSelective(update);
}
@Override
public Boolean cancel(StoreVisitReservationCancelRequest request) {
StoreVisitReservationDO old = getAvailableById(request.getId());
if (StoreVisitReservationStatusEnum.ARRIVED.getStatus().equals(old.getStatus())) {
throw new ServiceException(ErrorCodeEnum.NOT_ALLOW_OPERATE);
}
StoreVisitReservationDO update = new StoreVisitReservationDO();
update.setId(old.getId());
update.setStatus(StoreVisitReservationStatusEnum.CANCELED.getStatus());
update.setCancelReason(request.getCancelReason());
update.setUpdateTime(new Date());
return storeVisitReservationDAO.updateSelective(update);
}
private void checkIntentCityExists(Long intentCityId) {
HyOpenAreaInfoDO areaInfoDO = hyOpenAreaInfoDAO.selectById(intentCityId);
if (Objects.isNull(areaInfoDO) || Objects.equals(areaInfoDO.getDeleted(), 1)) {
throw new ServiceException(ErrorCodeEnum.OPEN_AREA_IS_NOT_EXISTS);
}
}
private StoreVisitReservationDO getAvailableById(Long id) {
StoreVisitReservationDO reservationDO = storeVisitReservationDAO.getById(id);
if (Objects.isNull(reservationDO) || Objects.equals(reservationDO.getDeleted(), 1)) {
throw new ServiceException(ErrorCodeEnum.NO_DATA);
}
return reservationDO;
}
}

View File

@@ -0,0 +1,25 @@
package com.cool.store.service.wallet;
import com.cool.store.entity.wallet.WalletTradeDO;
import com.cool.store.enums.wallet.WalletTradeModuleEnum;
/**
* <p>
* 钱包交易业务模块处理
* </p>
*
* @author wangff
* @since 2026/2/4
*/
public interface IWalletTradeResolve {
/**
* 模块code
*/
WalletTradeModuleEnum getModule();
/**
* 业务处理
*/
void resolve(WalletTradeDO walletTradeDO);
}

View File

@@ -120,6 +120,17 @@ public class WalletApiService {
}
/**
* 门店账户向公司分账转账接口(批量转账接口)
* @param request
* @return
*/
public BatchTransferDTO batchTransfer(BatchTransferRequest request){
return walletHttpClientRest.postWithSign(walletBaseUrl+"/open/crm/trans/v1/batchTransfer", request, BatchTransferDTO.class);
}
/**
* 门店签约账户,退款提现至提现卡
* @param request

View File

@@ -0,0 +1,43 @@
package com.cool.store.service.wallet;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.wallet.WalletTradeModuleEnum;
import com.cool.store.exception.ServiceException;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* <p>
* 钱包交易业务处理工厂
* </p>
*
* @author wangff
* @since 2026/2/4
*/
@Service
public class WalletTradeResolveFactory {
@Resource
private IWalletTradeResolve[] resolves;
private final Map<WalletTradeModuleEnum, IWalletTradeResolve> resolveMap = new HashMap<>();
@PostConstruct
public void init() {
for (IWalletTradeResolve resolve : resolves) {
resolveMap.put(resolve.getModule(), resolve);
}
}
public IWalletTradeResolve getResolve(WalletTradeModuleEnum module) {
IWalletTradeResolve resolve = resolveMap.get(module);
if (Objects.isNull(resolve)) {
throw new ServiceException(ErrorCodeEnum.NOT_EXIST_CALLBACK_RESOLVE);
}
return resolve;
}
}

View File

@@ -0,0 +1,21 @@
package com.cool.store.service.wallet;
/**
* <p>
* 钱包交易服务类
* </p>
*
* @author wangff
* @since 2026/2/4
*/
public interface WalletTradeService {
/**
* 交易回调
* @param storeId 门店id
* @param payNo 付款单号
* @param tradeId 交易流水号
* @param payStatus 付款状态
*/
void tradeCallback(String storeId, String payNo, String tradeId, Integer payStatus);
}

View File

@@ -0,0 +1,52 @@
package com.cool.store.service.wallet.impl;
import com.cool.store.dao.fees.WalletPayInfoDAO;
import com.cool.store.entity.fees.WalletPayInfoDO;
import com.cool.store.entity.wallet.WalletTradeDO;
import com.cool.store.enums.wallet.WalletTradeModuleEnum;
import com.cool.store.service.PushService;
import com.cool.store.service.wallet.IWalletTradeResolve;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Objects;
/**
* <p>
* 钱包加盟缴费
* </p>
*
* @author wangff
* @since 2026/2/4
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class WalletFranchisePayResolve implements IWalletTradeResolve {
private final WalletPayInfoDAO walletPayInfoDAO;
private final PushService pushService;
@Override
public WalletTradeModuleEnum getModule() {
return WalletTradeModuleEnum.FRANCHISE_PAY;
}
@Override
@Transactional
public void resolve(WalletTradeDO walletTradeDO) {
// 修改业务订单状态
WalletPayInfoDO payInfoDO = walletPayInfoDAO.getByPayNo(walletTradeDO.getPayNo());
if (Objects.isNull(payInfoDO)) {
log.info("不存在钱包加盟缴费信息");
return;
}
payInfoDO.setPayStatus(walletTradeDO.getPayStatus());
if (StringUtils.isBlank(payInfoDO.getTradeId())) {
payInfoDO.setTradeId(walletTradeDO.getTradeId());
}
walletPayInfoDAO.updateByPrimaryKeySelective(payInfoDO);
}
}

View File

@@ -18,6 +18,8 @@ import com.cool.store.entity.wallet.OpenBankInfoDO;
import com.cool.store.entity.wallet.TempOpenWalletInfoDO;
import com.cool.store.entity.wallet.WalletPaymentOrderDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.MessageEnum;
import com.cool.store.enums.UserRoleEnum;
import com.cool.store.enums.point.ShopSubStageEnum;
import com.cool.store.enums.point.ShopSubStageStatusEnum;
import com.cool.store.enums.wallet.BankAccountTypeEnum;
@@ -26,9 +28,10 @@ import com.cool.store.enums.wechat.WalletTypeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.ApplyLicenseMapper;
import com.cool.store.request.wallet.*;
import com.cool.store.service.UserAuthMappingService;
import com.cool.store.service.dict.impl.DictService;
import com.cool.store.service.wallet.WalletApiService;
import com.cool.store.service.wallet.WalletService;
import com.cool.store.service.impl.CommonService;
import com.cool.store.service.wallet.*;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.RedisUtilPool;
import com.cool.store.utils.UUIDUtils;
@@ -75,6 +78,9 @@ public class WalletServiceImpl implements WalletService {
private final TempOpenWalletInfoDAO tempOpenWalletInfoDAO;
private final OpenBankInfoDAO openBankInfoDAO;
private final DictService dictService;
private final UserAuthMappingService userAuthMappingService;
private final CommonService commonService;
private final WalletTradeService walletTradeService;
private final static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@@ -139,11 +145,35 @@ public class WalletServiceImpl implements WalletService {
// 更新钱包开通阶段状态
List<ShopSubStageStatusEnum> updateSubStageList = new ArrayList<>();
updateSubStageList.add(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_61);
// 判断一下缴费阶段是否开启,未开启则开启缴费阶段
ShopStageInfoDO payStage = shopStageInfoDAO.getShopSubStageInfo(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_7);
if (ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_00.getShopSubStageStatus().equals(payStage.getShopSubStageStatus())) {
updateSubStageList.add(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_70);
// 判断一下缴费阶段是否开启,未开启则开启缴费阶段 useStandardStore 普通店 标准店开启选配店型
if (shopInfo.getUseStandardStore()==0){
ShopStageInfoDO payStage = shopStageInfoDAO.getShopSubStageInfo(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_7);
if (ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_00.getShopSubStageStatus().equals(payStage.getShopSubStageStatus())) {
updateSubStageList.add(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_70);
LineInfoDO lineInfo = lineInfoDAO.getLineInfo(shopInfo.getLineId());
Set<String> publishFranchiseFeeUsers = new HashSet<>();
List<EnterpriseUserDO> joinUser = userAuthMappingService.getAllUserByRoleEnumAndRegionId(UserRoleEnum.JOIN_OFFICE, lineInfo.getRegionId());
if (Objects.nonNull(joinUser)) {
Set<String> joinUserIds = joinUser.stream().map(EnterpriseUserDO::getUserId).collect(Collectors.toSet());
publishFranchiseFeeUsers.addAll(joinUserIds);
}
List<EnterpriseUserDO> regionUser = userAuthMappingService.getAllUserByRoleEnumAndRegionId(UserRoleEnum.REGION_OFFICE, lineInfo.getRegionId());
if (Objects.nonNull(regionUser)) {
Set<String> regionUserIds = regionUser.stream().map(EnterpriseUserDO::getUserId).collect(Collectors.toSet());
publishFranchiseFeeUsers.addAll(regionUserIds);
}
HashMap<String, String> map = new HashMap<>();
map.put("partnerUsername", lineInfo.getUsername());
map.put("partnerMobile", lineInfo.getMobile());
//发送工作通知
commonService.sendQWMessage(new ArrayList<>(publishFranchiseFeeUsers),
MessageEnum.MESSAGE_23,
map);
}
}else{
updateSubStageList.add(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_280);
}
shopStageInfoDAO.batchUpdateShopStageStatus(request.getShopId(), updateSubStageList);
// 判断营业执照是否已经上传,已上传则调用打标接口
@@ -308,6 +338,9 @@ public class WalletServiceImpl implements WalletService {
@Override
public Boolean accountTradeCallback(AccountTradeCallbackRequest request) {
// if (CommonConstants.INDEX_ONE.equals(request.getTradeType())) {
// walletTradeService.tradeCallback(request.getOutStoreId(), request.getReqNo(), String.valueOf(request.getTradeId()), request.getTradeStatus());
// }
return Boolean.TRUE;
}

View File

@@ -0,0 +1,54 @@
package com.cool.store.service.wallet.impl;
import com.cool.store.dao.wallet.WalletTradeDAO;
import com.cool.store.entity.wallet.WalletTradeDO;
import com.cool.store.enums.wallet.WalletTradeModuleEnum;
import com.cool.store.service.wallet.IWalletTradeResolve;
import com.cool.store.service.wallet.WalletTradeResolveFactory;
import com.cool.store.service.wallet.WalletTradeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Objects;
/**
* <p>
* 钱包交易 服务实现类
* </p>
*
* @author wangff
* @since 2026/2/4
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class WalletTradeServiceImpl implements WalletTradeService {
private final WalletTradeDAO walletTradeDAO;
private final WalletTradeResolveFactory walletTradeResolveFactory;
@Override
@Transactional
@Async("generalThreadPool")
public void tradeCallback(String storeId, String payNo, String tradeId, Integer payStatus) {
WalletTradeDO walletTradeDO = walletTradeDAO.getByPayNo(payNo);
if (Objects.nonNull(walletTradeDO)) {
if (Objects.isNull(walletTradeDO.getTradeId())) {
walletTradeDO.setTradeId(tradeId);
}
walletTradeDO.setPayStatus(payStatus);
try {
WalletTradeModuleEnum module = WalletTradeModuleEnum.getByModule(walletTradeDO.getModule());
if (Objects.nonNull(module)) {
IWalletTradeResolve tradeResolve = walletTradeResolveFactory.getResolve(module);
tradeResolve.resolve(walletTradeDO);
}
} catch (Exception e) {
log.error("钱包交易回调业务处理失败", e);
}
walletTradeDAO.updateByPrimaryKeySelective(walletTradeDO);
}
}
}