Merge #132 into master from revert-56b85c33-20f063dc

Revert commit "Merge #128 into master from cc_20250512_uploadRentContract

* revert-56b85c33-20f063dc: (1 commits squashed)

  - Revert commit "Merge #128 into master from cc_20250512_uploadRentContract
    
    This reverts change request#128

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/132
This commit is contained in:
正新
2026-05-12 09:56:16 +00:00
parent fcb6fb0770
commit 8caf3b1a6a
325 changed files with 262 additions and 14063 deletions

View File

@@ -34,5 +34,4 @@ public class WechatMpProperties {
* 发送模板消息的URL
*/
private String sendTemplateMessageUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send";
}

View File

@@ -1,55 +0,0 @@
package com.cool.store.handler;
import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class TitleWriteHandler implements RowWriteHandler {
private final String title;
public TitleWriteHandler(String title) {
this.title = title;
}
@Override
public void beforeRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Integer rowIndex, Integer relativeRowIndex, Boolean isHead) {
if (rowIndex == 0 && !isHead) {
// 创建第一行index=0
Sheet sheet = writeSheetHolder.getSheet();
Row row = sheet.createRow(0);
// 创建单元格并设置标题内容
Cell cell = row.createCell(0);
cell.setCellValue(title);
// 合并第一行的所有列假设最多有10列
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 9));
// 设置字体样式(可选)
Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
CellStyle cellStyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setBold(true);
font.setFontHeightInPoints((short) 16);
cellStyle.setFont(font);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
cell.setCellStyle(cellStyle);
}
}
@Override
public void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer integer, Boolean aBoolean) {
}
@Override
public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer integer, Boolean aBoolean) {
}
}

View File

@@ -174,9 +174,7 @@ public class WalletHttpClientRest {
throw new ServiceException(ErrorCodeEnum.WALLET_API_ERROR, msg);
} else if (code == 610 || msg.equals("支付密码不正确")) {
throw new ServiceException(ErrorCodeEnum.PASSWORD_ERROR);
} else if (code == 611) {
throw new ServiceException(ErrorCodeEnum.WALLET_OPEN_ACCOUNT_NO_BALANCE);
}else {
} else {
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,
"code: " + code + ", msg: " + msg);
}

View File

@@ -8,7 +8,6 @@ import com.cool.store.dto.wx.PhoneInfoDTO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mq.util.HttpRestTemplateService;
import com.cool.store.utils.CommonContextUtil;
import com.cool.store.utils.RedisUtilPool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -17,7 +16,6 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
/**
* @author zhangchenbiao
@@ -49,11 +47,6 @@ public class WechatRest {
String GET_MINIAPP_URL_LINK = "https://api.weixin.qq.com/wxa/generate_urllink?access_token=%s";
/**
* 生成小程序二维码
*/
String GET_MINIAPP_QR_CODE = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s";
public CodeSessionDTO miniProgramJsCodeSession(String appId, String secret, String jsCode){
log.info("WechatRest#miniProgramJsCodeSession, jsCode:{}", jsCode);
@@ -145,44 +138,4 @@ public class WechatRest {
return null;
}
public byte[] createQrCode(String accessToken, String page, String scene, String width) {
String reqUrl = String.format(GET_MINIAPP_QR_CODE, accessToken);
Map<String, Object> body = new HashMap<>();
body.put("page", page);
body.put("scene", scene);
body.put("env_version", CommonContextUtil.getProfileName().equals("online") ? "release" : "trial");
if (StringUtils.isNotBlank(width)) {
body.put("width", width);
}
try {
// 直接使用 byte[] 接收二进制图片数据
byte[] result = httpRestTemplateService.postForObject(reqUrl, body, byte[].class);
if (result == null || result.length == 0) {
log.error("二维码生成失败, 返回数据为空");
return null;
}
// 检查是否是图片格式PNG开头是 89 50 4E 47JPEG开头是 FF D8 FF
boolean isImage = (result.length > 4 &&
// PNG: 89 50 4E 47 (即 0x89 'P' 'N' 'G')
(result[0] == (byte) 0x89 && result[1] == 0x50 && result[2] == 0x4E && result[3] == 0x47) ||
// JPEG: FF D8 FF
(result[0] == (byte) 0xFF && result[1] == (byte) 0xD8 && result[2] == (byte) 0xFF));
if (!isImage) {
// 不是图片说明返回的是错误JSON
String response = new String(result);
log.error("二维码生成失败, response:{}", response);
JSONObject jsonObject = JSONObject.parseObject(response);
if ("40001".equals(jsonObject.getString("errcode"))) {
throw new ServiceException(ErrorCodeEnum.WX_ACCESS_TOKEN_INVALID);
}
return null;
}
return result;
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
log.error("二维码生成失败", e);
}
return null;
}
}

View File

@@ -12,7 +12,6 @@ import com.cool.store.mq.consumer.listener.*;
import com.google.common.collect.Maps;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import javax.annotation.Resource;
import java.util.Map;
@@ -25,7 +24,6 @@ import java.util.Properties;
* @date 2021-12-21 11:35
*/
@Configuration
@Lazy
public class ConsumerClient {
@Resource
@@ -43,10 +41,6 @@ public class ConsumerClient {
@Resource
private TpPenaltyAppealListener tpPenaltyAppealListener;
@Resource
private ExamAutoSubmitListener examAutoSubmitListener;
@Resource
private ExamAutoEndListener examAutoEndListener;
@Resource
private CloseUpApplyStoreUpdateListener closeUpApplyStoreUpdateListener;
@Resource
private CloseUpPlanOpenStoreListener closeUpPlanOpenStoreListener;
@@ -155,32 +149,6 @@ public class ConsumerClient {
return consumerBean;
}
@Bean(initMethod = "start", destroyMethod = "shutdown")
public ConsumerBean examAutoSubmit() {
RocketMqGroupEnum groupEnum = RocketMqGroupEnum.EXAM_AUTO_SUBMIT;
ConsumerBean consumerBean = new ConsumerBean();
//配置文件
Properties properties = getCommonProperties(groupEnum);
consumerBean.setProperties(properties);
Map<Subscription, MessageListener> commonSubscriptionTable = getCommonSubscriptionTable(groupEnum, examAutoSubmitListener);
//订阅多个topic如上面设置
consumerBean.setSubscriptionTable(commonSubscriptionTable);
return consumerBean;
}
@Bean(initMethod = "start", destroyMethod = "shutdown")
public ConsumerBean examAutoEnd() {
RocketMqGroupEnum groupEnum = RocketMqGroupEnum.EXAM_AUTO_END;
ConsumerBean consumerBean = new ConsumerBean();
//配置文件
Properties properties = getCommonProperties(groupEnum);
consumerBean.setProperties(properties);
Map<Subscription, MessageListener> commonSubscriptionTable = getCommonSubscriptionTable(groupEnum, examAutoEndListener);
//订阅多个topic如上面设置
consumerBean.setSubscriptionTable(commonSubscriptionTable);
return consumerBean;
}
@Bean(initMethod = "start", destroyMethod = "shutdown")
public ConsumerBean closeUpApplyStoreUpdate() {
RocketMqGroupEnum groupEnum = RocketMqGroupEnum.CLOSE_UP_APPLY_STORE_UPDATE;

View File

@@ -1,52 +0,0 @@
package com.cool.store.mq.consumer.listener;
import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.MessageListener;
import com.cool.store.constants.CommonConstants;
import com.cool.store.service.exam.ExamInfoService;
import com.cool.store.utils.RedisUtilPool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 考试自动结束消费者监听器
*/
@Slf4j
@Service
public class ExamAutoEndListener implements MessageListener {
@Resource
private RedisUtilPool redisUtilPool;
@Resource
private ExamInfoService examInfoService;
@Override
public Action consume(Message message, ConsumeContext context) {
String text = new String(message.getBody());
if (StringUtils.isBlank(text)) {
log.info("消息体为空,tag:{},messageId:{}", message.getTag(), message.getMsgID());
return Action.CommitMessage;
}
String lockKey = "ExamAutoEndListener:" + message.getMsgID();
boolean lock = redisUtilPool.setNxExpire(lockKey, message.getMsgID(), CommonConstants.NORMAL_LOCK_TIMES);
if (lock) {
try {
Long examId = Long.valueOf(text);
examInfoService.autoEndExam(examId);
} catch (Exception e) {
log.error("ExamAutoEndListener consume error", e);
return Action.ReconsumeLater;
} finally {
redisUtilPool.delKey(lockKey);
}
log.info("消费成功,tag:{},messageId:{},examId={}", message.getTag(), message.getMsgID(), text);
return Action.CommitMessage;
}
return Action.ReconsumeLater;
}
}

View File

@@ -1,52 +0,0 @@
package com.cool.store.mq.consumer.listener;
import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.MessageListener;
import com.cool.store.constants.CommonConstants;
import com.cool.store.service.exam.ExamAttemptService;
import com.cool.store.utils.RedisUtilPool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 考试自动提交消费者监听器
*/
@Slf4j
@Service
public class ExamAutoSubmitListener implements MessageListener {
@Resource
private RedisUtilPool redisUtilPool;
@Resource
private ExamAttemptService examAttemptService;
@Override
public Action consume(Message message, ConsumeContext context) {
String text = new String(message.getBody());
if (StringUtils.isBlank(text)) {
log.info("消息体为空,tag:{},messageId:{}", message.getTag(), message.getMsgID());
return Action.CommitMessage;
}
String lockKey = "ExamAutoSubmitListener:" + message.getMsgID();
boolean lock = redisUtilPool.setNxExpire(lockKey, message.getMsgID(), CommonConstants.NORMAL_LOCK_TIMES);
if (lock) {
try {
Long attemptId = Long.valueOf(text);
examAttemptService.autoSubmit(attemptId);
} catch (Exception e) {
log.error("ExamAutoSubmitListener consume error", e);
return Action.ReconsumeLater;
} finally {
redisUtilPool.delKey(lockKey);
}
log.info("消费成功,tag:{},messageId:{},attemptId={}", message.getTag(), message.getMsgID(), text);
return Action.CommitMessage;
}
return Action.ReconsumeLater;
}
}

View File

@@ -87,11 +87,5 @@ public interface AdjustmentOrderService {
*/
Long pageCount(AdjustmentOrderPageRequest request,LoginUserInfo user);
/**
* 审批调整单
* @param request 审批请求
* @return 是否成功
*/
Boolean approval(AdjustmentApprovalRequest request);
}

View File

@@ -18,7 +18,7 @@ public interface AuditOpeningOperationPlanService {
* @Date: 2024/4/23
* @description:审核方案
*/
@Deprecated
Boolean auditPlan(OpeningOperationPlanAuditRequest openingOperationPlanAuditRequest, LoginUserInfo user);

View File

@@ -6,6 +6,7 @@ import com.cool.store.request.*;
import com.cool.store.request.order.PCStoreOrderQueryRequest;
import com.cool.store.request.tp.TpScoreJournalQueryRequest;
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;
import com.cool.store.response.ShopReportResponse;
@@ -41,7 +42,6 @@ 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

@@ -9,8 +9,6 @@ import com.cool.store.request.order.PCStoreOrderQueryRequest;
import com.cool.store.request.tp.TpScoreJournalQueryRequest;
import com.cool.store.request.visit.VisitRecordQueryRequest;
import com.cool.store.request.visit.VisitRecordQueryRequest;
import com.cool.store.request.order.PCStoreOrderQueryRequest;
import com.cool.store.request.visit.VisitRecordQueryRequest;
/**
* @Author: WangShuo

View File

@@ -1,27 +0,0 @@
package com.cool.store.service;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dto.ImportReceivingBankDTO;
import com.cool.store.entity.ImportTaskDO;
import java.util.List;
import java.util.Map;
/**
* @Author: WangShuo
* @Date: 2025/06/19/10:29
* @Version 1.0
* @注释:
*/
public interface ImportService {
/**
* 导入银行配置信息
* @param list
* @param originalFilename
* @param userId
* @param task
* @return
*/
Boolean importReceivingBank(List<ImportReceivingBankDTO> list, String originalFilename, String userId,
ImportTaskDO task);
}

View File

@@ -1,36 +0,0 @@
package com.cool.store.service;
/**
* 猎聘-招商 业务servive
* @Author suzhuhong
* @Date 2025/5/26 19:26
* @Version 1.0
*/
public interface LiePinService {
/**
* 获取小程序跳转链接
* @param shopCode
* @return mobile 当前登录人手机号
*/
String getJumpUrl(String shopCode,String mobile,String userName);
/**
* 推送门店到猎聘
* @param shopCode
* @return
*/
Long pushStoreToLiePin(String shopCode);
/**
* 推送门店人员到对应门店
* @param shopCode
* @param mobile
* @param userName
* @return
*/
Long pushStoreEmpToLiePin(String shopCode,String mobile,String userName);
}

View File

@@ -4,12 +4,9 @@ import com.cool.store.context.CurrentUserHolder;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dto.AmountDTO;
import com.cool.store.entity.LinePayDO;
import com.cool.store.request.FranchiseFeePayOnlineRequest;
import com.cool.store.request.LinePaySubmitRequest;
import com.cool.store.request.xgj.OnlinePayInfoRequest;
import com.cool.store.request.xgj.ReceiptCallBackRequest;
import com.cool.store.response.FranchiseFeePayInfoResponse;
import com.cool.store.response.FranchiseFeePayOnlineResponse;
import com.cool.store.response.bigdata.ApiResponse;
import com.cool.store.vo.LinePayVO;
import com.cool.store.vo.PartnerUserInfoVO;
@@ -54,13 +51,7 @@ public interface LinePayService {
*/
Boolean pushPayInfo(Long shopId, LinePayDO linePayDO);
Boolean onlinePushPayInfo(Long shopId, LinePayDO linePayDO);
ApiResponse<Boolean> ReceiptCallBack(ReceiptCallBackRequest request);
FranchiseFeePayOnlineResponse franchiseFeePayOnline(FranchiseFeePayOnlineRequest request, String userId);
ApiResponse<Boolean> changeOnlinePayInfo(OnlinePayInfoRequest onlinePayInfoRequest);
Boolean cancelFranchiseFeePayOnline(Long id,String userId);
}

View File

@@ -3,7 +3,6 @@ package com.cool.store.service;
import com.cool.store.dto.BatchStatusRefreshDTO;
import com.cool.store.dto.StatusRefreshDTO;
import com.cool.store.request.xgj.FranchiseFeeCallBackRequest;
import com.cool.store.request.xgj.OnlinePayInfoRequest;
import com.cool.store.request.xgj.ReceiptCallBackRequest;
import com.cool.store.response.bigdata.ApiResponse;
@@ -22,25 +21,9 @@ public interface OpenApiService {
*/
Boolean statusRefresh(StatusRefreshDTO statusRefreshDTO);
/**
* 线下支付收款单 回调
* @param request
* @return
*/
ApiResponse<Boolean> changeReceiptStatus(ReceiptCallBackRequest request);
/**
* 账单收款状态及缴款金额
* @param request
* @return
*/
ApiResponse<Boolean> changePaymentStatus(FranchiseFeeCallBackRequest request);
/**
* 线上支付 回调收款单信息 包括交易流水号 支付时间等
* @param onlinePayInfoRequest
* @return
*/
ApiResponse<Boolean> changeOnlinePayInfo(OnlinePayInfoRequest onlinePayInfoRequest);
}

View File

@@ -7,6 +7,8 @@ import com.cool.store.vo.OpeningOperationPlanListVO;
import com.cool.store.vo.OpeningOperationPlanVO;
import com.github.pagehelper.PageInfo;
import java.time.LocalDate;
import java.util.List;
/**
* @Auther: WangShuo

View File

@@ -21,13 +21,4 @@ public interface OperationLogService {
List<AuditInfoResponse> getAuditInfo(Long shopId,List<Integer> shopSubStageList);
Boolean batchUpdateProcessed( List<OperationLogDO> operationLogs,Long audit , String userId, String reason);
/**
* 后期新增的阶段数据 对于处在阶段中的数据 可能没有提前生成审批记录 直接插入数据 且是审批完成状态
* @param subStageStatusEnum
* @param audit
* @param userId
* @param reason
*/
Boolean handleApproveTimeNoDate(Long shopId,ShopSubStageStatusEnum subStageStatusEnum,Long audit , String userId, String reason);
}

View File

@@ -304,7 +304,7 @@ public interface PointService {
* @param request
* @return
*/
Integer uploadRentContract(AddRentContractRequest request,String userId,String userName);
Integer uploadRentContract(AddRentContractRequest request);
/**
* 获取租赁合同详情

View File

@@ -42,11 +42,6 @@ public interface PreparationService {
*/
void contractAndBuildStoreCompletion(Long shopId);
/**
* 装修完成
* @param shopId
*/
void decorationCompletion(Long shopId) ;
/**
* 建店完成

View File

@@ -4,9 +4,7 @@ import com.cool.store.dto.*;
import com.cool.store.dto.contract.ContractCallbackDTO;
import com.cool.store.request.AuditRequest;
import com.cool.store.request.ZxjpApiRequest;
import com.cool.store.request.xgj.CancelPayRequest;
import com.cool.store.request.xgj.PushFranchiseFeeRequest;
import com.cool.store.request.xgj.ReceiptOnlineRequest;
import com.cool.store.request.xgj.ReceiptRequest;
import com.cool.store.response.XgjAccessTokenDTO;
@@ -40,12 +38,6 @@ public interface PushService {
* @return
*/
Boolean pushReceiptToXGJ(ReceiptRequest receiptRequest);
/**
* 推送线上支付 收款单到新管家
* @param receiptRequest
* @return
*/
Boolean pushOnlineReceiptToXGJ(ReceiptOnlineRequest receiptRequest);
/**
* 推送数据到下游系统 POS

View File

@@ -1,22 +0,0 @@
package com.cool.store.service;
import com.cool.store.request.ReceivingBankListRequest;
import com.cool.store.request.ReceivingBankRequest;
import com.cool.store.response.ReceivingBankResponse;
import com.github.pagehelper.PageInfo;
/**
* @Author: WangShuo
* @Date: 2025/06/18/17:53
* @Version 1.0
* @注释:
*/
public interface ReceivingBankService {
Integer submit(ReceivingBankRequest request,String userId);
PageInfo<ReceivingBankResponse> getByFranchiseBrandAndRegionId(ReceivingBankListRequest request);
//获取该门店的收款方信息
ReceivingBankResponse getByShopId(Long shopId);
}

View File

@@ -62,8 +62,4 @@ public interface StoreService {
*/
List<StoreUserDTO> getStoreUserPositionList(String storeId, String userName);
/**
* 处理门店报表
*/
void saveStoreReport(String date);
}

View File

@@ -2,11 +2,6 @@ package com.cool.store.service;
import com.cool.store.dto.FoodTokenDTO;
import com.cool.store.dto.recipe.RecipeSpLaunchDTO;
import com.cool.store.dto.GetAccessTokenDTO;
import com.cool.store.dto.food.DishesDTO;
import java.util.List;
import com.cool.store.dto.store.StoreUserPositionDTO;
import com.cool.store.dto.store.StoreUserUpdateDTO;
import com.cool.store.request.recipe.RevenueDataRequest;
import com.cool.store.request.recipe.SalesVolumeDayRequest;
@@ -31,16 +26,6 @@ public interface ThirdFoodService {
*/
String getFoodToken(FoodTokenDTO dto);
/**
* 查询已购菜品
* @param dto
* @return
*/
List<DishesDTO> getPurchasedDishesList(FoodTokenDTO dto);
List<DishesDTO> getMyDesignDishesList(FoodTokenDTO dto);
/**
* 推送门店人员信息
* @param storeUserUpdateDTOList

View File

@@ -1,53 +0,0 @@
package com.cool.store.service;
import com.cool.store.request.liepin.AddStoreEmpRequest;
import com.cool.store.request.liepin.AddStoreRequest;
import com.cool.store.request.liepin.GetAccessTokenRequest;
import com.cool.store.request.liepin.GetPathRequest;
import com.cool.store.response.liepin.PathResponse;
/**
* @Author suzhuhong
* @Date 2025/5/20 15:33
* @Version 1.0
*/
public interface ThirdLiePinService {
/**
* 有效期30天,调用接口时拼接在链接后面
* @param request
* @return
*/
String getAccessToken(GetAccessTokenRequest request);
/**
* 新增门店
* @param addStoreRequest
* @return
*/
Long addStoreToLiePin(AddStoreRequest addStoreRequest);
/**
* 新增门店成员
* @param addStoreEmpRequest
* @return
*/
Long addStoreEmp(AddStoreEmpRequest addStoreEmpRequest);
/**
* 获取小程序调整链接
* @param getPathRequest
* @return
*/
PathResponse getPath(GetPathRequest getPathRequest);
/**
* 上传图片返回地址 只有该地址薪超人能解析
* @param ossUrl
* @return
*/
String getFilePath(String ossUrl);
}

View File

@@ -1,12 +1,10 @@
package com.cool.store.service;
import com.cool.store.dto.BigRegionUserListDTO;
import com.cool.store.dto.UserDTO;
import com.cool.store.entity.EnterpriseUserDO;
import com.cool.store.entity.UserAuthMappingDO;
import com.cool.store.enums.UserRoleEnum;
import com.cool.store.request.SysRoleRequest;
import com.cool.store.response.bigdata.ApiResponse;
import com.github.pagehelper.PageInfo;
import java.util.List;
@@ -134,10 +132,4 @@ public interface UserAuthMappingService {
* @return
*/
List<EnterpriseUserDO> findUserListByRole(SysRoleRequest request,Boolean flag);
/**
* 查询所有大区指定角色的 用户
* @return
*/
ApiResponse<List<BigRegionUserListDTO>> getAllBigRegionSpecialRoleUserList(String storeCode, UserRoleEnum userRoleEnum);
}

View File

@@ -43,13 +43,4 @@ public interface WechatMiniAppService {
* @return 用户信息VO
*/
PartnerUserInfoVO getUserInfoByShortTermToken(String token);
/**
* 生成微信小程序二维码
* @param page 页面路径,路径前不带/
* @param scene 参数,必填
* @param width 二维码的宽度
* @return 二维码图片路径
*/
String createQrCode(String page, String scene, String width);
}

View File

@@ -1,270 +0,0 @@
package com.cool.store.service;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.net.url.UrlQuery;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.dto.liepin.XbbAppInfo;
import com.cool.store.dto.liepin.XbbEncryptedData;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.liepin.XbbGetRequest;
import com.cool.store.request.liepin.XbbPostRequest;
import com.cool.store.response.liepin.XbbResponse;
import com.cool.store.response.oppty.OpportunityApiResponse;
import com.cool.store.utils.hire.XbbAesUtil;
import com.cool.store.utils.hire.XbbSignatureInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
/**
* @author sha.li
* @since 2025-03-28 14:53
*/
@Slf4j
public class XbbApiCaller {
private ObjectMapper objectMapper;
private final String domain;
private final String appId;
private final String secretKey;
private final String aesSecretKey;
public XbbApiCaller(String domain, String appId, String secretKey, String aesSecretKey,ObjectMapper objectMapper) {
this.domain = domain;
this.appId = appId;
this.secretKey = secretKey;
this.aesSecretKey = aesSecretKey;
this.objectMapper = objectMapper;
}
/**
* 发送get请求
*/
public <T> XbbResponse<T> get(XbbGetRequest request,
Class<T> responseDataType,String token) {
XbbSignatureInfo xbbSignatureInfo = XbbSignatureInfo.createGet();
xbbSignatureInfo.setAppId(getAppId());
xbbSignatureInfo.setUri(request.getUri());
xbbSignatureInfo.setQueryString(UrlQuery.of(request.getQueryParam()).toString());
xbbSignatureInfo.setRequestPayload(null);
xbbSignatureInfo.setNonce(UUID.randomUUID().toString(true));
xbbSignatureInfo.setTimestamp(System.currentTimeMillis());
xbbSignatureInfo.setAesSecretkey(getAesSecretKey());
String getUrlTemplate = "{domain}{uri}{queryString}";
String url = StrUtil.format(getUrlTemplate, Dict.of(
"domain", getDomain(),
"uri", request.getUri(),
"queryString", StrUtil.isBlank(xbbSignatureInfo.getQueryString()) ? "" : "?" + xbbSignatureInfo.getQueryString()
));
HttpRequest httpRequest = HttpUtil.createGet(url).timeout(request.getRequestTimeout());
return sendRequest("",token, responseDataType, httpRequest, xbbSignatureInfo, request.isResponseDecrypt());
}
/**
* 发送post请求
*/
public <T> XbbResponse<T> post(XbbPostRequest request, Class<T> responseDataType,String token) {
String requestBody;
if (request.isRequestEncrypt()) {
Dict encryptData = Dict.of("encrypt_data", XbbAesUtil.encrypt(request.getJsonString(), getAesSecretKey()));
requestBody = JSONUtil.toJsonStr(encryptData);
} else {
requestBody = request.getJsonString();
}
XbbSignatureInfo xbbSignatureInfo = XbbSignatureInfo.createPost();
xbbSignatureInfo.setAppId(getAppId());
xbbSignatureInfo.setUri(request.getUri());
xbbSignatureInfo.setQueryString(UrlQuery.of(request.getQueryParam()).toString());
xbbSignatureInfo.setRequestPayload(requestBody.getBytes(StandardCharsets.UTF_8));
xbbSignatureInfo.setNonce(UUID.randomUUID().toString(true));
xbbSignatureInfo.setTimestamp(System.currentTimeMillis());
xbbSignatureInfo.setAesSecretkey(getAesSecretKey());
String postUrlTemplate = "{domain}{uri}{queryString}";
String url = StrUtil.format(postUrlTemplate, Dict.of(
"domain", getDomain(),
"uri", request.getUri(),
"queryString", StrUtil.isBlank(xbbSignatureInfo.getQueryString()) ? "" : "?" + xbbSignatureInfo.getQueryString()
));
HttpRequest httpRequest = HttpUtil.createPost(url).timeout(request.getRequestTimeout());
httpRequest.body(requestBody);
log.info("url:{} , body:{} ", url,JSONObject.toJSONString(requestBody));
return sendRequest(requestBody,token, responseDataType, httpRequest, xbbSignatureInfo, request.isResponseDecrypt());
}
private <T> XbbResponse<T> sendRequest(String requestBody,
String token,
Class<T> responseDataType,
HttpRequest httpRequest,
XbbSignatureInfo xbbSignatureInfo,
boolean responseDecrypt) {
httpRequest.header("Authorization", "Bearer " + token);
httpRequest.header("Content-Type", "application/json");
httpRequest.header("X-App-Id", xbbSignatureInfo.getAppId());
httpRequest.header("X-Signature", xbbSignatureInfo.toSignature());
httpRequest.header("X-SignatureMethod", "SHA256");
httpRequest.header("X-Nonce", xbbSignatureInfo.getNonce());
httpRequest.header("X-Timestamp", String.valueOf(xbbSignatureInfo.getTimestamp()));
log.info("heads:{} ", JSONObject.toJSONString(httpRequest.headers()));
// String post = generateCurlCommand("POST", httpRequest.getUrl(), httpRequest.headers(), requestBody);
// log.info("===={}",post);
try (HttpResponse httpResponse = httpRequest.execute()) {
int httpResponseStatus = httpResponse.getStatus();
//状态码校验
if (httpResponseStatus != 200) {
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,"状态码"+httpResponseStatus);
}
String responseBody = httpResponse.body();
logResponse(httpRequest.getUrl(),httpResponse.getStatus(),responseBody);
if (responseDecrypt) {
XbbResponse<XbbEncryptedData> response = JSONUtil.toBean(responseBody, new TypeReference<XbbResponse<XbbEncryptedData>>() {
}, false);
String dataStr = decrypt(response.getData().getEncryptData());
T data = JSONUtil.toBean(dataStr, responseDataType);
return new XbbResponse<T>()
.setCode(response.getCode())
.setMsg(response.getMsg())
.setSuccess(response.isSuccess())
.setData(data);
}
JavaType javaType = objectMapper.getTypeFactory()
.constructParametricType(XbbResponse.class, responseDataType);
XbbResponse<T> apiResponse = null;
try {
apiResponse = objectMapper.readValue(responseBody, javaType);
} catch (Exception e) {
log.info("数据转换异常:{}",e.getMessage());
}
//业务码校验
if (apiResponse.getCode() != 2000) {
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,apiResponse.getMsg());
}
return apiResponse;
}
}
public static String generateCurlCommand(String method,
String url,
Map<String, List<String>> headers,
String body) {
StringBuilder curlCommand = new StringBuilder("curl -X ").append(method.toUpperCase()).append(" \\\n");
// Add URL
curlCommand.append(" '").append(url).append("' \\\n");
// Add headers
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
curlCommand.append(" -H '")
.append(entry.getKey())
.append(": ")
.append(entry.getValue().get((0)))
.append("' \\\n");
}
// Add body if present
if (body != null && !body.isEmpty()) {
// Escape single quotes in the body
String escapedBody = body.replace("'", "'\\''");
curlCommand.append(" -d '").append(escapedBody).append("'");
}
return curlCommand.toString();
}
/**
* 记录请求日志
*/
private void logRequest(String url, Object requestBody) {
if (log.isInfoEnabled()) {
try {
log.info("\n======= 请求开始 =======\n" +
"API地址: {}\n" +
"请求参数: {}\n" +
"======= 请求结束 =======",
url,
objectMapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(requestBody));
} catch (JsonProcessingException e) {
log.warn("日志JSON序列化失败", e);
}
}
}
/**
* 记录响应日志
*/
private void logResponse(String url, int statusCode, String responseBody) {
if (log.isInfoEnabled()) {
try {
// 尝试美化JSON输出
Object json = objectMapper.readValue(responseBody, Object.class);
String prettyResponse = objectMapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(json);
log.info("\n======= 响应开始 =======\n" +
"API地址: {}\n" +
"HTTP状态码: {}\n" +
"响应内容: {}\n" +
"======= 响应结束 =======",
url,
statusCode,
prettyResponse);
} catch (Exception e) {
// 非JSON响应或解析失败时直接输出原始内容
log.info("\n======= 响应开始 =======\n" +
"API地址: {}\n" +
"HTTP状态码: {}\n" +
"原始响应: {}\n" +
"======= 响应结束 =======",
url,
statusCode,
responseBody);
}
}
}
private String encrypt(String data) {
return XbbAesUtil.encrypt(data, getAesSecretKey());
}
private String decrypt(String encryptData) {
return XbbAesUtil.decrypt(encryptData, getAesSecretKey());
}
public String getDomain() {
return domain;
}
public String getAppId() {
return appId;
}
public String getSecretKey() {
return secretKey;
}
public String getAesSecretKey() {
return aesSecretKey;
}
}

View File

@@ -1,31 +0,0 @@
package com.cool.store.service.approval;
import com.cool.store.entity.approval.CommonApprovalLogDO;
import com.cool.store.vo.approval.ApprovalGroupedVO;
import java.util.List;
public interface CommonApprovalLogService {
/**
* 插入单条审批记录(提交场景)
*/
void insertSingleRecord(String applicationNo, String handleUserId, String handleUserName, String nodeCode, String nodeName);
/**
* 批量插入审批记录(同一批次)
*/
void batchInsertApprovalRecords(String applicationNo, List<CommonApprovalLogDO> records);
/**
* 更新节点审批状态(权限校验 + 可选生成下一节点)
*/
void updateNodeApprovalStatus(String applicationNo, String currentNodeCode,
String result, String handleUserId, String handleUserName,
String comment, boolean generateNextNode, Long regionId);
/**
* 查询某个申请的所有审批记录(按版本号分组)
*/
ApprovalGroupedVO getApprovalRecordsGroupedByVersion(String applicationNo);
}

View File

@@ -1,222 +0,0 @@
package com.cool.store.service.approval.impl;
import com.cool.store.dao.approval.CommonApprovalLogDAO;
import com.cool.store.dao.EnterpriseUserDAO;
import com.cool.store.entity.EnterpriseUserDO;
import com.cool.store.entity.approval.CommonApprovalLogDO;
import com.cool.store.enums.UserRoleEnum;
import com.cool.store.enums.approval.ApprovalResultEnum;
import com.cool.store.enums.renewal.RenewalNodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.service.UserAuthMappingService;
import com.cool.store.service.approval.CommonApprovalLogService;
import com.cool.store.utils.GenerateNoUtil;
import com.cool.store.utils.poi.DateUtils;
import com.cool.store.vo.approval.ApprovalBatchVO;
import com.cool.store.vo.approval.ApprovalGroupedVO;
import com.cool.store.vo.approval.ApprovalHandleVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
@Slf4j
public class CommonApprovalLogServiceImpl implements CommonApprovalLogService {
private final CommonApprovalLogDAO commonApprovalLogDAO;
private final UserAuthMappingService userAuthMappingService;
private final EnterpriseUserDAO enterpriseUserDAO;
@Override
public void insertSingleRecord(String applicationNo, String handleUserId, String handleUserName, String nodeCode, String nodeName) {
commonApprovalLogDAO.addSubmitRecord(applicationNo, handleUserId, handleUserName, nodeCode, nodeName);
}
@Override
public void batchInsertApprovalRecords(String applicationNo, List<CommonApprovalLogDO> records) {
if (CollectionUtils.isEmpty(records)) {
return;
}
Long version = GenerateNoUtil.generateVersion();
records.forEach(r -> {
r.setApplicationNo(applicationNo);
r.setVersion(version);
r.setStatus("2");
r.setSubmitType(1);
r.setOperateTime(new Date());
r.setDeleted(0);
});
commonApprovalLogDAO.batchInsertApprovalRecords(records);
}
@Override
@Transactional
public void updateNodeApprovalStatus(String applicationNo, String currentNodeCode,
String result, String handleUserId, String handleUserName,
String comment, boolean generateNextNode, Long regionId) {
// 获取当前节点所有待处理记录
List<CommonApprovalLogDO> pendingRecords = commonApprovalLogDAO.getPendingByApplicationNoAndNodeCode(applicationNo, currentNodeCode);
// 检查当前操作人是否在审批列表中,如果不在则新增
boolean isCurrentUserInList = false;
if (CollectionUtils.isNotEmpty(pendingRecords)) {
isCurrentUserInList = pendingRecords.stream()
.anyMatch(record -> handleUserId.equals(record.getHandleUserId()));
}
if (!isCurrentUserInList) {
// 新增当前操作人的审批记录
String currentNodeCodeName = RenewalNodeEnum.getNameByCode(currentNodeCode);
Long version = null ;
if (CollectionUtils.isNotEmpty(pendingRecords)){
version = pendingRecords.get(0).getVersion();
}
CommonApprovalLogDO newRecord = CommonApprovalLogDO.builder()
.applicationNo(applicationNo)
.nodeCode(currentNodeCode)
.nodeName(currentNodeCodeName)
.handleUserId(handleUserId)
.handleUserName(handleUserName)
.status("2")
.submitType(1)
.deleted(0)
.operateTime(new Date())
.build();
commonApprovalLogDAO.addApproveRecord(newRecord.getApplicationNo(), newRecord.getNodeCode(),
newRecord.getNodeName(), newRecord.getHandleUserId(), newRecord.getHandleUserName(),version);
// 重新获取待处理记录
pendingRecords = commonApprovalLogDAO.getPendingByApplicationNoAndNodeCode(applicationNo, currentNodeCode);
}
// 当前节点所有审批人标记为已处理
if (CollectionUtils.isNotEmpty(pendingRecords)) {
Date now = new Date();
for (CommonApprovalLogDO record : pendingRecords) {
record.setStatus("1");
record.setComment(comment);
record.setOperateTime(now);
// 仅当前操作人记录实际处理人信息
if (record.getHandleUserId() != null && record.getHandleUserId().equals(handleUserId)) {
record.setResult(result);
}
}
commonApprovalLogDAO.batchUpdateRecords(pendingRecords);
}
// 通过时生成下一节点
if (generateNextNode && ApprovalResultEnum.PASS.getResult().equals(result)) {
String nextNodeCode = RenewalNodeEnum.getNextNode(currentNodeCode);
if (nextNodeCode != null) {
RenewalNodeEnum nextNode = RenewalNodeEnum.getByCode(nextNodeCode);
if (nextNode != null) {
// 获取下一节点审批人
List<String> auditUserIds = getAuditUserIds(regionId, nextNodeCode);
List<CommonApprovalLogDO> nextRecords = new ArrayList<>();
for (String userId : auditUserIds) {
EnterpriseUserDO user = enterpriseUserDAO.getUserInfoById(userId);
String userName = user != null ? user.getName() : "";
CommonApprovalLogDO record = CommonApprovalLogDO.builder()
.nodeCode(nextNodeCode)
.nodeName(nextNode.getName())
.handleUserId(userId)
.handleUserName(userName)
.build();
nextRecords.add(record);
}
if (CollectionUtils.isNotEmpty(nextRecords)) {
batchInsertApprovalRecords(applicationNo, nextRecords);
}
}
}
}
}
@Override
public ApprovalGroupedVO getApprovalRecordsGroupedByVersion(String applicationNo) {
List<CommonApprovalLogDO> allRecords = commonApprovalLogDAO.getByApplicationNo(applicationNo);
ApprovalGroupedVO result = new ApprovalGroupedVO();
result.setApplicationNo(applicationNo);
if (CollectionUtils.isEmpty(allRecords)) {
result.setBatches(new ArrayList<>());
return result;
}
// 按version分组
Map<Long, List<CommonApprovalLogDO>> versionGroups = allRecords.stream()
.collect(Collectors.groupingBy(CommonApprovalLogDO::getVersion, LinkedHashMap::new, Collectors.toList()));
// 按nodeCode分组构建批次
List<ApprovalBatchVO> batches = new ArrayList<>();
for (Map.Entry<Long, List<CommonApprovalLogDO>> versionEntry : versionGroups.entrySet()) {
Long version = versionEntry.getKey();
List<CommonApprovalLogDO> versionRecords = versionEntry.getValue();
// 按nodeCode分组
Map<String, List<CommonApprovalLogDO>> nodeGroups = versionRecords.stream()
.collect(Collectors.groupingBy(CommonApprovalLogDO::getNodeCode, LinkedHashMap::new, Collectors.toList()));
for (Map.Entry<String, List<CommonApprovalLogDO>> nodeEntry : nodeGroups.entrySet()) {
String nodeCode = nodeEntry.getKey();
List<CommonApprovalLogDO> nodeRecords = nodeEntry.getValue();
ApprovalBatchVO batchVO = new ApprovalBatchVO();
batchVO.setVersion(version);
batchVO.setNodeCode(nodeCode);
// 取第一个记录的nodeName
batchVO.setNodeName(nodeRecords.get(0).getNodeName());
List<ApprovalHandleVO> handleList = nodeRecords.stream().map(r -> {
ApprovalHandleVO handleVO = new ApprovalHandleVO();
handleVO.setHandleUserId(r.getHandleUserId());
handleVO.setHandleUserName(r.getHandleUserName());
handleVO.setStatus(r.getStatus());
handleVO.setResult(r.getResult());
handleVO.setComment(r.getComment());
handleVO.setSubmitType(r.getSubmitType());
handleVO.setOperateTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,r.getOperateTime()));
return handleVO;
}).collect(Collectors.toList());
batchVO.setHandleUserIdList(handleList);
batches.add(batchVO);
}
}
result.setBatches(batches);
return result;
}
/**
* 根据节点code获取对应的审批人ID列表
*/
private List<String> getAuditUserIds(Long regionId, String nodeCode) {
UserRoleEnum roleEnum;
switch (nodeCode) {
case "20":
roleEnum = UserRoleEnum.SUPERVISION;
break;
case "25":
roleEnum = UserRoleEnum.OPERATION_GENERAL_CONSULTANT;
break;
case "30":
roleEnum = UserRoleEnum.ENGINEER_DEP_MANAGER;
break;
default:
return new ArrayList<>();
}
List<EnterpriseUserDO> users = userAuthMappingService.getAllUserByRoleEnumAndRegionId(roleEnum, regionId);
return ListUtils.emptyIfNull(users).stream()
.map(EnterpriseUserDO::getUserId)
.distinct()
.collect(Collectors.toList());
}
}

View File

@@ -2,14 +2,14 @@ package com.cool.store.service.close;
import com.cool.store.dto.close.CloseStoreMkUserDTO;
import com.cool.store.dto.xgj.XgjBranchBankDTO;
import com.cool.store.dto.xgj.XgjPartnerPageDTO;
import com.cool.store.entity.CloseStoreRefundInfoDO;
import com.cool.store.request.close.refund.*;
import com.cool.store.request.xgj.XgjBankQueryRequest;
import com.cool.store.request.close.refund.CloseStoreRefundAddRequest;
import com.cool.store.request.close.refund.CloseStoreRefundQueryRequest;
import com.cool.store.request.close.refund.CloseStoreRefundSkipRequest;
import com.cool.store.request.close.refund.CloseStoreRefundUpdateRequest;
import com.cool.store.dto.xgj.XgjPartnerPageDTO;
import com.cool.store.entity.CloseStoreRefundInfoDO;
import com.cool.store.request.close.refund.*;
import com.cool.store.request.xgj.XgjBankQueryRequest;
import com.cool.store.vo.close.refund.CloseStoreRefundDetailVO;
import com.cool.store.vo.close.refund.CloseStoreRefundListVO;
import com.cool.store.vo.close.refund.CloseStoreRefundSimpleVO;

View File

@@ -20,11 +20,6 @@ import com.cool.store.enums.close.CloseStoreSubStageStatusEnum;
import com.cool.store.enums.close.RefundPayStatusEnum;
import com.cool.store.enums.close.XgjRefundPayStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.close.refund.*;
import com.cool.store.request.xgj.XgjPartnerQueryRequest;
import com.cool.store.request.xgj.XgjPaymentRequest;
import com.cool.store.request.xgj.XgjReimburseRequest;
import com.cool.store.request.xgj.XgjSavePartnerRequest;
import com.cool.store.request.close.refund.CloseStoreRefundAddRequest;
import com.cool.store.request.close.refund.CloseStoreRefundQueryRequest;
import com.cool.store.request.close.refund.CloseStoreRefundSkipRequest;

View File

@@ -503,8 +503,7 @@ public class CloseUpServiceImpl implements CloseUpService {
List<CloseUpPlatformDO> unClosePlatformList = list.stream()
.filter(platformDO -> platformDO.getStatus().equals(0)
&& platformDO.getType().equals(1)
&& !(new Date()).before(platformDO.getTaskStartDate())
&& Objects.nonNull(CloseUpPlatformEnum.getPlatformCodeByCode(platformDO.getCode())))
&& !(new Date()).before(platformDO.getTaskStartDate()))
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(unClosePlatformList)) {
log.info("未处理的自动关闭平台为空");

View File

@@ -1,16 +0,0 @@
package com.cool.store.service.contract;
import com.cool.store.request.contract.ContractMasterQueryRequest;
import com.cool.store.vo.contract.ContractMasterDetailVO;
import com.cool.store.vo.contract.ContractMasterListVO;
import com.github.pagehelper.PageInfo;
import org.springframework.web.multipart.MultipartFile;
public interface ContractMasterService {
PageInfo<ContractMasterListVO> queryContractMasterList(ContractMasterQueryRequest request);
ContractMasterDetailVO getContractMasterDetail(Long contractId);
Boolean importContractAndCost(MultipartFile file);
}

View File

@@ -1,237 +0,0 @@
package com.cool.store.service.contract.impl;
import com.alibaba.excel.EasyExcel;
import com.cool.store.constants.RedisConstant;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.EnterpriseUserDAO;
import com.cool.store.dao.StoreDao;
import com.cool.store.dao.contract.ContractCostDAO;
import com.cool.store.dao.contract.ContractMasterDAO;
import com.cool.store.entity.ImportTaskDO;
import com.cool.store.entity.EnterpriseUserDO;
import com.cool.store.entity.StoreDO;
import com.cool.store.entity.contract.ContractCostDO;
import com.cool.store.entity.contract.ContractMasterDO;
import com.cool.store.enums.FileTypeEnum;
import com.cool.store.enums.ImportTaskStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.ImportTaskMapper;
import com.cool.store.request.contract.ContractImportRowDTO;
import com.cool.store.request.contract.ContractMasterQueryRequest;
import com.cool.store.service.contract.ContractMasterService;
import com.cool.store.service.contract.listener.ContractImportListener;
import com.cool.store.utils.RedisUtilPool;
import com.cool.store.utils.UUIDUtils;
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.contract.ContractCostVO;
import com.cool.store.vo.contract.ContractMasterDetailVO;
import com.cool.store.vo.contract.ContractMasterListVO;
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.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import javax.annotation.Resource;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import static com.cool.store.utils.poi.DateUtils.SPECIAL_DATE_START_1;
@Service
@RequiredArgsConstructor
@Slf4j
public class ContractMasterServiceImpl implements ContractMasterService {
private final ContractMasterDAO contractMasterDAO;
private final ContractCostDAO contractCostDAO;
private final EnterpriseUserDAO enterpriseUserDAO;
private final ImportTaskMapper importTaskMapper;
private final RedisUtilPool redisUtilPool;
private final EasyExcelUtil easyExcelUtil;
private final StoreDao storeDao;
@Resource(name = "generalThreadPool")
private ThreadPoolTaskExecutor executor;
@Value("${mybatis.configuration.variables.enterpriseId}")
private String eid;
@Override
public PageInfo<ContractMasterListVO> queryContractMasterList(ContractMasterQueryRequest request) {
// 门店名称/编码模糊查询时需要JOIN门店表
if (request.getStoreNameOrCode() != null && !request.getStoreNameOrCode().isEmpty()) {
request.setQueryStore(true);
}
PageHelper.startPage(request.getPageNum(), request.getPageSize());
List<ContractMasterListVO> list = contractMasterDAO.queryContractMasterList(request);
PageInfo<ContractMasterListVO> pageInfo = new PageInfo<>(list);
// 批量查询创建人姓名
fill(pageInfo.getList());
return pageInfo;
}
@Override
public ContractMasterDetailVO getContractMasterDetail(Long contractId) {
ContractMasterDO contractDO = contractMasterDAO.getById(contractId);
if (contractDO == null) {
throw new ServiceException(500, "合同不存在");
}
ContractMasterDetailVO detailVO = new ContractMasterDetailVO();
detailVO.setContractId(contractDO.getId());
detailVO.setContractType(contractDO.getContractType());
detailVO.setContractNo(contractDO.getContractNo());
detailVO.setStoreId(contractDO.getStoreId());
detailVO.setStoreCode(contractDO.getStoreCode());
detailVO.setBrandName(contractDO.getBrandName());
detailVO.setSource(contractDO.getSource());
detailVO.setSignForm(contractDO.getSignForm());
detailVO.setContractYears(contractDO.getContractYears());
detailVO.setStartDate(contractDO.getStartDate());
detailVO.setEndDate(contractDO.getEndDate());
detailVO.setContractStatus(contractDO.getContractStatus());
detailVO.setCurrency(contractDO.getCurrency());
detailVO.setSignDate(contractDO.getSignDate());
detailVO.setRelatedContractNo(contractDO.getRelatedContractNo());
detailVO.setRemark(contractDO.getRemark());
detailVO.setCreatedTime(contractDO.getCreatedTime());
// 查询创建人姓名
if (contractDO.getCreateUserId() != null) {
EnterpriseUserDO user = enterpriseUserDAO.getUserInfoById(contractDO.getCreateUserId());
if (user != null) {
detailVO.setCreateUserName(user.getName());
}
}
// 查询费用信息
List<ContractCostDO> costList = contractCostDAO.queryByContractNo(contractDO.getContractNo());
if (CollectionUtils.isNotEmpty(costList)) {
ContractCostDO cost = costList.get(0);
ContractCostVO costVO = new ContractCostVO();
costVO.setJoinFeeAmount(cost.getJoinFeeAmount());
costVO.setJoinFeeFrequencyYears(cost.getJoinFeeFrequencyYears());
costVO.setJoinFeeDiscountAmount(cost.getJoinFeeDiscountAmount());
costVO.setJoinFeeDiscountReason(cost.getJoinFeeDiscountReason());
costVO.setBrandUsageFeeAmount(cost.getBrandUsageFeeAmount());
costVO.setBrandUsageFeeFrequencyYears(cost.getBrandUsageFeeFrequencyYears());
costVO.setBrandManagementFeeAmount(cost.getBrandManagementFeeAmount());
costVO.setBrandManagementFeeFrequencyYears(cost.getBrandManagementFeeFrequencyYears());
costVO.setDesignFeeAmount(cost.getDesignFeeAmount());
costVO.setSystemUsageFeeAmount(cost.getSystemUsageFeeAmount());
costVO.setPerformanceBondAmount(cost.getPerformanceBondAmount());
detailVO.setCostList(Collections.singletonList(costVO));
}
return detailVO;
}
@Override
@Transactional
public Boolean importContractAndCost(MultipartFile file) {
final String lockKey = RedisConstant.CONTRACT_IMPORT_LOCK;
boolean lock = redisUtilPool.setNxExpire(lockKey, UUIDUtils.get32UUID(), 30 * 60 * 1000);
if (!lock) {
throw new ServiceException(500, "存在正在进行的导入任务");
}
ImportTaskDO importTaskDO = new ImportTaskDO();
importTaskDO.setFileName(file.getOriginalFilename());
importTaskDO.setFileType(FileTypeEnum.CONTRACT_IMPORT.getFileType());
importTaskDO.setIsImport(true);
importTaskDO.setStatus(ImportTaskStatusEnum.PROGRESS.getCode());
importTaskDO.setCreateUserId(CurrentUserHolder.getUserId());
importTaskDO.setCreateName(CurrentUserHolder.getUser().getName());
importTaskDO.setCreateTime(System.currentTimeMillis());
importTaskMapper.insert(eid, importTaskDO);
LoginUserInfo user = CurrentUserHolder.getUser();
try {
byte[] excelBytes = file.getBytes();
executor.execute(() -> importContract(excelBytes, importTaskDO, user));
} catch (Exception e) {
log.error("导入失败", e);
}
return true;
}
private void importContract(byte[] excelBytes, ImportTaskDO importTaskDO, LoginUserInfo user) {
List<String> errorList = new ArrayList<>();
AtomicInteger successNum = new AtomicInteger();
AtomicInteger totalNum = new AtomicInteger();
try {
// 合同导入(包含费用)
EasyExcel.read(new ByteArrayInputStream(excelBytes), ContractImportRowDTO.class,
new ContractImportListener(contractMasterDAO, contractCostDAO, totalNum, successNum, errorList))
.sheet(0)
.doRead();
} catch (Exception e) {
log.error("合同导入失败", e);
} finally {
try {
final String lockKey = RedisConstant.CONTRACT_IMPORT_LOCK;
String value = redisUtilPool.getString(lockKey);
if (org.apache.commons.lang3.StringUtils.isNotBlank(value)) {
redisUtilPool.delKey(lockKey);
}
} catch (Exception ex) {
log.error("释放合同导入锁异常", ex);
}
}
importTaskDO.setStatus(totalNum.get() == successNum.get() ? ImportTaskStatusEnum.SUCCESS.getCode() : ImportTaskStatusEnum.PART_ERROR.getCode());
importTaskDO.setTotalNum(totalNum.get());
importTaskDO.setSuccessNum(successNum.get());
if (CollectionUtils.isNotEmpty(errorList)) {
try {
String url = easyExcelUtil.exportExcel(String.class, errorList, null,
FileTypeEnum.CONTRACT_ERROR_EXPORT.getDesc() + DateUtils.parseDateToStr(SPECIAL_DATE_START_1, new Date()),
FileTypeEnum.CONTRACT_ERROR_EXPORT.getDesc() + DateUtils.parseDateToStr(SPECIAL_DATE_START_1, new Date()));
importTaskDO.setFileUrl(url);
} catch (Exception e) {
log.info("导出失败列表失败 errorList:{}", errorList);
}
}
importTaskMapper.update(eid, importTaskDO);
}
/**
* 批量填充
*/
private void fill(List<ContractMasterListVO> list) {
if (CollectionUtils.isEmpty(list)) {
return;
}
List<String> userIds = list.stream()
.map(ContractMasterListVO::getCreateUserId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
List<EnterpriseUserDO> users = enterpriseUserDAO.getUserInfoByUserIds(userIds);
Map<String, String> userNameMap = users.stream()
.collect(Collectors.toMap(EnterpriseUserDO::getUserId, EnterpriseUserDO::getName, (a, b) -> a));
List<String> storeCodes = list.stream().filter(x-> StringUtils.isNotBlank(x.getStoreCode()))
.map(ContractMasterListVO::getStoreCode)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
List<StoreDO> storeList = storeDao.getStoreNumByStoreCodes(storeCodes);
Map<String, StoreDO> storeMap = storeList.stream().collect(Collectors.toMap(StoreDO::getStoreNum, data -> data, (a, b) -> a));
list.forEach(vo -> {
if (vo.getCreateUserId() != null) {
vo.setCreateUserName(userNameMap.get(vo.getCreateUserId()));
}
StoreDO storeDO = storeMap.get(vo.getStoreCode());
if (storeDO!=null){
vo.setStoreName(storeDO.getStoreName());
}
});
}
}

View File

@@ -1,132 +0,0 @@
package com.cool.store.service.contract.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.read.listener.ReadListener;
import com.cool.store.dao.contract.ContractCostDAO;
import com.cool.store.dao.contract.ContractMasterDAO;
import com.cool.store.entity.contract.ContractCostDO;
import com.cool.store.entity.contract.ContractMasterDO;
import com.cool.store.request.contract.ContractImportRowDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 合同导入监听器
*/
@RequiredArgsConstructor
@Slf4j
public class ContractImportListener implements ReadListener<ContractImportRowDTO> {
private final ContractMasterDAO contractMasterDAO;
private final ContractCostDAO contractCostDAO;
private final AtomicInteger totalNum;
private final AtomicInteger successNum;
private final List<String> errorList;
private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
@Override
public void onException(Exception e, AnalysisContext analysisContext) {
log.error("合同导入失败", e);
}
@Override
public void invokeHead(Map<Integer, CellData> map, AnalysisContext analysisContext) {
}
@Override
public void invoke(ContractImportRowDTO data, AnalysisContext context) {
totalNum.incrementAndGet();
int rowIndex = context.readRowHolder().getRowIndex();
if (data == null || StringUtils.isBlank(data.getContractNo())) {
errorList.add("" + rowIndex + "行:合同编号为空");
return;
}
if (StringUtils.isBlank(data.getStoreCode())) {
errorList.add("" + rowIndex + "行:门店编码为空");
return;
}
ContractMasterDO contractDO = new ContractMasterDO();
contractDO.setContractType(data.getContractType());
contractDO.setContractNo(data.getContractNo());
contractDO.setStoreCode(data.getStoreCode());
contractDO.setBrandName(data.getBrandName());
contractDO.setSource(data.getSource());
contractDO.setSignForm(data.getSignForm());
contractDO.setContractYears(data.getContractYears());
contractDO.setContractStatus(data.getContractStatus());
contractDO.setRemark(data.getRemark());
contractDO.setRelatedContractNo(data.getRelatedContractNo());
contractDO.setRenewalCreated(0);
try {
if (StringUtils.isNotBlank(data.getStartDate())) {
contractDO.setStartDate(dateFormat.parse(data.getStartDate()));
}
if (StringUtils.isNotBlank(data.getEndDate())) {
contractDO.setEndDate(dateFormat.parse(data.getEndDate()));
}
if (StringUtils.isNotBlank(data.getSignDate())) {
contractDO.setSignDate(dateFormat.parse(data.getSignDate()));
}
} catch (Exception e) {
errorList.add("" + rowIndex + "行:日期格式错误");
return;
}
try {
contractMasterDAO.insertSelective(contractDO);
// 插入费用数据
ContractCostDO costDO = ContractCostDO.builder()
.contractNo(data.getContractNo())
.joinFeeAmount(data.getJoinFeeAmount())
.joinFeeFrequencyYears(data.getJoinFeeFrequencyYears())
.joinFeeDiscountAmount(data.getJoinFeeDiscountAmount())
.joinFeeDiscountReason(data.getJoinFeeDiscountReason())
.brandUsageFeeAmount(data.getBrandUsageFeeAmount())
.brandUsageFeeFrequencyYears(data.getBrandUsageFeeFrequencyYears())
.brandManagementFeeAmount(data.getBrandManagementFeeAmount())
.brandManagementFeeFrequencyYears(data.getBrandManagementFeeFrequencyYears())
.designFeeAmount(data.getDesignFeeAmount())
.systemUsageFeeAmount(data.getSystemUsageFeeAmount())
.performanceBondAmount(data.getPerformanceBondAmount())
.createdTime(new Date())
.updatedTime(new Date())
.build();
contractCostDAO.insertSelective(costDO);
successNum.incrementAndGet();
} catch (Exception e) {
log.error("合同导入插入失败: contractNo={}", data.getContractNo(), e);
errorList.add("" + rowIndex + "行:插入失败-" + e.getMessage());
}
}
@Override
public void extra(CellExtra cellExtra, AnalysisContext analysisContext) {
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
log.info("合同导入完成,总数:{}, 成功:{}", totalNum.get(), successNum.get());
}
@Override
public boolean hasNext(AnalysisContext analysisContext) {
return true;
}
}

View File

@@ -1,49 +0,0 @@
package com.cool.store.service.exam;
import com.cool.store.dto.exam.*;
import com.cool.store.vo.exam.ExamAttemptListVO;
import com.cool.store.vo.exam.ExamAttemptVO;
import com.cool.store.vo.exam.ExamPaperForAttemptVO;
import com.cool.store.vo.exam.ExamResultVO;
import com.github.pagehelper.PageInfo;
/**
* 答卷服务接口
*/
public interface ExamAttemptService {
/**
* 开始考试
*/
ExamPaperForAttemptVO startAttempt(ExamStartAttemptDTO dto);
/**
* 保存答案
*/
void saveAnswer(ExamSubmitAnswerDTO dto);
/**
* 提交试卷
*/
ExamResultVO submitPaper(ExamSubmitPaperDTO dto);
/**
* 超时自动提交
*/
void autoSubmit(Long attemptId);
/**
* 查看答卷详情
*/
ExamAttemptVO getAttemptDetail(Long attemptId);
/**
* 查看考试结果
*/
ExamResultVO getResult(Long attemptId);
/**
* 根据手机号分页查询答卷列表
*/
PageInfo<ExamAttemptListVO> listByMobile(String mobile, Integer pageNum, Integer pageSize);
}

View File

@@ -1,57 +0,0 @@
package com.cool.store.service.exam;
import com.cool.store.dto.exam.*;
import com.cool.store.vo.exam.ExamInfoListVO;
import com.cool.store.vo.exam.ExamInfoVO;
import com.github.pagehelper.PageInfo;
/**
* 考试服务接口
*/
public interface ExamInfoService {
/**
* 创建考试
*/
void addExam(ExamInfoAddDTO dto);
/**
* 更新考试
*/
void updateExam(ExamInfoAddDTO dto);
/**
* 发布考试
*/
void publishExam(Long id);
/**
* 结束考试
*/
void endExam(Long id);
/**
* 查询考试列表
*/
PageInfo<ExamInfoListVO> getExamList(ExamInfoListDTO dto);
/**
* 查询考试详情
*/
ExamInfoVO getExamDetail(Long id);
/**
* 通过token获取考试信息
*/
ExamInfoVO getExamByToken(String token);
/**
* 删除考试
*/
void deleteExam(Long id);
/**
* 自动结束考试(由延时消息触发)
*/
void autoEndExam(Long id);
}

View File

@@ -1,42 +0,0 @@
package com.cool.store.service.exam;
import com.cool.store.dto.exam.*;
import com.cool.store.vo.exam.ExamPaperListVO;
import com.cool.store.vo.exam.ExamPaperVO;
import com.github.pagehelper.PageInfo;
/**
* 试卷服务接口
*/
public interface ExamPaperService {
/**
* 新增试卷
*/
void addPaper(ExamPaperAddDTO dto);
/**
* 更新试卷
*/
void updatePaper(ExamPaperAddDTO dto);
/**
* 删除试卷
*/
void deletePaper(Long id);
/**
* 查询试卷列表
*/
PageInfo<ExamPaperListVO> getPaperList(ExamPaperListDTO dto);
/**
* 查询试卷详情
*/
ExamPaperVO getPaperDetail(Long id);
/**
* 检查试卷是否已开始考试
*/
boolean hasStartedExam(Long paperId);
}

View File

@@ -1,39 +0,0 @@
package com.cool.store.service.exam;
import com.cool.store.dto.exam.*;
import com.cool.store.vo.exam.ExamQuestionListVO;
import com.cool.store.vo.exam.ExamQuestionVO;
import com.github.pagehelper.PageInfo;
import java.util.List;
/**
* 题目服务接口
*/
public interface ExamQuestionService {
/**
* 新增题目
*/
void addQuestion(ExamQuestionAddDTO dto);
/**
* 更新题目
*/
void updateQuestion(ExamQuestionAddDTO dto);
/**
* 批量删除题目
*/
void deleteQuestions(List<Long> ids);
/**
* 查询题目列表
*/
PageInfo<ExamQuestionListVO> getQuestionList(ExamQuestionListDTO dto);
/**
* 查询题目详情
*/
ExamQuestionVO getQuestionDetail(Long id);
}

View File

@@ -1,477 +0,0 @@
package com.cool.store.service.exam.impl;
import cn.hutool.core.collection.CollStreamUtil;
import com.alibaba.fastjson.JSON;
import com.cool.store.constants.CommonConstants;
import com.cool.store.context.PartnerUserHolder;
import com.cool.store.dao.exam.*;
import com.cool.store.dto.exam.*;
import com.cool.store.entity.exam.*;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.ExamAttemptStatusEnum;
import com.cool.store.enums.ExamInfoStatusEnum;
import com.cool.store.enums.RocketMqTagEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mq.producer.SimpleMessageService;
import com.cool.store.service.exam.ExamAttemptService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.vo.exam.ExamAttemptListVO;
import com.cool.store.vo.exam.ExamAttemptVO;
import com.cool.store.vo.exam.ExamAnswerVO;
import com.cool.store.vo.exam.ExamOptionVO;
import com.cool.store.vo.exam.ExamPaperForAttemptVO;
import com.cool.store.vo.exam.ExamResultVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
* 答卷服务实现
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class ExamAttemptServiceImpl implements ExamAttemptService {
private final ExamInfoDAO examInfoDAO;
private final ExamPaperDAO examPaperDAO;
private final ExamPaperQuestionDAO examPaperQuestionDAO;
private final ExamAttemptDAO examAttemptDAO;
private final ExamAttemptAnswerDAO examAttemptAnswerDAO;
private final SimpleMessageService simpleMessageService;
@Override
@Transactional(rollbackFor = Exception.class)
public ExamPaperForAttemptVO startAttempt(ExamStartAttemptDTO dto) {
// 获取当前登录用户信息
String mobile = PartnerUserHolder.getUser().getMobile();
// 验证考试信息
ExamInfoDO examInfoDO = examInfoDAO.selectByToken(dto.getEntryToken());
if (examInfoDO == null || CommonConstants.INDEX_ONE.equals(examInfoDO.getDeleted())) {
throw new ServiceException(ErrorCodeEnum.EXAM_TOKEN_INVALID);
}
// 检查是否有进行中的答卷
ExamAttemptDO existingAttempt = examAttemptDAO.selectInProgressByExamIdAndMobile(examInfoDO.getId(), mobile);
if (existingAttempt != null) {
// 检查是否已超时
if (existingAttempt.getDeadlineTime() != null && new Date().before(existingAttempt.getDeadlineTime())) {
// 返回继续考试的试卷信息(包含已保存的答案)
return buildPaperForAttemptWithAnswers(examInfoDO, existingAttempt);
}
throw new ServiceException(ErrorCodeEnum.EXAM_ATTEMPT_EXPIRED);
}
// 已参加考试
if (examAttemptDAO.existFinishAttempt(mobile, examInfoDO.getId())) {
throw new ServiceException(ErrorCodeEnum.EXAM_COMPLETED);
}
// 校验考试时间范围
Date now = new Date();
Date startTime = examInfoDO.getStartTime();
Date endTime = examInfoDO.getEndTime();
// 如果开始时间不为空,校验当前时间是否已到开始时间
if (startTime != null && now.before(startTime)) {
throw new ServiceException(ErrorCodeEnum.EXAM_NOT_STARTED);
}
// 如果结束时间不为空,校验当前时间是否早于结束时间
if (endTime != null && !now.before(endTime)) {
throw new ServiceException(ErrorCodeEnum.EXAM_TIME_ENDED);
}
// 检查考试状态
if (!ExamInfoStatusEnum.isPublished(examInfoDO.getStatus())) {
throw new ServiceException(ErrorCodeEnum.EXAM_NOT_PUBLISHED);
}
// 创建新答卷
ExamAttemptDO attemptDO = new ExamAttemptDO();
attemptDO.setExamId(examInfoDO.getId());
attemptDO.setPaperId(examInfoDO.getPaperId());
attemptDO.setName(dto.getName());
attemptDO.setMobile(mobile);
attemptDO.setStartTime(new Date());
Date deadline = new Date(System.currentTimeMillis() + examInfoDO.getDurationMinutes() * 60 * 1000L);
attemptDO.setDeadlineTime(deadline);
examAttemptDAO.insertSelective(attemptDO);
// 加入延时队列
simpleMessageService.send(String.valueOf(attemptDO.getId()), RocketMqTagEnum.EXAM_AUTO_SUBMIT, deadline.getTime());
// 返回试卷信息
return buildPaperForAttempt(examInfoDO, attemptDO);
}
@Override
public void saveAnswer(ExamSubmitAnswerDTO dto) {
ExamAttemptDO attemptDO = getAndCheckAttempt(dto.getAttemptId());
checkAttemptInProgress(attemptDO);
String partnerId = PartnerUserHolder.getUser().getPartnerId();
// 保存或更新答案
ExamAttemptAnswerDO answerDO = new ExamAttemptAnswerDO();
answerDO.setAttemptId(dto.getAttemptId());
answerDO.setPaperId(attemptDO.getPaperId());
answerDO.setPaperQuestionId(dto.getPaperQuestionId());
answerDO.setCreateUserId(partnerId);
// 将答案对象转为JSON字符串存储
if (dto.getAnswer() != null) {
answerDO.setAnswer(JSON.toJSONString(dto.getAnswer()));
}
examAttemptAnswerDAO.insertOrUpdate(answerDO);
}
@Override
@Transactional(rollbackFor = Exception.class)
public ExamResultVO submitPaper(ExamSubmitPaperDTO dto) {
ExamAttemptDO attemptDO = getAndCheckAttempt(dto.getAttemptId());
checkAttemptInProgress(attemptDO);
String partnerId = PartnerUserHolder.getUser().getPartnerId();
// 批量保存答案
if (CollectionUtils.isNotEmpty(dto.getAnswers())) {
List<ExamAttemptAnswerDO> answerList = CollStreamUtil.toList(dto.getAnswers(), item -> {
ExamAttemptAnswerDO answerDO = new ExamAttemptAnswerDO();
answerDO.setAttemptId(dto.getAttemptId());
answerDO.setPaperId(attemptDO.getPaperId());
answerDO.setPaperQuestionId(item.getPaperQuestionId());
answerDO.setCreateUserId(partnerId);
// 将答案对象转为JSON字符串存储
if (item.getAnswer() != null) {
answerDO.setAnswer(JSON.toJSONString(item.getAnswer()));
}
return answerDO;
});
examAttemptAnswerDAO.batchInsertOrUpdate(answerList);
}
// 自动评分
return doScoring(attemptDO, 0);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void autoSubmit(Long attemptId) {
ExamAttemptDO attemptDO = examAttemptDAO.selectByPrimaryKey(attemptId);
if (attemptDO == null || ExamAttemptStatusEnum.isCompleted(attemptDO.getStatus())) {
return;
}
doScoring(attemptDO, 1);
}
@Override
public ExamAttemptVO getAttemptDetail(Long attemptId) {
ExamAttemptDO attemptDO = getAndCheckAttempt(attemptId);
ExamAttemptVO vo = BeanUtil.toBean(attemptDO, ExamAttemptVO.class);
// 查询考试名称
ExamInfoDO examInfoDO = examInfoDAO.selectByPrimaryKey(attemptDO.getExamId());
if (examInfoDO != null) {
vo.setExamName(examInfoDO.getExamName());
}
// 查询题目和答案(批量查询)
List<ExamPaperQuestionDO> questions = examPaperQuestionDAO.selectByPaperId(attemptDO.getPaperId());
Map<Long, ExamAttemptAnswerDO> answerMap = examAttemptAnswerDAO.getMapByAttemptId(attemptId);
List<ExamAttemptVO.AnswerDetail> answers = CollStreamUtil.toList(questions, pq -> {
ExamAttemptVO.AnswerDetail detail = new ExamAttemptVO.AnswerDetail();
detail.setPaperQuestionId(pq.getId());
detail.setType(pq.getType());
detail.setQuestionStem(pq.getQuestionStem());
if (pq.getOptions() != null) {
detail.setOptions(JSON.parseArray(pq.getOptions(), ExamOptionVO.class));
}
// 将正确答案JSON字符串转为对象
if (StringUtils.isNotBlank(pq.getAnswer())) {
detail.setCorrectAnswer(JSON.parseObject(pq.getAnswer(), ExamAnswerVO.class));
}
detail.setTotalScore(pq.getScore());
detail.setAnalysis(pq.getAnalysis());
ExamAttemptAnswerDO userAnswer = answerMap.get(pq.getId());
if (userAnswer != null) {
// 将用户答案JSON字符串转为对象
if (StringUtils.isNotBlank(userAnswer.getAnswer())) {
detail.setUserAnswer(JSON.parseObject(userAnswer.getAnswer(), ExamAnswerVO.class));
}
detail.setScore(userAnswer.getScore());
detail.setIsCorrect(isCorrect(pq.getAnswer(), userAnswer.getAnswer(), pq.getType()));
}
return detail;
});
vo.setAnswers(answers);
return vo;
}
@Override
public ExamResultVO getResult(Long attemptId) {
ExamAttemptDO attemptDO = getAndCheckAttempt(attemptId);
// 查询试卷总分
ExamPaperDO paperDO = examPaperDAO.selectByPrimaryKey(attemptDO.getPaperId());
BigDecimal fullScore = paperDO != null ? paperDO.getTotalScore() : BigDecimal.ZERO;
// 批量查询题目和答案
List<ExamPaperQuestionDO> questions = examPaperQuestionDAO.selectByPaperId(attemptDO.getPaperId());
Map<Long, ExamAttemptAnswerDO> answerMap = examAttemptAnswerDAO.getMapByAttemptId(attemptId);
int totalCount = questions.size();
int correctCount = 0;
for (ExamPaperQuestionDO pq : questions) {
ExamAttemptAnswerDO answer = answerMap.get(pq.getId());
if (answer != null && isCorrect(pq.getAnswer(), answer.getAnswer(), pq.getType())) {
correctCount++;
}
}
ExamResultVO vo = new ExamResultVO();
vo.setAttemptId(attemptId);
vo.setTotalScore(attemptDO.getTotalScore() != null ? attemptDO.getTotalScore() : BigDecimal.ZERO);
vo.setFullScore(fullScore);
vo.setCorrectCount(correctCount);
vo.setTotalCount(totalCount);
vo.setPassed(isPassed(attemptDO.getTotalScore(), fullScore));
return vo;
}
@Override
public PageInfo<ExamAttemptListVO> listByMobile(String mobile, Integer pageNum, Integer pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<ExamAttemptDO> attemptList = examAttemptDAO.selectByMobile(mobile);
PageInfo<ExamAttemptDO> pageInfo = new PageInfo<>(attemptList);
if (CollectionUtils.isEmpty(attemptList)) {
return new PageInfo<>();
}
// 批量查询考试信息,包含被删除的考试
List<Long> examIds = CollStreamUtil.toList(attemptList, ExamAttemptDO::getExamId);
Map<Long, ExamInfoDO> examInfoMap = examInfoDAO.getMapIncludeDeletedByIds(examIds);
// 批量查询试卷信息
List<Long> paperIds = CollStreamUtil.toList(attemptList, ExamAttemptDO::getPaperId);
Map<Long, ExamPaperDO> paperMap = examPaperDAO.getMapByIds(paperIds);
List<ExamAttemptListVO> voList = CollStreamUtil.toList(attemptList, attempt -> {
ExamAttemptListVO vo = BeanUtil.toBean(attempt, ExamAttemptListVO.class);
ExamInfoDO examInfoDO = examInfoMap.get(attempt.getExamId());
if (examInfoDO != null) {
vo.setExamName(examInfoDO.getExamName());
vo.setDurationMinutes(examInfoDO.getDurationMinutes());
vo.setEntryToken(examInfoDO.getEntryToken());
}
ExamPaperDO paperDO = paperMap.get(attempt.getPaperId());
if (paperDO != null) {
vo.setFullScore(paperDO.getTotalScore());
}
vo.setStatusDesc(ExamAttemptStatusEnum.isCompleted(attempt.getStatus()) ? "已完成" : "进行中");
if (ExamAttemptStatusEnum.isCompleted(attempt.getStatus()) && paperDO != null) {
vo.setPassed(isPassed(attempt.getTotalScore(), paperDO.getTotalScore()));
}
return vo;
});
// 构建分页结果
PageInfo<ExamAttemptListVO> resultPage = new PageInfo<>();
resultPage.setList(voList);
resultPage.setTotal(pageInfo.getTotal());
resultPage.setPageNum(pageInfo.getPageNum());
resultPage.setPageSize(pageInfo.getPageSize());
resultPage.setPages(pageInfo.getPages());
return resultPage;
}
// ==================== 私有方法 ====================
/**
* 获取并校验答卷
*/
private ExamAttemptDO getAndCheckAttempt(Long attemptId) {
ExamAttemptDO attemptDO = examAttemptDAO.selectByPrimaryKey(attemptId);
if (attemptDO == null) {
throw new ServiceException(ErrorCodeEnum.EXAM_ATTEMPT_NOT_EXIST);
}
return attemptDO;
}
/**
* 校验答卷是否进行中
*/
private void checkAttemptInProgress(ExamAttemptDO attemptDO) {
// 检查是否已提交
if (ExamAttemptStatusEnum.isCompleted(attemptDO.getStatus())) {
throw new ServiceException(ErrorCodeEnum.EXAM_ATTEMPT_ALREADY_SUBMITTED);
}
// 检查是否超时
if (attemptDO.getDeadlineTime() != null && new Date().after(attemptDO.getDeadlineTime())) {
throw new ServiceException(ErrorCodeEnum.EXAM_ATTEMPT_EXPIRED);
}
}
/**
* 执行评分
*/
private ExamResultVO doScoring(ExamAttemptDO attemptDO, Integer submitType) {
// 批量查询题目和答案
List<ExamPaperQuestionDO> questions = examPaperQuestionDAO.selectByPaperId(attemptDO.getPaperId());
Map<Long, ExamAttemptAnswerDO> answerMap = examAttemptAnswerDAO.getMapByAttemptId(attemptDO.getId());
BigDecimal totalScore = BigDecimal.ZERO;
List<ExamAttemptAnswerDO> updateList = new ArrayList<>();
// 计算每道题得分
for (ExamPaperQuestionDO pq : questions) {
ExamAttemptAnswerDO answerDO = answerMap.get(pq.getId());
if (answerDO != null) {
BigDecimal score = calculateScore(pq, answerDO.getAnswer());
answerDO.setScore(score);
updateList.add(answerDO);
totalScore = totalScore.add(score);
}
}
// 批量更新分数
if (CollectionUtils.isNotEmpty(updateList)) {
examAttemptAnswerDAO.batchUpdateScore(updateList);
}
// 更新答卷状态
examAttemptDAO.updateStatusAndScore(attemptDO.getId(),
ExamAttemptStatusEnum.COMPLETED.getCode(), submitType, totalScore);
return getResult(attemptDO.getId());
}
/**
* 计算单题得分
*/
private BigDecimal calculateScore(ExamPaperQuestionDO pq, String userAnswer) {
if (userAnswer == null || userAnswer.isEmpty()) {
return BigDecimal.ZERO;
}
boolean correct = isCorrect(pq.getAnswer(), userAnswer, pq.getType());
return correct ? pq.getScore() : BigDecimal.ZERO;
}
/**
* 判断答案是否正确
*/
private boolean isCorrect(String correctAnswer, String userAnswer, Integer type) {
if (correctAnswer == null || userAnswer == null) {
return false;
}
// 单选和判断题直接比较 (type: 1=单选, 2=多选, 3=判断)
if (type == null || type == 1 || type == 3) {
return correctAnswer.trim().equalsIgnoreCase(userAnswer.trim());
}
// 多选题需要比较所有选项
Set<String> correctSet = Arrays.stream(correctAnswer.split(","))
.map(String::trim)
.collect(Collectors.toSet());
Set<String> userSet = Arrays.stream(userAnswer.split(","))
.map(String::trim)
.collect(Collectors.toSet());
return correctSet.equals(userSet);
}
/**
* 判断是否通过60%及格)
*/
private boolean isPassed(BigDecimal totalScore, BigDecimal fullScore) {
if (totalScore == null || fullScore == null || fullScore.compareTo(BigDecimal.ZERO) <= 0) {
return false;
}
return totalScore.compareTo(fullScore.multiply(new BigDecimal("0.6"))) >= 0;
}
/**
* 构建答题试卷VO
*/
private ExamPaperForAttemptVO buildPaperForAttempt(ExamInfoDO examInfoDO, ExamAttemptDO attemptDO) {
ExamPaperForAttemptVO vo = new ExamPaperForAttemptVO();
vo.setAttemptId(attemptDO.getId());
vo.setExamName(examInfoDO.getExamName());
vo.setDurationMinutes(examInfoDO.getDurationMinutes());
vo.setStartTime(attemptDO.getStartTime().getTime());
vo.setDeadlineTime(attemptDO.getDeadlineTime().getTime());
vo.setRemainingTime(attemptDO.getDeadlineTime().getTime() - System.currentTimeMillis());
// 查询试卷题目(不含答案)
List<ExamPaperQuestionDO> questions = examPaperQuestionDAO.selectByPaperId(examInfoDO.getPaperId());
int[] sortNo = {1};
List<ExamPaperForAttemptVO.QuestionItem> items = CollStreamUtil.toList(questions, pq -> {
ExamPaperForAttemptVO.QuestionItem item = new ExamPaperForAttemptVO.QuestionItem();
item.setId(pq.getId());
item.setType(pq.getType());
item.setQuestionStem(pq.getQuestionStem());
if (pq.getOptions() != null) {
item.setOptions(JSON.parseArray(pq.getOptions(), ExamOptionVO.class));
}
item.setScore(pq.getScore());
item.setSortNo(sortNo[0]++);
return item;
});
vo.setQuestions(items);
return vo;
}
/**
* 构建答题试卷VO包含已保存的答案用于恢复考试
*/
private ExamPaperForAttemptVO buildPaperForAttemptWithAnswers(ExamInfoDO examInfoDO, ExamAttemptDO attemptDO) {
ExamPaperForAttemptVO vo = new ExamPaperForAttemptVO();
vo.setAttemptId(attemptDO.getId());
vo.setExamName(examInfoDO.getExamName());
vo.setDurationMinutes(examInfoDO.getDurationMinutes());
vo.setStartTime(attemptDO.getStartTime().getTime());
vo.setDeadlineTime(attemptDO.getDeadlineTime().getTime());
vo.setRemainingTime(attemptDO.getDeadlineTime().getTime() - System.currentTimeMillis());
// 查询试卷题目
List<ExamPaperQuestionDO> questions = examPaperQuestionDAO.selectByPaperId(examInfoDO.getPaperId());
// 查询已保存的答案
Map<Long, ExamAttemptAnswerDO> answerMap = examAttemptAnswerDAO.getMapByAttemptId(attemptDO.getId());
int[] sortNo = {1};
List<ExamPaperForAttemptVO.QuestionItem> items = CollStreamUtil.toList(questions, pq -> {
ExamPaperForAttemptVO.QuestionItem item = new ExamPaperForAttemptVO.QuestionItem();
item.setId(pq.getId());
item.setType(pq.getType());
item.setQuestionStem(pq.getQuestionStem());
if (pq.getOptions() != null) {
item.setOptions(JSON.parseArray(pq.getOptions(), ExamOptionVO.class));
}
item.setScore(pq.getScore());
item.setSortNo(sortNo[0]++);
// 设置已保存的答案
ExamAttemptAnswerDO savedAnswer = answerMap.get(pq.getId());
if (savedAnswer != null && StringUtils.isNotBlank(savedAnswer.getAnswer())) {
item.setUserAnswer(JSON.parseObject(savedAnswer.getAnswer(), ExamAnswerVO.class));
}
return item;
});
vo.setQuestions(items);
return vo;
}
}

View File

@@ -1,236 +0,0 @@
package com.cool.store.service.exam.impl;
import cn.hutool.core.collection.CollStreamUtil;
import com.aliyun.core.utils.StringUtils;
import com.cool.store.constants.CommonConstants;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.dao.exam.ExamAttemptDAO;
import com.cool.store.dao.exam.ExamInfoDAO;
import com.cool.store.dao.exam.ExamPaperDAO;
import com.cool.store.dto.exam.*;
import com.cool.store.entity.exam.ExamInfoDO;
import com.cool.store.entity.exam.ExamPaperDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.ExamInfoStatusEnum;
import com.cool.store.enums.RocketMqTagEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mq.producer.SimpleMessageService;
import com.cool.store.service.WechatMiniAppService;
import com.cool.store.service.exam.ExamInfoService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.UUIDUtils;
import com.cool.store.vo.exam.ExamInfoListVO;
import com.cool.store.vo.exam.ExamInfoVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 考试服务实现
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class ExamInfoServiceImpl implements ExamInfoService {
private final ExamInfoDAO examInfoDAO;
private final ExamPaperDAO examPaperDAO;
private final WechatMiniAppService wechatMiniAppService;
private final SimpleMessageService simpleMessageService;
private final ExamAttemptDAO examAttemptDAO;
@Value("${exam.qrcode.page:twelvePoints/exam/indexCode}")
private String examQrcodePage;
@Override
public void addExam(ExamInfoAddDTO dto) {
// 检查试卷是否存在
ExamPaperDO paperDO = examPaperDAO.selectByPrimaryKey(dto.getPaperId());
if (paperDO == null || CommonConstants.INDEX_ONE.equals(paperDO.getDeleted())) {
throw new ServiceException(ErrorCodeEnum.EXAM_PAPER_NOT_EXIST);
}
ExamInfoDO examInfoDO = BeanUtil.toBean(dto, ExamInfoDO.class);
examInfoDO.setEntryToken(UUIDUtils.get8UUID());
examInfoDO.setCreateUserId(CurrentUserHolder.getUserId());
examInfoDAO.insertSelective(examInfoDO);
}
@Override
public void updateExam(ExamInfoAddDTO dto) {
ExamInfoDO existExam = examInfoDAO.selectByPrimaryKey(dto.getId());
if (existExam == null || CommonConstants.INDEX_ONE.equals(existExam.getDeleted())) {
throw new ServiceException(ErrorCodeEnum.EXAM_INFO_NOT_EXIST);
}
// 已发布的考试不能修改
if (ExamInfoStatusEnum.isPublished(existExam.getStatus())) {
throw new ServiceException(ErrorCodeEnum.EXAM_ALREADY_PUBLISHED);
}
// 已结束的考试不能修改
if (ExamInfoStatusEnum.isEnded(existExam.getStatus())) {
throw new ServiceException(ErrorCodeEnum.EXAM_ALREADY_ENDED);
}
ExamInfoDO examInfoDO = BeanUtil.toBean(dto, ExamInfoDO.class);
examInfoDAO.updateByPrimaryKeySelective(examInfoDO);
}
@Override
@Transactional
public void publishExam(Long id) {
ExamInfoDO existExam = examInfoDAO.selectByPrimaryKey(id);
if (existExam == null || CommonConstants.INDEX_ONE.equals(existExam.getDeleted())) {
throw new ServiceException(ErrorCodeEnum.EXAM_INFO_NOT_EXIST);
}
// 只有未发布状态可以发布
if (!ExamInfoStatusEnum.canPublish(existExam.getStatus())) {
if (ExamInfoStatusEnum.isPublished(existExam.getStatus())) {
throw new ServiceException(ErrorCodeEnum.EXAM_ALREADY_PUBLISHED);
}
if (ExamInfoStatusEnum.isEnded(existExam.getStatus())) {
throw new ServiceException(ErrorCodeEnum.EXAM_ALREADY_ENDED);
}
}
// 标记试卷已开始考试
examPaperDAO.updateStartExam(existExam.getPaperId(), 1);
// 生成小程序二维码
String qrcodeUrl = null;
try {
qrcodeUrl = wechatMiniAppService.createQrCode(examQrcodePage, "entryToken=" + existExam.getEntryToken(), "430");
if (StringUtils.isBlank(qrcodeUrl)) {
log.warn("考试发布成功但生成二维码失败examId:{}", id);
}
} catch (Exception e) {
log.error("考试发布成功但生成二维码异常examId:{}", id, e);
}
// 合并更新状态和二维码URL
Date now = new Date();
ExamInfoDO update = new ExamInfoDO();
update.setId(id);
update.setQrcodeUrl(qrcodeUrl);
update.setStatus(ExamInfoStatusEnum.PUBLISHED.getCode());
update.setUpdateTime(now);
update.setStartTime(now);
examInfoDAO.updateByPrimaryKeySelective(update);
// 如果设置了结束时间,发送延时消息自动结束考试
if (existExam.getEndTime() != null && existExam.getEndTime().after(new Date())) {
simpleMessageService.send(String.valueOf(id), RocketMqTagEnum.EXAM_AUTO_END, existExam.getEndTime().getTime());
log.info("考试发布成功已设置自动结束延时消息examId:{}, endTime:{}", id, existExam.getEndTime());
}
}
@Override
public void endExam(Long id) {
ExamInfoDO existExam = examInfoDAO.selectByPrimaryKey(id);
if (existExam == null || CommonConstants.INDEX_ONE.equals(existExam.getDeleted())) {
throw new ServiceException(ErrorCodeEnum.EXAM_INFO_NOT_EXIST);
}
// 只有已发布状态可以结束
if (!ExamInfoStatusEnum.canEnd(existExam.getStatus())) {
if (ExamInfoStatusEnum.isEnded(existExam.getStatus())) {
throw new ServiceException(ErrorCodeEnum.EXAM_ALREADY_ENDED);
}
throw new ServiceException(ErrorCodeEnum.EXAM_NOT_PUBLISHED);
}
ExamInfoDO update = new ExamInfoDO();
update.setId(id);
update.setStatus(ExamInfoStatusEnum.ENDED.getCode());
update.setEndTime(new Date());
examInfoDAO.updateByPrimaryKeySelective(update);
}
@Override
public PageInfo<ExamInfoListVO> getExamList(ExamInfoListDTO dto) {
PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
List<ExamInfoDO> list = examInfoDAO.selectList(dto.getStatus());
PageInfo<ExamInfoListVO> pageInfo = BeanUtil.toPage(new PageInfo<>(list), ExamInfoListVO.class);
// 批量查询试卷信息
List<Long> paperIds = CollStreamUtil.toList(list, ExamInfoDO::getPaperId);
Map<Long, ExamPaperDO> paperMap = examPaperDAO.getMapByIds(paperIds);
List<Long> examIds = CollStreamUtil.toList(list, ExamInfoDO::getId);
Map<Long, Long> attemptCountMap = examAttemptDAO.getAttemptCount(examIds);
pageInfo.getList().forEach(vo -> {
ExamPaperDO paperDO = paperMap.get(vo.getPaperId());
if (paperDO != null) {
vo.setPaperName(paperDO.getPaperName());
}
vo.setAttemptCount(attemptCountMap.getOrDefault(vo.getId(), 0L).intValue());
});
return pageInfo;
}
@Override
public ExamInfoVO getExamDetail(Long id) {
ExamInfoDO examInfoDO = examInfoDAO.selectByPrimaryKey(id);
if (examInfoDO == null || CommonConstants.INDEX_ONE.equals(examInfoDO.getDeleted())) {
throw new ServiceException(ErrorCodeEnum.EXAM_INFO_NOT_EXIST);
}
ExamInfoVO vo = BeanUtil.toBean(examInfoDO, ExamInfoVO.class);
ExamPaperDO paperDO = examPaperDAO.selectByPrimaryKey(examInfoDO.getPaperId());
if (paperDO != null) {
vo.setPaperName(paperDO.getPaperName());
}
return vo;
}
@Override
public ExamInfoVO getExamByToken(String token) {
ExamInfoDO examInfoDO = examInfoDAO.selectByToken(token);
if (examInfoDO == null || CommonConstants.INDEX_ONE.equals(examInfoDO.getDeleted())) {
throw new ServiceException(ErrorCodeEnum.EXAM_TOKEN_INVALID);
}
if (!ExamInfoStatusEnum.isPublished(examInfoDO.getStatus())) {
throw new ServiceException(ErrorCodeEnum.EXAM_NOT_PUBLISHED);
}
ExamInfoVO vo = BeanUtil.toBean(examInfoDO, ExamInfoVO.class);
ExamPaperDO paperDO = examPaperDAO.selectByPrimaryKey(examInfoDO.getPaperId());
if (paperDO != null) {
vo.setPaperName(paperDO.getPaperName());
}
return vo;
}
@Override
@Transactional
public void deleteExam(Long id) {
ExamInfoDO existExam = examInfoDAO.selectByPrimaryKey(id);
if (existExam == null || CommonConstants.INDEX_ONE.equals(existExam.getDeleted())) {
throw new ServiceException(ErrorCodeEnum.EXAM_INFO_NOT_EXIST);
}
// 检查是否在考试中(已发布状态)
if (ExamInfoStatusEnum.isPublished(existExam.getStatus())) {
throw new ServiceException(ErrorCodeEnum.EXAM_IN_PROGRESS_CANNOT_DELETE);
}
examInfoDAO.deleteById(id);
}
@Override
public void autoEndExam(Long id) {
log.info("考试自动结束, id:{}", id);
ExamInfoDO existExam = examInfoDAO.selectByPrimaryKey(id);
if (existExam == null || CommonConstants.INDEX_ONE.equals(existExam.getDeleted())) {
log.warn("自动结束考试失败考试不存在examId:{}", id);
return;
}
// 只有已发布状态才自动结束
if (!ExamInfoStatusEnum.isPublished(existExam.getStatus())) {
log.info("考试非已发布状态跳过自动结束examId:{}, status:{}", id, existExam.getStatus());
return;
}
ExamInfoDO update = new ExamInfoDO();
update.setId(id);
update.setStatus(ExamInfoStatusEnum.ENDED.getCode());
update.setUpdateTime(new Date());
examInfoDAO.updateByPrimaryKeySelective(update);
log.info("考试自动结束成功examId:{}", id);
}
}

View File

@@ -1,173 +0,0 @@
package com.cool.store.service.exam.impl;
import cn.hutool.core.collection.CollStreamUtil;
import com.alibaba.fastjson.JSON;
import com.cool.store.constants.CommonConstants;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.dao.exam.ExamPaperDAO;
import com.cool.store.dao.exam.ExamPaperQuestionDAO;
import com.cool.store.dao.exam.ExamQuestionDAO;
import com.cool.store.dto.exam.*;
import com.cool.store.entity.exam.ExamPaperDO;
import com.cool.store.entity.exam.ExamPaperQuestionDO;
import com.cool.store.entity.exam.ExamQuestionDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.service.exam.ExamPaperService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.vo.exam.ExamOptionVO;
import com.cool.store.vo.exam.ExamPaperListVO;
import com.cool.store.vo.exam.ExamPaperVO;
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.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 试卷服务实现
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class ExamPaperServiceImpl implements ExamPaperService {
private final ExamPaperDAO examPaperDAO;
private final ExamPaperQuestionDAO examPaperQuestionDAO;
private final ExamQuestionDAO examQuestionDAO;
@Override
@Transactional(rollbackFor = Exception.class)
public void addPaper(ExamPaperAddDTO dto) {
// 创建试卷
ExamPaperDO paperDO = BeanUtil.toBean(dto, ExamPaperDO.class);
paperDO.setCreateUserId(CurrentUserHolder.getUserId());
examPaperDAO.insertSelective(paperDO);
// 保存试卷题目
BigDecimal totalScore = insertQuestionAndComputeTotalScore(dto.getQuestions(), paperDO.getId());
// 更新总分
ExamPaperDO updateDO = new ExamPaperDO();
updateDO.setId(paperDO.getId());
updateDO.setTotalScore(totalScore);
examPaperDAO.updateByPrimaryKeySelective(updateDO);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updatePaper(ExamPaperAddDTO dto) {
ExamPaperDO existPaper = examPaperDAO.selectByPrimaryKey(dto.getId());
if (existPaper == null || CommonConstants.INDEX_ONE.equals(existPaper.getDeleted())) {
throw new ServiceException(ErrorCodeEnum.EXAM_PAPER_NOT_EXIST);
}
// 检查是否已开始考试
if (CommonConstants.INDEX_ONE.equals(existPaper.getStartExam())) {
throw new ServiceException(ErrorCodeEnum.EXAM_PAPER_STARTED_CANNOT_EDIT);
}
ExamPaperDO paperDO = BeanUtil.toBean(dto, ExamPaperDO.class);
// 如果有题目列表,更新题目
if (CollectionUtils.isNotEmpty(dto.getQuestions())) {
// 删除原有题目
examPaperQuestionDAO.deleteByPaperId(dto.getId());
// 重新添加题目(批量插入)
BigDecimal totalScore = insertQuestionAndComputeTotalScore(dto.getQuestions(), dto.getId());
// 更新总分
paperDO.setTotalScore(totalScore);
}
examPaperDAO.updateByPrimaryKeySelective(paperDO);
}
public BigDecimal insertQuestionAndComputeTotalScore(List<ExamPaperAddDTO.PaperQuestionItemDTO> questions, Long paperId) {
BigDecimal totalScore = BigDecimal.ZERO;
List<Long> questionIds = CollStreamUtil.toList(questions, ExamPaperAddDTO.PaperQuestionItemDTO::getQuestionId);
Map<Long, ExamQuestionDO> questionMap = examQuestionDAO.getMapByIds(questionIds);
List<ExamPaperQuestionDO> pqDOs = new ArrayList<>();
for (ExamPaperAddDTO.PaperQuestionItemDTO item : questions) {
ExamQuestionDO questionDO = questionMap.get(item.getQuestionId());
if (questionDO == null || CommonConstants.INDEX_ONE.equals(questionDO.getDeleted())) {
throw new ServiceException(ErrorCodeEnum.EXAM_QUESTION_NOT_EXIST);
}
ExamPaperQuestionDO pqDO = BeanUtil.toBean(questionDO, ExamPaperQuestionDO.class);
pqDO.setPaperId(paperId);
pqDO.setQuestionId(item.getQuestionId());
pqDO.setScore(item.getScore() != null ? item.getScore() : questionDO.getScore());
pqDO.setCreateUserId(CurrentUserHolder.getUserId());
pqDOs.add(pqDO);
totalScore = totalScore.add(pqDO.getScore());
}
examPaperQuestionDAO.insertBatch(pqDOs);
return totalScore;
}
@Override
@Transactional
public void deletePaper(Long id) {
ExamPaperDO existPaper = examPaperDAO.selectByPrimaryKey(id);
if (existPaper == null || CommonConstants.INDEX_ONE.equals(existPaper.getDeleted())) {
throw new ServiceException(ErrorCodeEnum.EXAM_PAPER_NOT_EXIST);
}
// 检查是否已开始考试
if (CommonConstants.INDEX_ONE.equals(existPaper.getStartExam())) {
throw new ServiceException(ErrorCodeEnum.EXAM_PAPER_STARTED_CANNOT_EDIT);
}
examPaperDAO.deleteById(id);
examPaperQuestionDAO.deleteByPaperId(id);
}
@Override
public PageInfo<ExamPaperListVO> getPaperList(ExamPaperListDTO dto) {
PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
List<ExamPaperDO> list = examPaperDAO.selectList(dto.getPaperName(), dto.getEnable(), dto.getStartExam());
PageInfo<ExamPaperListVO> pageInfo = BeanUtil.toPage(new PageInfo<>(list), ExamPaperListVO.class);
pageInfo.getList().forEach(vo -> vo.setQuestionCount(examPaperQuestionDAO.countByPaperId(vo.getId())));
return pageInfo;
}
@Override
public ExamPaperVO getPaperDetail(Long id) {
ExamPaperDO paperDO = examPaperDAO.selectByPrimaryKey(id);
if (paperDO == null || CommonConstants.INDEX_ONE.equals(paperDO.getDeleted())) {
throw new ServiceException(ErrorCodeEnum.EXAM_PAPER_NOT_EXIST);
}
ExamPaperVO vo = new ExamPaperVO();
BeanUtils.copyProperties(paperDO, vo);
// 查询题目列表
ExamPaperQuestionDO pqQuery = new ExamPaperQuestionDO();
pqQuery.setPaperId(id);
pqQuery.setDeleted(0);
List<ExamPaperQuestionDO> questions = examPaperQuestionDAO.select(pqQuery);
List<ExamPaperVO.PaperQuestionVO> questionVOList = new ArrayList<>();
int sortNo = 1;
for (ExamPaperQuestionDO pq : questions) {
ExamPaperVO.PaperQuestionVO qvo = new ExamPaperVO.PaperQuestionVO();
BeanUtils.copyProperties(pq, qvo);
// 将JSON字符串转为选项对象列表
if (pq.getOptions() != null) {
qvo.setOptions(JSON.parseArray(pq.getOptions(), ExamOptionVO.class));
}
qvo.setSortNo(sortNo++);
questionVOList.add(qvo);
}
vo.setQuestions(questionVOList);
vo.setQuestionCount(questionVOList.size());
return vo;
}
@Override
public boolean hasStartedExam(Long paperId) {
ExamPaperDO paperDO = examPaperDAO.selectByPrimaryKey(paperId);
return paperDO != null && CommonConstants.INDEX_ONE.equals(paperDO.getStartExam());
}
}

View File

@@ -1,88 +0,0 @@
package com.cool.store.service.exam.impl;
import com.alibaba.fastjson.JSON;
import com.cool.store.constants.CommonConstants;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.dao.exam.ExamQuestionDAO;
import com.cool.store.dto.exam.*;
import com.cool.store.entity.exam.ExamQuestionDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.service.exam.ExamQuestionService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.vo.exam.ExamAnswerVO;
import com.cool.store.vo.exam.ExamOptionVO;
import com.cool.store.vo.exam.ExamQuestionListVO;
import com.cool.store.vo.exam.ExamQuestionVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 题目服务实现
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class ExamQuestionServiceImpl implements ExamQuestionService {
private final ExamQuestionDAO examQuestionDAO;
@Override
public void addQuestion(ExamQuestionAddDTO dto) {
ExamQuestionDO questionDO = dto.convert();
questionDO.setCreateUserId(CurrentUserHolder.getUserId());
examQuestionDAO.insertSelective(questionDO);
}
@Override
public void updateQuestion(ExamQuestionAddDTO dto) {
ExamQuestionDO existQuestion = examQuestionDAO.selectByPrimaryKey(dto.getId());
if (existQuestion == null || CommonConstants.INDEX_ONE.equals(existQuestion.getDeleted())) {
throw new ServiceException(ErrorCodeEnum.EXAM_QUESTION_NOT_EXIST);
}
ExamQuestionDO questionDO = dto.convert();
examQuestionDAO.updateByPrimaryKeySelective(questionDO);
}
@Override
public void deleteQuestions(List<Long> ids) {
examQuestionDAO.batchDeleteByIds(ids);
}
@Override
public PageInfo<ExamQuestionListVO> getQuestionList(ExamQuestionListDTO dto) {
PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
List<ExamQuestionDO> list = examQuestionDAO.selecList(dto.getType(), dto.getDifficulty(), dto.getQuestionStem(), dto.getEnable());
PageInfo<ExamQuestionDO> page = new PageInfo<>(list);
return BeanUtil.toPage(page, ExamQuestionListVO.class);
}
@Override
public ExamQuestionVO getQuestionDetail(Long id) {
ExamQuestionDO questionDO = examQuestionDAO.selectByPrimaryKey(id);
if (questionDO == null || CommonConstants.INDEX_ONE.equals(questionDO.getDeleted())) {
throw new ServiceException(ErrorCodeEnum.EXAM_QUESTION_NOT_EXIST);
}
return convertToVO(questionDO);
}
private ExamQuestionVO convertToVO(ExamQuestionDO questionDO) {
ExamQuestionVO vo = new ExamQuestionVO();
BeanUtils.copyProperties(questionDO, vo);
// 将JSON字符串转为答案对象
if (questionDO.getAnswer() != null) {
vo.setAnswer(JSON.parseObject(questionDO.getAnswer(), ExamAnswerVO.class));
}
// 将JSON字符串转为选项对象列表
if (questionDO.getOptions() != null) {
vo.setOptions(JSON.parseArray(questionDO.getOptions(), ExamOptionVO.class));
}
return vo;
}
}

View File

@@ -1,6 +1,5 @@
package com.cool.store.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.*;
@@ -11,7 +10,6 @@ import com.cool.store.entity.SplitOrderDO;
import com.cool.store.entity.StoreDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.ExpenseSheetTypeEnum;
import com.cool.store.enums.wallet.AdjustTypeEnum;
import com.cool.store.enums.wallet.DocStatusEnum;
import com.cool.store.enums.wallet.SplitSourceEnum;
import com.cool.store.enums.wallet.SplitTypeEnum;
@@ -21,11 +19,11 @@ import com.cool.store.request.wallet.ConfirmRechargeRequest;
import com.cool.store.request.wallet.OutStoreIdRequest;
import com.cool.store.response.AdjustmentOrderResponse;
import com.cool.store.service.AdjustmentOrderService;
import com.cool.store.service.SplitOrderService;
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.utils.GenerateNoUtil;
import com.cool.store.vo.login.UserLoginVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
@@ -41,7 +39,6 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.cool.store.enums.fees.AllocationPayStatusEnum.*;
import static com.cool.store.enums.fees.WalletFeeItemEnum.*;
import static com.cool.store.enums.wallet.DocStatusEnum.*;
/**
@@ -72,17 +69,8 @@ public class AdjustmentOrderServiceImpl implements AdjustmentOrderService {
@Resource
DictService dictService;
@Resource
SplitOrderService splitOrderService;
@Resource
UserAuthMappingService userAuthMappingService;
@Resource
EnterpriseUserRoleDao enterpriseUserRoleDao;
private static final String PAYEE_ACCOUNT_NAME = "上海立规装饰设计工程有限公司";
private static final String PAYEE_ACCOUNT_NO = "422011940168069";
private static final String ADJUSTMENT_ORDER_PREFIX = "TZ";
private static final String EXPENSE_SHEET_PREFIX = "FY";
@Override
@Transactional(rollbackFor = Exception.class)
@@ -94,10 +82,7 @@ public class AdjustmentOrderServiceImpl implements AdjustmentOrderService {
if (store == null) {
throw new ServiceException(ErrorCodeEnum.STORE_IS_EXIST);
}
Integer status = DOC_STATUS_1.getStatus();
if (request.getAdjustType()!=null && request.getAdjustType()==2){
status = DOC_STATUS_05.getStatus();
}
AdjustmentOrderDO adjustmentOrder = AdjustmentOrderDO.builder()
.adjustmentNo(GenerateNoUtil.generateAdjustmentNo(request.getExpenseSheetType()))
.storeId(request.getStoreId())
@@ -112,7 +97,7 @@ public class AdjustmentOrderServiceImpl implements AdjustmentOrderService {
.expenseSheetType(request.getExpenseSheetType())
.settledAmount(new BigDecimal("0"))
.pendingSettlementAmount(request.getAdjustAmount())
.status(status)
.status(DOC_STATUS_1.getStatus())
.createUserId(userId)
.createTime(new Date())
.build();
@@ -134,7 +119,7 @@ public class AdjustmentOrderServiceImpl implements AdjustmentOrderService {
}
// 只有待确认缴费状态才能编辑
if (!(DOC_STATUS_1.getStatus().equals(existing.getStatus())||DOC_STATUS_05.getStatus().equals(existing.getStatus()))) {
if (!DOC_STATUS_1.getStatus().equals(existing.getStatus())) {
throw new ServiceException(ErrorCodeEnum.NOT_SUPPORT_OPERATION);
}
@@ -171,7 +156,7 @@ public class AdjustmentOrderServiceImpl implements AdjustmentOrderService {
}
// 只有待确认缴费状态才能删除
if (!DocStatusEnum.getCanDeleteStatus().contains(existing.getStatus())) {
if (!DOC_STATUS_1.getStatus().equals(existing.getStatus())) {
throw new ServiceException(ErrorCodeEnum.NOT_SUPPORT_OPERATION);
}
existing.setDeleted(1);
@@ -192,6 +177,10 @@ public class AdjustmentOrderServiceImpl implements AdjustmentOrderService {
return buildResponse(adjustmentOrder);
}
@Resource
UserAuthMappingService userAuthMappingService;
@Resource
EnterpriseUserRoleDao enterpriseUserRoleDao;
@Override
public PageInfo<AdjustmentOrderResponse> page(AdjustmentOrderPageRequest request, String userId) {
@@ -382,68 +371,9 @@ public class AdjustmentOrderServiceImpl implements AdjustmentOrderService {
log.info("费用调整单认款成功,单号:{},交易流水号:{}",
adjustmentOrder.getAdjustmentNo(), request.getTradeNos());
//查看当前门店是否有账户
OutStoreIdRequest outStoreIdRequest = new OutStoreIdRequest();
outStoreIdRequest.setOutStoreId(adjustmentOrder.getStoreId());
AccountInfoDTO onlineAccountInfo = walletApiService.getOnlineAccountInfo(outStoreIdRequest);
if (onlineAccountInfo==null){
log.info("费用调整单认款成功_当前门店无网商钱包账户");
return Boolean.TRUE;
}
//费用单:费用类型为“灯箱广告类(立规) ”、“监控设备类(立规)” ,认款完成自动分账,默认分账到“上海立规装饰设计工程有限公司”
if (autoSplitOrder(adjustmentOrder.getExpenseSheetType(),adjustmentOrder.getExpenseTypeCode(),adjustmentOrder.getAdjustType())){
StoreDO store = storeDao.getByStoreId(adjustmentOrder.getStoreId());
GenerateSplitOrderRequest generateSplitOrderRequest = new GenerateSplitOrderRequest();
generateSplitOrderRequest.setId(update.getId());
generateSplitOrderRequest.setRemark(store.getStoreName()+adjustmentOrder.getRemark());
//
generateSplitOrderRequest.setSplitType(SplitTypeEnum.ADD_BY_HAND.getStatus());
generateSplitOrderRequest.setSplitAmount(adjustmentOrder.getPendingSettlementAmount());
//收款账户
generateSplitOrderRequest.setPayeeAccountName(PAYEE_ACCOUNT_NAME);
generateSplitOrderRequest.setPayeeAccountNo(PAYEE_ACCOUNT_NO);
//付款账户
generateSplitOrderRequest.setPayerAccountName(onlineAccountInfo.getAccountName());
generateSplitOrderRequest.setPayerAccountNo(onlineAccountInfo.getAccountNo());
//生成分账单
String splitOrder = generateSplitOrder(generateSplitOrderRequest);
SplitOrderDO adjustDO = splitOrderDAO.getBySplitNo(splitOrder);
//确认分账
splitOrderService.confirmSplitOrder(adjustDO.getId(),userInfo);
}
return Boolean.TRUE;
}
/**
* 是否自动分账
* 费用单 广告费或者视频设备费
* 调整单 广告费或者视频设备费 且是调增
* @param expenseSheetType
* @param expenseType
* @param adjustType
* @return
*/
private Boolean autoSplitOrder(Integer expenseSheetType, String expenseType, Integer adjustType) {
// 广告费或者视频设备费
boolean flag = ADVERTISEMENT_FEE.getExpenseType().equals(expenseType)
|| VIDEO_DEVICE_FEE.getExpenseType().equals(expenseType);
if (expenseSheetType == ExpenseSheetTypeEnum.EXPENSE_SHEET.getCode()) {
// 广告费或者视频设备费 自动分账 返回true其他费用类型手动分账
return flag;
}
// 调整单逻辑
if (expenseSheetType == ExpenseSheetTypeEnum.ADJUSTMENT_SHEET.getCode()) {
// 调整单逻辑:调增 且 广告费/视频设备费 才自动分账
return adjustType == AdjustTypeEnum.ADJUST_TYPE_1.getCode()&& flag;
}
// 其他单据类型不分账
return Boolean.FALSE;
}
@Override
public Boolean calculateAmount(String no, String transferAmount) {
AdjustmentOrderDO adjustmentOrderDO = adjustmentOrderDAO.getByAdjustmentNo(no);
@@ -480,57 +410,9 @@ public class AdjustmentOrderServiceImpl implements AdjustmentOrderService {
@Override
public Long pageCount(AdjustmentOrderPageRequest request,LoginUserInfo user) {
List<String> regionIds = new ArrayList<>();
Boolean isAdmin = enterpriseUserRoleDao.checkIsAdmin(user.getUserId());
//非管理员根据管辖权限查询 管理员查所有
if (StringUtils.isNotEmpty(user.getUserId())&&!isAdmin){
regionIds = userAuthMappingService.getAuthRegionIdAndSubRegionIdByUserId(user.getUserId());
request.setRegionIds(regionIds);
}
return adjustmentOrderDAO.pageCount(request);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean approval(AdjustmentApprovalRequest request) {
if (request.getId() == null) {
throw new ServiceException(ErrorCodeEnum.CHANGE_ID_NOT_NULL);
}
AdjustmentOrderDO adjustmentOrder = adjustmentOrderDAO.getById(request.getId());
if (adjustmentOrder == null) {
throw new ServiceException(ErrorCodeEnum.CHANGE_NOT_NULL);
}
// 只有待审批状态才能审批
if (!DOC_STATUS_05.getStatus().equals(adjustmentOrder.getStatus())) {
throw new ServiceException(ErrorCodeEnum.NOT_SUPPORT_OPERATION);
}
// 拒绝时必须填写拒绝原因
if (request.getApprovalResult() == 2 && StringUtils.isBlank(request.getRejectReason())) {
throw new ServiceException(ErrorCodeEnum.ERROR_MESSAGE, "拒绝原因不能为空");
}
Integer newStatus;
if (request.getApprovalResult() == 1) {
// 审批通过,状态变为待充值
newStatus = DOC_STATUS_1.getStatus();
} else {
// 审批拒绝,状态变为审批未通过
newStatus = DOC_STATUS_15.getStatus();
}
AdjustmentOrderDO update = AdjustmentOrderDO.builder()
.id(request.getId())
.status(newStatus)
.rejectReason(request.getRejectReason())
.build();
int result = adjustmentOrderDAO.update(update);
return result > 0;
}
/**
* 构建响应对象
*/
@@ -555,7 +437,6 @@ public class AdjustmentOrderServiceImpl implements AdjustmentOrderService {
response.setClaimTime(adjustmentOrder.getClaimTime());
response.setContractAttachmentInfo(adjustmentOrder.getContractAttachmentInfo());
response.setPayTime(adjustmentOrder.getPayTime());
response.setRejectReason(adjustmentOrder.getRejectReason());
// 设置门店信息
if (StringUtils.isNotBlank(adjustmentOrder.getStoreId())) {

View File

@@ -52,14 +52,14 @@ public class AuditOpeningOperationPlanImpl implements AuditOpeningOperationPlanS
@Transactional(rollbackFor = Exception.class)
public Boolean auditPlan(OpeningOperationPlanAuditRequest request, LoginUserInfo user) {
log.info("auditPlan request:{}", JSONObject.toJSONString(request));
if (Boolean.TRUE) {
if (Objects.isNull(request)) {
log.error("auditPlan request is null");
throw new ServiceException("接口废弃");
throw new ServiceException("auditPlan request is null");
}
ShopStageInfoDO shopStageInfo = shopStageInfoDAO.getShopSubStageInfo(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_14);
// if (!shopStageInfo.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_141.getShopSubStageStatus())){
// throw new ServiceException(ErrorCodeEnum.NOT_ALLOW_OPERATE);
// }
if (!shopStageInfo.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_141.getShopSubStageStatus())){
throw new ServiceException(ErrorCodeEnum.NOT_ALLOW_OPERATE);
}
try {
ShopAuditInfoDO shopAuditInfoDO = request.toShopAuditInfoDO();
shopAuditInfoDO.setSubmittedUserId(user.getUserId());
@@ -73,12 +73,12 @@ public class AuditOpeningOperationPlanImpl implements AuditOpeningOperationPlanS
ShopSubStageStatusEnum shopSubStageStatusEnum = null;
Boolean flag = Boolean.FALSE;
if(OpeningOperationPlanResultTypeEnum.PASS_AUDIT.getCode().equals(request.getResultType())){
//shopSubStageStatusEnum = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_143;
shopSubStageStatusEnum = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_143;
flag = Boolean.TRUE;
}else {
ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(request.getShopId());
LineInfoDO lineInfoDO = lineInfoDAO.getLineInfo(shopInfo.getLineId());
//shopSubStageStatusEnum = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_142;
shopSubStageStatusEnum = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_142;
HashMap<String, String> map = new HashMap<>();
map.put("partnerUsername",lineInfoDO.getUsername());
map.put("partnerMobile",lineInfoDO.getMobile());

View File

@@ -26,7 +26,7 @@ public class BigRegionServiceImpl implements BigRegionService {
@Override
public List<BigRegionDTO> queryAllBigRegion(String keyword, Integer joinBrand,Integer type) {
return bigRegionDAO.queryAllBigRegion(keyword, joinBrand,type,null);
return bigRegionDAO.queryAllBigRegion(keyword, joinBrand,type);
}
@Override

View File

@@ -51,11 +51,11 @@ import static com.cool.store.enums.point.ShopSubStageStatusEnum.SHOP_SUB_STAGE_S
@Service
@Slf4j
public class BuildInformationServiceImpl implements BuildInformationService {
@Resource
private EnumInfoService enumInfoService;
@Resource
private PlatformBuildDAO platformBuildDAO;
@Resource
private EnumInfoService enumInfoService;
@Resource
private RedisConstantUtil redisConstantUtil;
@Resource
private RedisUtilPool redisUtilPool;

View File

@@ -1170,7 +1170,7 @@ public class DataHandlerServerImpl implements DataHandlerServer {
shopInfoDO.setManagerRegionId(isCreateStoreDTO.getPid());
updateList.add(shopInfoDO);
}
List<BigRegionDTO> bigRegionDTOS = bigRegionDAO.queryAllBigRegion(null, null,null,null);
List<BigRegionDTO> bigRegionDTOS = bigRegionDAO.queryAllBigRegion(null, null,null);
Map<Long, BigRegionDTO> bigRegionDTOMap = bigRegionDTOS.stream().collect(Collectors.toMap(BigRegionDTO::getRegionId, x -> x));
//XX大区 正烧鸡
List<Long> storeManageIds = bigRegionDTOS.stream().filter(x -> x.getStoreManageRegionId() != null).map(BigRegionDTO::getStoreManageRegionId).collect(Collectors.toList());

View File

@@ -1,6 +1,5 @@
package com.cool.store.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.*;
import com.cool.store.dto.DeskStageDTO;
@@ -31,7 +30,6 @@ import com.cool.store.vo.LabelBaseInfoVO;
import com.cool.store.vo.desk.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -52,7 +50,6 @@ import static com.cool.store.utils.poi.DateUtils.YYYY_MM_DD_HH_MM_SS;
* @Date 2024/3/26 15:15
* @Version 1.0
*/
@Slf4j
@Service
public class DeskServiceImpl implements DeskService {
@@ -99,8 +96,6 @@ public class DeskServiceImpl implements DeskService {
@Autowired
private ShopStageRemarkInfoDAO shopStageRemarkInfoDAO;
@Resource
OpeningOperationPlanDAO openingOperationPlanDAO;
@Resource
ShopAccountDAO shopAccountDAO;
@Resource
OperationsConsultantAssignDAO operationsConsultantAssignDAO;
@@ -1004,9 +999,6 @@ public class DeskServiceImpl implements DeskService {
List<ShopStageRemarkInfoDO> remarkInfoDOList = shopStageRemarkInfoDAO.getByShopIdsAndStage(shopIds, subStageStatusList);
Map<Long, List<ShopStageRemarkInfoDO>> remarkInfoMap = remarkInfoDOList.stream().collect(Collectors.groupingBy(ShopStageRemarkInfoDO::getShopId));
List<OpeningOperationPlanDO> openingOperationPlanDOS = openingOperationPlanDAO.selectByShopIds(shopIds);
Map<Long, OpeningOperationPlanDO> planDOMap = openingOperationPlanDOS.stream().collect(Collectors.toMap(OpeningOperationPlanDO::getShopId, Function.identity()));
List<PreparationCommonPendingVO> list = new ArrayList<>();
specialShopStageInfo.forEach(x -> {
PreparationCommonPendingVO preparationCommonPendingVO = new PreparationCommonPendingVO();
@@ -1030,9 +1022,6 @@ public class DeskServiceImpl implements DeskService {
preparationCommonPendingVO.setSignType(signFranchiseDO.getSignType());
preparationCommonPendingVO.setPartnershipSignatorySecond(signFranchiseDO.getPartnershipSignatorySecond());
}
OpeningOperationPlanDO doMapOrDefault = planDOMap.getOrDefault(x.getShopId(), new OpeningOperationPlanDO());
preparationCommonPendingVO.setOpenTime(doMapOrDefault.getOpenTime());
preparationCommonPendingVO.setActivityTheme(doMapOrDefault.getActivityTheme());
preparationCommonPendingVO.setShopCode(shopInfoDO.getShopCode());
preparationCommonPendingVO.setJoinMode(shopInfoDO.getJoinMode());
preparationCommonPendingVO.setInvestmentManager(userNameMap.getOrDefault(shopInfoDO.getInvestmentManager(),""));

View File

@@ -73,7 +73,7 @@ public class EnterpriseServiceImpl implements EnterpriseService {
currentUser.setId(enterpriseUser.getId());
currentUser.setUserId(enterpriseUser.getUserId());
currentUser.setAccount(enterpriseUser.getUserId());
currentUser.setDbName("coolcollege_intelligent_74");
currentUser.setDbName("coolcollege_intelligent_10027");
currentUser.setDepartmentIds(enterpriseUser.getDepartments());
currentUser.setRoles(enterpriseUser.getRoles());
currentUser.setLanguage(enterpriseUser.getLanguage());

View File

@@ -25,7 +25,7 @@ import com.cool.store.service.order.MiniStoreOrderService;
import com.cool.store.service.order.impl.MiniStoreOrderServiceImpl;
import com.cool.store.service.tp.TpScoreJournalService;
import com.cool.store.service.visit.VisitRecordService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.service.visit.VisitRecordService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.JSONUtils;
import com.cool.store.utils.RedisUtilPool;
@@ -40,6 +40,7 @@ import com.cool.store.vo.tp.TpScoreJournalVO;
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;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -852,8 +853,6 @@ public class ExportRealizeServiceImpl implements ExportRealizeService {
}
}
private List<PointExportVO> convertAndFillPointExport(List<PointPageVO> list) {
List<Long> pointIds = CollStreamUtil.toList(list, PointPageVO::getPointId);
Map<Long, PointFinancialDataDO> pointMap = pointFinancialDataDAO.getMapByPointIds(pointIds);

View File

@@ -311,7 +311,6 @@ public class ExportServiceImpl implements ExportService {
return count;
}
@Override
public Long myPointExport(PointPageRequest request, LoginUserInfo user) {
Long count = pointService.getMyPointCount(request, user.getUserId());

View File

@@ -15,8 +15,6 @@ import com.cool.store.request.HqtPartnerAcceptanceRequest;
import com.cool.store.request.hqt.*;
import com.cool.store.response.HqtAPIResponse;
import com.cool.store.service.HqtAPIService;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;

View File

@@ -1,197 +0,0 @@
package com.cool.store.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.dao.BigRegionDAO;
import com.cool.store.dao.ReceivingBankDAO;
import com.cool.store.dao.RegionDao;
import com.cool.store.dto.ImportOaOldShopDataDTO;
import com.cool.store.dto.ImportOaOldShopDataErrorDTO;
import com.cool.store.dto.ImportReceivingBankDTO;
import com.cool.store.dto.ImportReceivingBankErrorDTO;
import com.cool.store.dto.region.BigRegionDTO;
import com.cool.store.entity.ImportTaskDO;
import com.cool.store.entity.ReceivingBankDO;
import com.cool.store.enums.FileTypeEnum;
import com.cool.store.enums.FranchiseBrandEnum;
import com.cool.store.enums.ImportTaskStatusEnum;
import com.cool.store.enums.point.PayTypeEnum;
import com.cool.store.mapper.ImportTaskMapper;
import com.cool.store.request.ReceivingBankRequest;
import com.cool.store.service.ImportService;
import com.cool.store.utils.easyExcel.EasyExcelUtil;
import com.cool.store.utils.poi.DateUtils;
import com.cool.store.utils.poi.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import static com.cool.store.utils.poi.DateUtils.SPECIAL_DATE_START_1;
/**
* @Author: WangShuo
* @Date: 2025/06/19/10:29
* @Version 1.0
* @注释:
*/
@Service
@Slf4j
public class ImportServiceImpl implements ImportService {
@Value("${mybatis.configuration.variables.enterpriseId}")
private String eid;
@Resource
private EasyExcelUtil easyExcelUtil;
@Resource
private ImportTaskMapper importTaskMapper;
@Resource
private RegionDao regionDao;
@Resource
private BigRegionDAO bigRegionDAO;
@Resource
private ReceivingBankDAO receivingBankDAO;
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean importReceivingBank(List<ImportReceivingBankDTO> importList, String originalFilename, String userId, ImportTaskDO task) {
List<ReceivingBankDO> list = new ArrayList<>();
List<ImportReceivingBankErrorDTO> errorList = new ArrayList<>();
List<BigRegionDTO> bigRegionDTOS = bigRegionDAO.queryAllBigRegion(null, null, null, null);
Map<String, BigRegionDTO> bigRegionMap = bigRegionDTOS.stream().collect(Collectors.toMap(BigRegionDTO::getRegionName, x -> x));
List<ReceivingBankDO> receivingBankDOS = receivingBankDAO.queryAll();
Set<ReceivingBankDO> receivingBankSet = receivingBankDOS.stream()
.map(bank -> new ReceivingBankDO(bank.getRegionId(), bank.getFranchiseBrand(), bank.getPayType()))
.collect(Collectors.toSet());
ListUtils.emptyIfNull(importList)
.forEach(data -> {
try {
buildReceivingBankColumn(data,list,errorList,bigRegionMap,receivingBankSet,userId);
} catch (Exception e) {
ImportReceivingBankErrorDTO errorDTO = new ImportReceivingBankErrorDTO();
//直接复制
BeanUtils.copyProperties(data, errorDTO);
errorDTO.setErrorMsg("数据处理异常,请确认!");
errorList.add(errorDTO);
log.info("importReceivingBank 转化error:{}", JSONObject.toJSONString(data));
}
});
receivingBankDAO.batchInsertOrUpdate(list);
if (!errorList.isEmpty()) {
task.setStatus(ImportTaskStatusEnum.ERROR.getCode());
String url = null;
try {
url = easyExcelUtil.exportExcel(ImportReceivingBankErrorDTO.class, errorList, null,
FileTypeEnum.RECEIVING_BANK_IMPORT.getDesc() + DateUtils.parseDateToStr(SPECIAL_DATE_START_1, new Date()),
FileTypeEnum.RECEIVING_BANK_IMPORT.getDesc() + DateUtils.parseDateToStr(SPECIAL_DATE_START_1, new Date()));
} catch (Exception e) {
log.info("导出失败列表失败 errorList:{}", JSONObject.toJSONString(errorList));
}
task.setFileUrl(url);
} else {
task.setStatus(ImportTaskStatusEnum.SUCCESS.getCode());
}
task.setTotalNum(importList.size());
task.setSuccessNum(importList.size() - errorList.size());
importTaskMapper.update(eid, task);
log.info("导入数据条数:{}", list.size());
if (CollectionUtils.isEmpty(list)) {
log.info("导入数据转化为空");
return false;
}
return true;
}
/**
* @param dto excel列表数据
* @param list 正常导入的数据
* @param errorList 错误导入的数据
* @param bigRegionMap 区域数据
* @param receivingBankSet 重复数据校验
* @param userId 用户id
* @return
*/
private boolean buildReceivingBankColumn(ImportReceivingBankDTO dto, List<ReceivingBankDO> list,
List<ImportReceivingBankErrorDTO> errorList,
Map<String, BigRegionDTO> bigRegionMap,
Set<ReceivingBankDO> receivingBankSet, String userId) {
// 1. 统一获取并处理字段
String franchiseBrand = StringUtils.trimToNull(dto.getFranchiseBrand());
String regionName = StringUtils.trimToNull(dto.getRegionName());
String payType = StringUtils.trimToNull(dto.getPayType());
String payee = StringUtils.trimToNull(dto.getPayee());
String receivingAccount = StringUtils.trimToNull(dto.getReceivingAccount());
String bankName = StringUtils.trimToNull(dto.getBankName());
String branchBankName = StringUtils.trimToNull(dto.getBranchBankName());
// 2. 错误信息收集
StringBuilder errorMsg = new StringBuilder();
if (FranchiseBrandEnum.getCodeByDesc(franchiseBrand) == null) {
errorMsg.append("品牌信息错误;");
}
if (bigRegionMap.get(regionName) == null) {
errorMsg.append("大区信息错误;");
}
if (PayTypeEnum.getCodeByDesc(payType) == null) {
errorMsg.append("付款方式信息错误;");
}
if (StringUtils.isBlank(payee)) {
errorMsg.append("收款人不能为空;");
}
if (StringUtils.isBlank(receivingAccount)) {
errorMsg.append("收款账户不能为空;");
}
if (StringUtils.isBlank(bankName)) {
errorMsg.append("收款银行不能为空;");
}
if (StringUtils.isBlank(branchBankName)) {
errorMsg.append("收款银行开户行不能为空;");
}
// if (receivingBankSet.contains(new ReceivingBankDO(
// bigRegionMap.get(regionName) != null ? bigRegionMap.get(regionName).getRegionId() : null,
// FranchiseBrandEnum.getCodeByDesc(franchiseBrand) != null ? FranchiseBrandEnum.getCodeByDesc(franchiseBrand) : null,
// PayTypeEnum.getCodeByDesc(payType) != null ? PayTypeEnum.getCodeByDesc(payType) : null))) {
// errorMsg.append("收款信息已存在;");
// }
// 3. 只有存在错误时才创建错误dto 没有错误不需要创建对象
if (errorMsg.length() > 0) {
ImportReceivingBankErrorDTO errorDTO = new ImportReceivingBankErrorDTO();
//直接复制
BeanUtils.copyProperties(dto, errorDTO);
errorDTO.setErrorMsg(errorMsg.toString());
errorList.add(errorDTO);
return false;
}
// 4. 正常数据处理
ReceivingBankDO bankDO = new ReceivingBankDO();
bankDO.setRegionId(bigRegionMap.get(regionName).getRegionId());
bankDO.setFranchiseBrand(FranchiseBrandEnum.getCodeByDesc(franchiseBrand));
bankDO.setPayType(PayTypeEnum.getCodeByDesc(payType));
bankDO.setPayee(payee);
bankDO.setReceivingAccount(receivingAccount);
bankDO.setBankName(bankName);
bankDO.setBranchBankName(branchBankName);
bankDO.setCreateTime(new Date());
bankDO.setCreateUser(userId);
bankDO.setUpdateTime(new Date());
bankDO.setUpdateUser(userId);
list.add(bankDO);
// 5. 添加到已存在集合
receivingBankSet.add(new ReceivingBankDO(
bankDO.getRegionId(),
bankDO.getFranchiseBrand(),
bankDO.getPayType()));
return true;
}
}

View File

@@ -1,131 +0,0 @@
package com.cool.store.service.impl;
import com.cool.store.constants.RedisConstant;
import com.cool.store.dao.StoreDao;
import com.cool.store.dao.ThirdPartyAccountDAO;
import com.cool.store.dao.ThirdPartyStoreDAO;
import com.cool.store.entity.StoreDO;
import com.cool.store.entity.ThirdPartyAccountDO;
import com.cool.store.entity.ThirdPartyStoreDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.liepin.AddStoreEmpRequest;
import com.cool.store.request.liepin.AddStoreRequest;
import com.cool.store.request.liepin.GetPathRequest;
import com.cool.store.response.liepin.PathResponse;
import com.cool.store.service.LiePinService;
import com.cool.store.service.ThirdLiePinService;
import com.cool.store.utils.RedisConstantUtil;
import com.cool.store.utils.RedisUtilPool;
import com.cool.store.utils.StringUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @Author suzhuhong
* @Date 2025/5/26 19:27
* @Version 1.0
*/
@Service
public class LiePinServiceImpl implements LiePinService {
@Resource
ThirdPartyStoreDAO thirdPartyStoreDAO;
@Resource
ThirdPartyAccountDAO thirdPartyAccountDAO;
@Resource
StoreDao storeDao;
@Resource
ThirdLiePinService thirdLiePinService;
@Value("${liePin.tenantId}")
private Long tenantId;
@Resource
RedisUtilPool redisUtilPool;
@Resource
private RedisConstantUtil redisConstantUtil;
@Override
public String getJumpUrl(String shopCode,String mobile,String userName) {
String key = redisConstantUtil.getKeyCommonMethod(RedisConstant.LIE_PIN_EMP_PATH_PREFIX, shopCode,mobile);
String path = redisUtilPool.getString(key);
if (StringUtil.isNotEmpty(path)){
return path;
}
//查询当前门店是否推送该人员和门店到猎聘 如果没有推送 先推送
ThirdPartyAccountDO codeAndMobile = thirdPartyAccountDAO.getByCodeAndMobile(shopCode, mobile);
Long storeId = null;
if (codeAndMobile!=null){
storeId = Long.valueOf(codeAndMobile.getThirdPartyStoreId());
}else {
//先推送门店
storeId = pushStoreToLiePin(shopCode);
//推送人员
pushStoreEmpToLiePin(shopCode, mobile,userName);
}
//推送门店推送人员
GetPathRequest pathRequest = GetPathRequest.builder().mobile(mobile).store_id(String.valueOf(storeId)).tenant_id(tenantId).build();
PathResponse pathDTO = thirdLiePinService.getPath(pathRequest);
//存储3分钟
redisUtilPool.setString(key,pathDTO.getPath(),3*60);
return pathDTO.getPath();
}
@Override
public Long pushStoreToLiePin(String shopCode) {
//首先校验门店是否推送过
ThirdPartyStoreDO storeRecord = thirdPartyStoreDAO.getByLocalStoreCode(shopCode);
if (storeRecord!=null){
return Long.valueOf(storeRecord.getThirdPartyStoreId());
}
//校验推送的数据是否全 不全提示信息不足
StoreDO store = storeDao.getByStoreNum(shopCode);
if (StringUtil.isAnyBlank(store.getStoreAddress(),store.getLatitude(),store.getLongitude(),store.getAvatar(),store.getTelephone())){
throw new ServiceException(ErrorCodeEnum.STORE_INFO_INSUFFICIENT);
}
//oss文件换猎聘文件路径
String filePath = thirdLiePinService.getFilePath(store.getAvatar());
AddStoreRequest addStore = AddStoreRequest.builder().store_name(store.getStoreName()).
address(store.getStoreAddress())
.longitude(store.getLongitude())
.latitude(store.getLatitude())
.contact_person_mobile(store.getTelephone())
.exigency_mobile(store.getTelephone())
.contact_person_name(store.getStoreName() + store.getTelephone())
.doorplate_picture(filePath).tenant_id(tenantId).build();
Long storeId = thirdLiePinService.addStoreToLiePin(addStore);
//成功之后新增记录
ThirdPartyStoreDO thirdPartyStoreDO = ThirdPartyStoreDO.builder().localStoreCode(shopCode).thirdPartyStoreId(String.valueOf(storeId)).thirdPartyStoreUrl(filePath).build();
thirdPartyStoreDAO.addPushRecord(thirdPartyStoreDO);
return storeId;
}
@Override
public Long pushStoreEmpToLiePin(String shopCode, String mobile, String userName) {
if (StringUtil.isAnyBlank(shopCode,mobile)){
throw new ServiceException(ErrorCodeEnum.PARAMS_REQUIRED);
}
ThirdPartyAccountDO codeAndMobile = thirdPartyAccountDAO.getByCodeAndMobile(shopCode, mobile);
if (codeAndMobile!=null){
return Long.valueOf(codeAndMobile.getThirdPartyAccountId());
}
if (StringUtil.isEmpty(userName)){
userName = "店员" + mobile;
}
Long storeId = pushStoreToLiePin(shopCode);
AddStoreEmpRequest request = AddStoreEmpRequest.builder().store_id(storeId).account_type(1).position_id(1L).tenant_id(tenantId).mobile(mobile).nick_name(userName).build();
Long accountId = thirdLiePinService.addStoreEmp(request);
ThirdPartyAccountDO accountDO = ThirdPartyAccountDO.builder().accountType(request.getAccount_type()).mobile(mobile)
.positionId(request.getPosition_id()).localStoreCode(shopCode).thirdPartyStoreId(String
.valueOf(storeId)).thirdPartyAccountId(String.valueOf(accountId)).build();
thirdPartyAccountDAO.addPushRecord(accountDO);
return accountId;
}
}

View File

@@ -101,6 +101,7 @@ public abstract class LineFlowService {
if (CollectionUtils.isNotEmpty(shopInfoDOS)){
throw new ServiceException(ErrorCodeEnum.SHOP_HAVE_NOT_OVER_ACCORDING);
}
LineInfoDO lineInfo = lineInfoDAO.getLineInfo(request.getLineId());
String partnerId = lineInfo.getPartnerId();
LineAuditInfoDO auditInfo = new LineAuditInfoDO();

View File

@@ -6,7 +6,10 @@ import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.CommonConstants;
import com.cool.store.constants.RedisConstant;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.*;
import com.cool.store.dao.HyPartnerUserInfoDAO;
import com.cool.store.dao.LineInfoDAO;
import com.cool.store.dao.LinePayDAO;
import com.cool.store.dao.ShopStageInfoDAO;
import com.cool.store.dto.AmountDTO;
import com.cool.store.entity.*;
import com.cool.store.enums.*;
@@ -18,16 +21,13 @@ import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.FranchiseFeeMapper;
import com.cool.store.mapper.LineInfoMapper;
import com.cool.store.mapper.ShopInfoMapper;
import com.cool.store.request.FranchiseFeePayOnlineRequest;
import com.cool.store.request.LinePaySubmitRequest;
import com.cool.store.request.xgj.*;
import com.cool.store.request.xgj.ReceiptCallBackRequest;
import com.cool.store.request.xgj.ReceiptRequest;
import com.cool.store.response.FranchiseFeePayInfoResponse;
import com.cool.store.response.FranchiseFeePayOnlineResponse;
import com.cool.store.response.ReceivingBankResponse;
import com.cool.store.response.bigdata.ApiResponse;
import com.cool.store.service.LinePayService;
import com.cool.store.service.PushService;
import com.cool.store.service.ReceivingBankService;
import com.cool.store.service.UserAuthMappingService;
import com.cool.store.utils.CoolDateUtils;
import com.cool.store.utils.RedisConstantUtil;
@@ -39,7 +39,6 @@ import com.cool.store.vo.LinePayVO;
import com.cool.store.vo.PartnerUserInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@@ -53,7 +52,6 @@ import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.cool.store.enums.WorkflowSubStageStatusEnum.PAY_DEPOSIT_45;
import static com.cool.store.utils.poi.DateUtils.SPECIAL_DATE_START;
import static com.cool.store.utils.poi.DateUtils.YYYY_MM_DD_HH_MM_SS;
@@ -94,8 +92,6 @@ public class LinePayServiceImpl implements LinePayService {
RedisConstantUtil redisConstantUtil;
@Resource
PushService pushService;
@Resource
private ReceivingBankService receivingBankService;
@Override
public LinePayVO getLinePayInfo(Long lineId, Integer businessType, Long shopId) {
@@ -136,7 +132,7 @@ public class LinePayServiceImpl implements LinePayService {
if (lineInfo == null) {
throw new ServiceException(ErrorCodeEnum.LINE_ID_IS_NOT_EXIST);
}
if (!PAY_DEPOSIT_45.getCode().equals(lineInfo.getWorkflowSubStageStatus())) {
if (!WorkflowSubStageStatusEnum.PAY_DEPOSIT_45.getCode().equals(lineInfo.getWorkflowSubStageStatus())) {
throw new ServiceException(ErrorCodeEnum.LINE_STATUS_NOT_ALLOW_OPERATE);
}
lineInfo.setWorkflowSubStage(WorkflowSubStageEnum.SIGN_INTENT_AGREEMENT.getCode());
@@ -165,8 +161,7 @@ public class LinePayServiceImpl implements LinePayService {
if (StringUtils.isBlank(userId)) {
throw new ServiceException(ErrorCodeEnum.ACCESS_TOKEN_INVALID);
}
// doFilter(request.getShopId(),request.getAmount(),request.getId(),request.getPayUserName());
// FranchiseFeeDO franchiseFeeDO = franchiseFeeMapper.selectByShopId(request.getShopId());
FranchiseFeeDO franchiseFeeDO = franchiseFeeMapper.selectByShopId(request.getShopId());
//判断付款人最多2人可重复
List<LinePayDO> list = linePayDAO.getFranchiseFeePayInfoByShopId(request.getShopId());
Map<Long, LinePayDO> payIdMap = list.stream().collect(Collectors.toMap(LinePayDO::getId, Function.identity()));
@@ -221,7 +216,7 @@ public class LinePayServiceImpl implements LinePayService {
LinePayDO linePayById = linePayDAO.getById(linePayDO.getId());
if (linePayById == null) {
log.info("linePayById is null");
throw new ServiceException(ErrorCodeEnum.UPDATE_ERROR);
throw new ServiceException(ErrorCodeEnum.UPDATE_ERROR);
} else {
linePayDO.setUpdateTime(new Date());
linePayDO.setUpdateUserId(userId);
@@ -255,37 +250,6 @@ public class LinePayServiceImpl implements LinePayService {
}
}
private void doFilter(Long shopId,BigDecimal amount,Long payId,String payUserName) {
FranchiseFeeDO franchiseFeeDO = franchiseFeeMapper.selectByShopId(shopId);
//判断付款人最多2人可重复
List<LinePayDO> list = linePayDAO.getFranchiseFeePayInfoByShopId(shopId);
list=list.stream().filter(linePayDO -> !linePayDO.getPayStatus().equals(PayStatusEnum.CANCELED.getCode())
&&!linePayDO.getPayStatus().equals(PayStatusEnum.PAY_FAIL_55.getCode())).collect(Collectors.toList());
Map<Long, LinePayDO> payIdMap = list.stream().collect(Collectors.toMap(LinePayDO::getId, Function.identity()));
if (payId!= null) {
payIdMap.remove(payId);
}
//判断缴费金额不能大于未缴费金额
BigDecimal total = payIdMap.values().stream()
.map(LinePayDO::getAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
//应缴金额
BigDecimal amountDue = new BigDecimal(franchiseFeeDO.getYearFranchiseFee())
.add(new BigDecimal(franchiseFeeDO.getLoanMargin()))
.add(new BigDecimal(franchiseFeeDO.getFirstYearFee()))
.add(new BigDecimal(franchiseFeeDO.getFirstYearManageFee()))
.add(new BigDecimal(franchiseFeeDO.getPerformanceBond()));
//未缴费金额
BigDecimal amountUnpaid = amountDue.subtract(total);
if (amount.compareTo(amountUnpaid) > 0) {
throw new ServiceException(ErrorCodeEnum.PAY_AMOUNT_ERROR);
}
Set<String> payUserList = list.stream().map(LinePayDO::getPayUserName).collect(Collectors.toSet());
if (!payUserList.contains(payUserName) && payUserList.size() >= 2) {
throw new ServiceException(ErrorCodeEnum.PAY_USER_NAME_ERROR);
}
}
@Override
public String getPaymentReceiptCode() {
//当前日期
@@ -350,18 +314,6 @@ public class LinePayServiceImpl implements LinePayService {
return Boolean.TRUE;
}
@Override
public Boolean onlinePushPayInfo(Long shopId, LinePayDO linePayDO) {
FranchiseFeeDO franchiseFeeDO = franchiseFeeMapper.selectByShopId(shopId);
ReceivingBankResponse receivingBankResponse = receivingBankService.getByShopId(shopId);
ReceiptOnlineRequest receiptOnlineRequest = new ReceiptOnlineRequest(shopId, franchiseFeeDO.getId().intValue(), linePayDO);
receiptOnlineRequest.setPayee(receivingBankResponse.getPayee());
receiptOnlineRequest.setReceivingAccount(receivingBankResponse.getReceivingAccount());
receiptOnlineRequest.setBankName(receivingBankResponse.getBankName());
receiptOnlineRequest.setBranchBankName(receivingBankResponse.getBranchBankName());
return pushService.pushOnlineReceiptToXGJ(receiptOnlineRequest);
}
@Override
@Transactional(rollbackFor = Exception.class)
public ApiResponse<Boolean> ReceiptCallBack(ReceiptCallBackRequest request) {
@@ -370,139 +322,11 @@ public class LinePayServiceImpl implements LinePayService {
return ApiResponse.error(ErrorCodeEnum.RECEIPT_NOT_EXIST);
}
linePayDO.setXgjClaimStatus(request.getClaimStatus());
if (StringUtils.isNotEmpty(request.getFailReason())){
linePayDO.setXgjFailReason(request.getFailReason());
}
linePayDO.setUpdateTime(new Date());
linePayDAO.updateLinePay(linePayDO);
return ApiResponse.success(Boolean.TRUE);
}
@Override
public ApiResponse<Boolean> changeOnlinePayInfo(OnlinePayInfoRequest onlinePayInfoRequest) {
if (PayStatusEnum.FEES_HAVE_BEEN_PAID_50.getCode().equals(onlinePayInfoRequest.getPaymentStatus())&&StringUtils.isEmpty(onlinePayInfoRequest.getPaySerialNumber())&&
ObjectUtils.anyNull(onlinePayInfoRequest.getActAmount(),onlinePayInfoRequest.getPayTime())){
return ApiResponse.error(ErrorCodeEnum.PARAMS_REQUIRED);
}
//根据收款单编号查询
LinePayDO linePayDO = linePayDAO.selectByPaymentReceiptCode(onlinePayInfoRequest.getReceiptId());
if (Objects.isNull(linePayDO)) {
return ApiResponse.error(ErrorCodeEnum.RECEIPT_NOT_EXIST);
}
linePayDO.setPayStatus(onlinePayInfoRequest.getPaymentStatus());
linePayDO.setPayTime(onlinePayInfoRequest.getPayTime());
linePayDO.setPaySerialNumber(onlinePayInfoRequest.getPaySerialNumber());
linePayDO.setXgjClaimStatus(onlinePayInfoRequest.getClaimStatus());
linePayDO.setAmount(onlinePayInfoRequest.getActAmount());
linePayDAO.updateLinePay(linePayDO);
return ApiResponse.success(Boolean.TRUE);
}
@Override
@Transactional(rollbackFor = Exception.class)
public FranchiseFeePayOnlineResponse franchiseFeePayOnline(FranchiseFeePayOnlineRequest request, String userId) {
if (request.getId()!=null){
throw new ServiceException(ErrorCodeEnum.NOT_ALLOW_OPERATE);
}
String lockKey = "submitFranchiseFeePayInfoOnline:lineId" + request.getLineId() + "shopId" + request.getShopId();
doFilter(request.getShopId(),request.getAmount(),request.getId(),request.getPayUserName());
ShopStageInfoDO shopSubStageInfo = shopStageInfoDAO.getShopSubStageInfo(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_7);
if (!shopSubStageInfo.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_72.getShopSubStageStatus())
&& !shopSubStageInfo.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_71.getShopSubStageStatus())) {
throw new ServiceException(ErrorCodeEnum.NOT_ALLOW_OPERATE);
}
//流水
String lockValue = UUID.randomUUID().toString();
boolean acquired = false;
try {
//10s过期
acquired = redisUtilPool.setNxExpire(lockKey, lockValue, CommonConstants.TEN_SECONDS);
if (Boolean.TRUE.equals(acquired)) {
LineInfoDO lineInfo = lineInfoDAO.getLineInfo(request.getLineId());
FranchiseFeePayOnlineResponse response = new FranchiseFeePayOnlineResponse();
response.setShopId(request.getShopId());
//新增
if (request.getId() == null) {
LinePayDO linePayDO = new LinePayDO();
linePayDO.setShopId(request.getShopId());
linePayDO.setLineId(request.getLineId());
linePayDO.setAmount(request.getAmount());
linePayDO.setPayBusinessType(PayBusinessTypeEnum.FRANCHISE_FEE.getCode());
linePayDO.setPartnerId(lineInfo.getPartnerId());
linePayDO.setPayStatus(PayStatusEnum.WAIT_PAY_45.getCode());
linePayDO.setPayType(PayTypeEnum.ONLINE_PAY.getCode());
linePayDO.setPayUserName(request.getPayUserName());
linePayDO.setCreateUserId(userId);
linePayDO.setCreateTime(new Date());
linePayDO.setXgjClaimStatus(ClaimStatusEnum.TO_BE_CLAIMED.getCode());
linePayDO.setPaymentReceiptCode(this.getPaymentReceiptCode());
linePayDO.setDeleted(false);
linePayDAO.addLinePay(linePayDO);
response.setPaymentReceiptCode(linePayDO.getPaymentReceiptCode());
//推送收款单到新管家
this.onlinePushPayInfo(request.getShopId(),linePayDO);
}else{
//修改
LinePayDO linePayDO = linePayDAO.getById(request.getId());
if (linePayDO == null){
throw new ServiceException(ErrorCodeEnum.UPDATE_ERROR);
}
if (linePayDO.getXgjClaimStatus().equals(ClaimStatusEnum.CLAIMED.getCode())){
throw new ServiceException(ErrorCodeEnum.CLAIM_STATUS_ERROR);
}
if (linePayDO.getPayStatus().equals(PayStatusEnum.CANCELED.getCode())
||linePayDO.getPayStatus().equals(PayStatusEnum.FEES_HAVE_BEEN_PAID_50.getCode())){
throw new ServiceException(ErrorCodeEnum.NOT_ALLOW_OPERATE);
}
linePayDO.setUpdateTime(new Date());
linePayDO.setPayStatus(PayStatusEnum.WAIT_PAY_45.getCode());
linePayDO.setPayUserName(request.getPayUserName());
linePayDO.setUpdateUserId(userId);
linePayDO.setAmount(request.getAmount());
//如果是认领失败状态的时候 修改需要将状态置为待认领
if (linePayDO.getXgjClaimStatus().equals(ClaimStatusEnum.CLAIMED_FAIL.getCode())){
linePayDO.setXgjClaimStatus(ClaimStatusEnum.TO_BE_CLAIMED.getCode());
}
linePayDAO.updateLinePay(linePayDO);
response.setPaymentReceiptCode(linePayDO.getPaymentReceiptCode());
//推送数据
this.onlinePushPayInfo(request.getShopId(),linePayDO);
}
if (shopSubStageInfo.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_71.getShopSubStageStatus())) {
shopStageInfoDAO.updateShopStageInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_72);
}
return response;
} else {
throw new ServiceException(ErrorCodeEnum.DUPLICATE_SUBMISSION);
}
} finally {
if (Boolean.TRUE.equals(acquired)) {
String currentValue = redisUtilPool.getString(lockKey);
if (lockValue.equals(currentValue)) {
redisUtilPool.delKey(lockKey);
}
}
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean cancelFranchiseFeePayOnline(Long id, String userId) {
LinePayDO linePay = linePayDAO.getById(id);
if (linePay == null) {
throw new ServiceException(ErrorCodeEnum.DELETE_ERROR);
}
if (linePay.getXgjClaimStatus().equals(ClaimStatusEnum.CLAIMED.getCode())){
throw new ServiceException(ErrorCodeEnum.CLAIM_STATUS_ERROR);
}
linePay.setPayStatus(PayStatusEnum.CANCELED.getCode());
linePayDAO.updateLinePay(linePay);
//取消支付
this.onlinePushPayInfo(linePay.getShopId(),linePay);
return true;
}
@Override
public FranchiseFeePayInfoResponse getById(Long id) {

View File

@@ -80,9 +80,9 @@ public class MessageTemplateServiceImpl implements MessageTemplateService {
@Resource
TaskExecutor noticeThreadPool;
@Resource
MessageIssueService messageIssueService;
@Resource
HyPartnerUserInfoDAO hyPartnerUserInfoDAO;
@Resource
MessageIssueService messageIssueService;

View File

@@ -23,7 +23,6 @@ import com.cool.store.enums.point.ShopSubStageStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.PostAndOrderRequest;
import com.cool.store.request.xgj.FranchiseFeeCallBackRequest;
import com.cool.store.request.xgj.OnlinePayInfoRequest;
import com.cool.store.request.xgj.ReceiptCallBackRequest;
import com.cool.store.response.bigdata.ApiResponse;
import com.cool.store.service.FranchiseFeeService;
@@ -140,9 +139,4 @@ public class OpenApiServiceImpl implements OpenApiService {
public ApiResponse<Boolean> changePaymentStatus(FranchiseFeeCallBackRequest request) {
return franchiseFeeService.changePaymentStatus(request);
}
@Override
public ApiResponse<Boolean> changeOnlinePayInfo(OnlinePayInfoRequest onlinePayInfoRequest) {
return linePayService.changeOnlinePayInfo(onlinePayInfoRequest);
}
}

View File

@@ -19,11 +19,8 @@ import com.cool.store.enums.point.ShopSubStageStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.UserAuthMappingMapper;
import com.cool.store.request.OpeningOperationPlanRequest;
import com.cool.store.request.OrderSummaryRequest;
import com.cool.store.request.PlanListRequest;
import com.cool.store.response.OrderSummaryResponse;
import com.cool.store.service.*;
import com.cool.store.utils.poi.DateUtils;
import com.cool.store.utils.poi.StringUtils;
import com.cool.store.vo.OpeningOperationPlanListVO;
import com.cool.store.vo.OpeningOperationPlanVO;
@@ -35,7 +32,6 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
@@ -69,8 +65,6 @@ public class OpeningOperationPlanImpl implements OpeningOperationPlanService {
private LineInfoDAO lineInfoDAO;
@Resource
private ShopService shopService;
@Resource
HuoMaService huoMaService;
@Resource
UserAuthMappingService userAuthMappingService;
@@ -85,7 +79,10 @@ public class OpeningOperationPlanImpl implements OpeningOperationPlanService {
log.error("addNewPlan ActivityTheme length error");
throw new ServiceException(ErrorCodeEnum.ACTIVITY_THEME_LENGTH_FALSE);
}
ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(request.getShopId());
if (request.getSurveyResult().length() > CommonConstants.MAX_LENGTH_ONE_HUNDRED) {
log.error("addNewPlan SurveyResult length error");
throw new ServiceException(ErrorCodeEnum.SURVEYRESULT_LENGTH_FALSE);
}
String userId = userInfo.getUserId();
OpeningOperationPlanDO selectByShopId = openingOperationPlanDAO.selectByShopId(request.getShopId());
Long planId;
@@ -98,10 +95,6 @@ public class OpeningOperationPlanImpl implements OpeningOperationPlanService {
openingOperationPlanDO.setId(selectByShopId.getId());
openingOperationPlanDO.setUpdateTime(new Date());
openingOperationPlanDO.setUpdateUserId(userId);
//如果开业时间调整 需要重新获取数据 时间相同不需要拉取数据
if (!DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,request.getOpenTime()).equals(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,selectByShopId.getOpenTime()))){
getIncome(shopInfo.getShopCode(),openingOperationPlanDO);
}
planId = openingOperationPlanDAO.updateSelective(openingOperationPlanDO);
} else {
//新增
@@ -109,11 +102,32 @@ public class OpeningOperationPlanImpl implements OpeningOperationPlanService {
openingOperationPlanDO.setSubmittedUserId(userId);
openingOperationPlanDO.setCreateTime(new Date());
openingOperationPlanDO.setCreateUserId(userId);
getIncome(shopInfo.getShopCode(),openingOperationPlanDO);
planId = openingOperationPlanDAO.insertSelective(openingOperationPlanDO);
}
shopStageInfoDAO.updateShopStageInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_143);
shopStageInfoDAO.updateShopStageInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_141);
ShopInfoDO shopInfoDO = shopInfoDAO.getShopInfo(request.getShopId());
LineInfoDO lineInfoDO = lineInfoDAO.getLineInfo(shopInfoDO.getLineId());
Set<String> planAuditUser = new HashSet<>();
List<EnterpriseUserDO> regionManagerUser = userAuthMappingService.getAllUserByRoleEnumAndRegionId(UserRoleEnum.REGION_MANAGER, shopInfoDO.getRegionId());
if (Objects.nonNull(regionManagerUser)){
Set<String> regionManagerUserIds = regionManagerUser.stream().map(EnterpriseUserDO::getUserId).collect(Collectors.toSet());
planAuditUser.addAll(regionManagerUserIds);
}
List<EnterpriseUserDO> regionalManager = userAuthMappingService.getAllUserByRoleEnumAndRegionId(UserRoleEnum.REGIONAL_MANAGER, shopInfoDO.getRegionId());
if (Objects.nonNull(regionalManager)){
Set<String> regionalManagerUserIds = regionalManager.stream().map(EnterpriseUserDO::getUserId).collect(Collectors.toSet());
planAuditUser.addAll(regionalManagerUserIds);
}
HashMap<String, String> map = new HashMap<>();
map.put("partnerUsername",lineInfoDO.getUsername());
map.put("partnerMobile",lineInfoDO.getMobile());
map.put("storeName",shopInfoDO.getShopName());
commonService.sendQWMessage(new ArrayList<>(planAuditUser),
MessageEnum.MESSAGE_42,
map);
return planId;
}
@Override
@@ -127,9 +141,21 @@ public class OpeningOperationPlanImpl implements OpeningOperationPlanService {
ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
OpeningOperationPlanDO openingOperationPlanDO = openingOperationPlanDAO.selectByShopId(shopId);
EnterpriseUserDO userInfoById = enterpriseUserDAO.getUserInfoById(shopInfo.getSupervisorUserId());
List<EnterpriseUserDO> allUserByRoleEnumAndRegionId = userAuthMappingService.getAllUserByRoleEnumAndRegionId(UserRoleEnum.OPERATIONS_MANAGER, shopInfo.getRegionId());
List<String> collect = new ArrayList<>();
if (CollectionUtils.isEmpty(allUserByRoleEnumAndRegionId)){
collect = null;
}else {
collect = allUserByRoleEnumAndRegionId.stream()
.filter(user -> user.getName() != null)
.map(user -> user.getName())
.collect(Collectors.toList());
}
if (Objects.nonNull(openingOperationPlanDO)) {
openingOperationPlanVO = new OpeningOperationPlanVO(openingOperationPlanDO);
openingOperationPlanVO.setSubmiter(Objects.isNull(userInfoById) ? null : userInfoById.getName());
openingOperationPlanVO.setApprover(CollectionUtils.isEmpty(collect) ? null : collect.stream().collect(Collectors.joining(",")));
String preparationUserIds = openingOperationPlanDO.getPreparationUserIds();
if (StringUtils.isNotBlank(preparationUserIds)){
List<String> stream = Arrays.stream(preparationUserIds.split(CommonConstants.COMMA)).collect(Collectors.toList());
@@ -139,71 +165,14 @@ public class OpeningOperationPlanImpl implements OpeningOperationPlanService {
String userName = enterpriseUserDAO.getUserName(openingOperationPlanDO.getSubmittedUserId());
openingOperationPlanVO.setSubmittedUserName(userName);
openingOperationPlanVO.setShopName(shopInfo.getShopName());
if (StringUtils.isAnyEmpty(openingOperationPlanDO.getFirstDayIncome(),openingOperationPlanDO.getSecondDayIncome(),openingOperationPlanDO.getThirdDayIncome())){
getIncome(shopInfo.getShopCode(),openingOperationPlanDO);
openingOperationPlanDAO.updateSelective(openingOperationPlanDO);
}
openingOperationPlanVO.setFirstDayIncome(openingOperationPlanDO.getFirstDayIncome());
openingOperationPlanVO.setSecondDayIncome(openingOperationPlanDO.getSecondDayIncome());
openingOperationPlanVO.setThirdDayIncome(openingOperationPlanDO.getThirdDayIncome());
return openingOperationPlanVO;
}
openingOperationPlanVO.setSubmiter(Objects.isNull(userInfoById) ? null : userInfoById.getName());
openingOperationPlanVO.setApprover(CollectionUtils.isEmpty(collect) ? null : collect.stream().collect(Collectors.joining(",")));
return openingOperationPlanVO;
}
private OpeningOperationPlanDO getIncome(String code,OpeningOperationPlanDO openingOperationPlanDO){
if (openingOperationPlanDO.getOpenTime()==null||StringUtils.isEmpty(code)){
return openingOperationPlanDO;
}
OrderSummaryRequest orderSummaryRequest = new OrderSummaryRequest();
orderSummaryRequest.setType("1");
orderSummaryRequest.setShop_sn(code);
//当前日期
try {
String dateStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, openingOperationPlanDO.getOpenTime());
if (StringUtils.isEmpty(openingOperationPlanDO.getFirstDayIncome())||"0.00".equals(openingOperationPlanDO.getFirstDayIncome())){
orderSummaryRequest.setStart_date(dateStr);
orderSummaryRequest.setEnd_date(dateStr);
OrderSummaryResponse orderSummary = huoMaService.getOrderSummary(orderSummaryRequest);
//第一天收入
BigDecimal firstDay = OrderSummaryResponse.calculateExpectedIncome(orderSummary);
openingOperationPlanDO.setFirstDayIncome(firstDay.toString());
}
//当前日期加1
String dateStr1 = DateUtils.getPlusFDays(openingOperationPlanDO.getOpenTime(), 1).toString();
if (StringUtils.isEmpty(openingOperationPlanDO.getSecondDayIncome())||"0.00".equals(openingOperationPlanDO.getSecondDayIncome())){
orderSummaryRequest.setStart_date(dateStr1);
orderSummaryRequest.setEnd_date(dateStr1);
OrderSummaryResponse orderSummary = huoMaService.getOrderSummary(orderSummaryRequest);
//第一天收入
BigDecimal secondDay = OrderSummaryResponse.calculateExpectedIncome(orderSummary);
openingOperationPlanDO.setSecondDayIncome(secondDay.toString());
}
//当前日期加2
String dateStr2 = DateUtils.getPlusFDays(openingOperationPlanDO.getOpenTime(), 2).toString();
if (StringUtils.isEmpty(openingOperationPlanDO.getThirdDayIncome())||"0.00".equals(openingOperationPlanDO.getThirdDayIncome())){
orderSummaryRequest.setStart_date(dateStr2);
orderSummaryRequest.setEnd_date(dateStr2);
OrderSummaryResponse orderSummary = huoMaService.getOrderSummary(orderSummaryRequest);
//第一天收入
BigDecimal thirdDay = OrderSummaryResponse.calculateExpectedIncome(orderSummary);
openingOperationPlanDO.setThirdDayIncome(thirdDay.toString());
}
} catch (Exception e) {
log.error("收入查询失败:{}",e.getMessage());
return openingOperationPlanDO;
}
return openingOperationPlanDO;
}
@Override
@Deprecated
public PageInfo<OpeningOperationPlanListVO> getPlanListPage(PlanListRequest request) {
log.info("getPlanListPage request:{}", JSONObject.toJSONString(request));
if (!sysRoleService.checkIsAdmin(request.getCurUserId())) {

View File

@@ -235,30 +235,6 @@ public class OperationLogServiceImpl implements OperationLogService {
return operationLogDAO.batchUpdateByPrimaryKeySelective(operationLogList);
}
@Override
public Boolean handleApproveTimeNoDate(Long shopId,ShopSubStageStatusEnum subStageStatusEnum, Long audit, String userId, String reason) {
OperationLogDO operationLogDO = new OperationLogDO();
operationLogDO.setOperator(userId);
operationLogDO.setAuditResultId(audit);
operationLogDO.setRemarks(reason);
operationLogDO.setShopId(shopId);
operationLogDO.setShopSubStage(subStageStatusEnum.getShopSubStageEnum().getShopSubStage());
operationLogDO.setShopSubStageStatus(subStageStatusEnum.getShopSubStageStatus());
operationLogDO.setStatus(OperationStatusEnum.PROCESSED.getCode());
operationLogDO.setType(OperationTypeEnum.OPERATION_TYPE_1.getCode());
String userName = enterpriseUserDAO.getUserName(userId);
if (StringUtils.isNotBlank(userName)) {
operationLogDO.setOperatorName(userName);
}
Date createTime = new Date();
Date updateTime = new Date();
operationLogDO.setCreateTime(createTime);
operationLogDO.setUpdateTime(updateTime);
operationLogDO.setCreateUserId(userId);
operationLogDAO.addOperationLog(operationLogDO);
return Boolean.TRUE;
}
}

View File

@@ -51,7 +51,8 @@ import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.cool.store.enums.point.ShopSubStageStatusEnum.*;
import static com.cool.store.enums.point.ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_21;
import static com.cool.store.enums.point.ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_21_5;
/**
* @author zhangchenbiao
@@ -105,10 +106,6 @@ public class PointServiceImpl implements PointService {
private String enterpriseId;
@Resource
SysRoleMapper sysRoleMapper;
@Resource
OperationLogService operationLogService;
@Resource
OperationLogDAO operationLogDAO;
@Resource
PointFinancialDataDAO pointFinancialDataDAO;
@@ -1198,13 +1195,14 @@ public class PointServiceImpl implements PointService {
}
@Override
public Integer uploadRentContract(AddRentContractRequest request,String userId,String userName) {
public Integer uploadRentContract(AddRentContractRequest request) {
if (!request.check()) {
throw new ServiceException(ErrorCodeEnum.PARAMS_VALIDATE_ERROR);
}
Long pointId = request.getPointId(), shopId = request.getShopId();
ShopInfoDO shopInfo = shopInfo = shopInfoDAO.getShopInfo(shopId);;
ShopInfoDO shopInfo = null;
if (Objects.isNull(pointId) && Objects.nonNull(shopId)) {
shopInfo = shopInfoDAO.getShopInfo(shopId);
pointId = shopInfo.getPointId();
}
if (Objects.nonNull(pointId) && Objects.isNull(shopId)) {
@@ -1241,13 +1239,6 @@ public class PointServiceImpl implements PointService {
MessageEnum.MESSAGE_15,
map);
}
// 审批记录
operationLogService.addOperationLog(shopId, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_20, userId, userName,
OperationTypeEnum.OPERATION_TYPE_0, "加盟商上传租赁合同", OperationStatusEnum.PROCESSED);
List<EnterpriseUserDO> userDOList = userAuthMappingService.getAllUserByRoleEnumAndRegionId(UserRoleEnum.REGION_MANAGER, shopInfo.getInvestRegionId());
operationLogService.addOperationLog(shopId, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_21,
userId, userDOList,
OperationTypeEnum.OPERATION_TYPE_1, "招商片区老总审核", OperationStatusEnum.NOT_PROCESSED);
return shopStageInfoDAO.updateShopStageInfo(shopId, SHOP_SUB_STAGE_STATUS_21);
}
@@ -1295,8 +1286,6 @@ public class PointServiceImpl implements PointService {
Long auditId = shopAuditInfoDAO.addAuditInfo(AuditRentContractRequest.convert(request, AuditTypeEnum.UPLOAD_RENT_CONTRACT));
ShopSubStageStatusEnum subStageStatus = null;
Integer current = shopStageInfo.getShopSubStageStatus();
ShopSubStageStatusEnum currentShopSubStageStatusEnum = getShopSubStageStatusEnum(current);
if (AuditResultTypeEnum.PASS.getCode().equals(request.getResultType())){
if (shopStageInfo.getShopSubStageStatus().equals(SHOP_SUB_STAGE_STATUS_21.getShopSubStageStatus())){
subStageStatus = SHOP_SUB_STAGE_STATUS_21_5;
@@ -1307,16 +1296,6 @@ public class PointServiceImpl implements PointService {
}else {
subStageStatus = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_22;
}
//处理审批
handleApprove(shopId,AuditTypeEnum.UPLOAD_RENT_CONTRACT,request.getOperateUserId(),request.getOperateUserName(),
request.getResultType(),currentShopSubStageStatusEnum,request.getReason());
//如果有下一级
if (SHOP_SUB_STAGE_STATUS_21.getShopSubStageStatus().equals(currentShopSubStageStatusEnum.getShopSubStageStatus())){
List<EnterpriseUserDO> userDOList = userAuthMappingService.getAllUserByRoleEnumAndRegionId(UserRoleEnum.BRANCH_OFFICE, shopInfo.getInvestRegionId());
operationLogService.addOperationLog(shopId, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_21_5,
request.getOperateUserId(), userDOList,
OperationTypeEnum.OPERATION_TYPE_1, "分部内勤审核", OperationStatusEnum.NOT_PROCESSED);
}
if (ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_23.equals(subStageStatus)) {
//审核通过铺位变为已签约
@@ -1345,41 +1324,6 @@ public class PointServiceImpl implements PointService {
return CommonConstants.ONE;
}
/**
* 处理审批
* @param shopId
* @param auditTypeEnum
* @param userId
* @param userName
* @param resultType
* @param currentStatusEnum
* @param cause
* @return
*/
private Boolean handleApprove(Long shopId,AuditTypeEnum auditTypeEnum,String userId,String userName,Integer resultType,ShopSubStageStatusEnum currentStatusEnum,String cause){
ShopAuditInfoDO shopAuditInfoDO = new ShopAuditInfoDO();
shopAuditInfoDO.setShopId(shopId);
shopAuditInfoDO.setAuditType(auditTypeEnum.getCode());
shopAuditInfoDO.setSubmittedUserId(userId);
shopAuditInfoDO.setSubmittedUserName(userName);
shopAuditInfoDO.setResultType(resultType);
if (AuditResultTypeEnum.PASS.getCode().equals(shopAuditInfoDO.getResultType())) {
shopAuditInfoDO.setPassReason(cause);
} else {
shopAuditInfoDO.setRejectReason(cause);
}
Long auditId = shopAuditInfoDAO.addAuditInfo(shopAuditInfoDO);
//更新操作记录
List<OperationLogDO> operationLogs = operationLogDAO.getBySubStageStatusEnumAndsStatus(shopId, currentStatusEnum, OperationTypeEnum.OPERATION_TYPE_1.getCode());
if (CollectionUtils.isNotEmpty(operationLogs)){
operationLogService.batchUpdateProcessed(operationLogs, auditId, userId, cause);
}else {
operationLogService.handleApproveTimeNoDate(shopId,currentStatusEnum,auditId, userId, cause);
}
return true;
}
@Override
public Integer updateRentContract(UpdateRentContractRequest request) {
if (!request.check()) {

View File

@@ -212,28 +212,6 @@ public class PreparationServiceImpl implements PreparationService {
}
}
@Override
public void decorationCompletion(Long shopId) {
List<ShopStageInfoDO> shopStageInfo = shopStageInfoDAO.getShopStageInfo(shopId, null);
if (CollectionUtils.isNotEmpty(shopStageInfo)) {
Map<Integer, ShopStageInfoDO> shopStageInfoDOMap = shopStageInfo.stream().collect(Collectors.toMap(ShopStageInfoDO::getShopSubStage, data -> data));
Boolean flag2 = ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_123.getShopSubStageStatus().
equals(shopStageInfoDOMap.get(ShopSubStageEnum.SHOP_STAGE_12.getShopSubStage()).getShopSubStageStatus());
//如果阶段已经初始化过 直接跳过 针对老数据
if(shopStageInfoDOMap.get(ShopSubStageEnum.SHOP_STAGE_14.getShopSubStage()).getShopSubStageStatus()
>ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_140.getShopSubStageStatus()){
return;
}
if (flag2){
List<ShopSubStageStatusEnum> list = new ArrayList<>();
list.add(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_140);
shopStageInfoDAO.batchUpdateShopStageStatus(shopId, list);
}
}
}
@Override
public void sysStoreCompleted(Long shopId) {
List<ShopStageInfoDO> shopStageInfo = shopStageInfoDAO.getShopStageInfo(shopId, null);

View File

@@ -16,9 +16,7 @@ import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.UserRoleEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.ZxjpApiRequest;
import com.cool.store.request.xgj.CancelPayRequest;
import com.cool.store.request.xgj.PushFranchiseFeeRequest;
import com.cool.store.request.xgj.ReceiptOnlineRequest;
import com.cool.store.request.xgj.ReceiptRequest;
import com.cool.store.response.XgjAccessTokenDTO;
import com.cool.store.response.XgjBaseResponse;
@@ -155,12 +153,6 @@ public class PushServiceImpl implements PushService {
return executePostApiCall(apiUrl, request, Boolean.class, xgjUsername, xgjSecret,getXgjAccessToken().getAccess_token());
}
@Override
public Boolean pushOnlineReceiptToXGJ(ReceiptOnlineRequest receiptRequest) {
String apiUrl = xgjUrl + "/dmp/dmp-join/open/franchiseeReceipts/online";
return executePostApiCall(apiUrl, receiptRequest, Boolean.class, xgjUsername, xgjSecret,getXgjAccessToken().getAccess_token());
}
@Override
public Boolean pushDataToPOS(ZxjpApiRequest zxjpApiRequest) {
String apiUrl = url + "/dzgV1/zxcrm/shop/upsert";
@@ -305,7 +297,7 @@ public class PushServiceImpl implements PushService {
}
String responseBody = response.body().string();
log.info("getUnReadMessageNum response num{}", responseBody);
return Integer.valueOf(responseBody)+100;
return Integer.valueOf(responseBody);
} catch (Exception e) {
log.error("API调用异常 - URL: {}, 错误: {}", url, e.getMessage(), e);
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR, "接口调用异常: " + e.getMessage());

View File

@@ -1,139 +0,0 @@
package com.cool.store.service.impl;
import com.cool.store.dao.*;
import com.cool.store.entity.BigRegionDO;
import com.cool.store.entity.FranchiseFeeDO;
import com.cool.store.entity.ReceivingBankDO;
import com.cool.store.entity.ShopInfoDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.point.PayTypeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.FranchiseFeeMapper;
import com.cool.store.request.ReceivingBankListRequest;
import com.cool.store.request.ReceivingBankRequest;
import com.cool.store.response.ReceivingBankResponse;
import com.cool.store.service.ReceivingBankService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
* @Author: WangShuo
* @Date: 2025/06/18/17:53
* @Version 1.0
* @注释:
*/
@Service
public class ReceivingBankServiceImpl implements ReceivingBankService {
@Resource
private ReceivingBankDAO receivingBankDAO;
@Resource
private RegionDao regionDao;
@Resource
private BigRegionDAO bigRegionDAO;
@Resource
private EnterpriseUserDAO enterpriseUserDAO;
@Resource
private ShopInfoDAO shopInfoDAO;
@Resource
private FranchiseFeeMapper franchiseFeeMapper;
@Override
public Integer submit(ReceivingBankRequest request, String userId) {
ReceivingBankDO receivingBankDO = new ReceivingBankDO();
receivingBankDO.setRegionId(request.getRegionId());
receivingBankDO.setFranchiseBrand(Integer.parseInt(request.getFranchiseBrand()));
receivingBankDO.setPayee(request.getPayee());
receivingBankDO.setPayType(request.getPayType());
receivingBankDO.setReceivingAccount(request.getReceivingAccount());
receivingBankDO.setBankName(request.getBankName());
receivingBankDO.setBranchBankName(request.getBranchBankName());
if (request.getId() == null) {
receivingBankDO.setCreateTime(new Date());
receivingBankDO.setCreateUser(userId);
} else {
receivingBankDO.setId(request.getId());
receivingBankDO.setUpdateTime(new Date());
receivingBankDO.setUpdateUser(userId);
}
return receivingBankDAO.batchInsertOrUpdate(Collections.singletonList(receivingBankDO));
}
@Override
public PageInfo<ReceivingBankResponse> getByFranchiseBrandAndRegionId(ReceivingBankListRequest request) {
PageHelper.startPage(request.getPageNum(),request.getPageSize());
List<ReceivingBankDO> list = receivingBankDAO.getByFranchiseBrandAndRegionId(request.getFranchiseBrandList(),request.getRegionIdList());
if (CollectionUtils.isEmpty(list)){
return new PageInfo<>();
}
PageInfo pageInfo = new PageInfo<>(list);
List<ReceivingBankResponse> responses = new ArrayList<>();
Set<Long> regionSet = list.stream().filter(Objects::nonNull).map(ReceivingBankDO::getRegionId).collect(Collectors.toSet());
Set<String> userIds = list.stream().filter(Objects::nonNull).map(ReceivingBankDO::getCreateUser).collect(Collectors.toSet());
userIds.addAll(list.stream().filter(Objects::nonNull).map(ReceivingBankDO::getUpdateUser).collect(Collectors.toSet()));
Map<String, String> userNameMap = enterpriseUserDAO.getUserNameMap(new ArrayList<>(userIds));
Map<Long, String> regionNameMap = regionDao.getRegionNameMap(new ArrayList<>(regionSet));
Map<Long, BigRegionDO> bigRegionMap = bigRegionDAO.getMapByRegionIds(new ArrayList<>(regionSet));
for (ReceivingBankDO x:list){
ReceivingBankResponse response = new ReceivingBankResponse();
response.setId(x.getId());
response.setRegionId(x.getRegionId());
response.setRegionName(regionNameMap.getOrDefault(x.getRegionId(),""));
response.setGroup(bigRegionMap.getOrDefault(x.getRegionId(),new BigRegionDO()).getGroupName());
response.setFranchiseBrand(x.getFranchiseBrand().toString());
response.setPayType(x.getPayType());
response.setPayee(x.getPayee());
response.setReceivingAccount(x.getReceivingAccount());
response.setBankName(x.getBankName());
response.setBranchBankName(x.getBranchBankName());
response.setCreateUserName(userNameMap.getOrDefault(x.getCreateUser(),""));
response.setUpdateUserName(userNameMap.getOrDefault(x.getUpdateUser(),""));
response.setCreateTime(x.getCreateTime());
response.setUpdateTime(x.getUpdateTime());
responses.add(response);
}
pageInfo.setList(responses);
return pageInfo;
}
@Override
public ReceivingBankResponse getByShopId(Long shopId) {
ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
if (shopInfo.getRegionId()==null){
throw new ServiceException(ErrorCodeEnum.SHOP_REGION_NOT_EXIST);
}
if (StringUtils.isBlank(shopInfo.getFranchiseBrand())){
throw new ServiceException(ErrorCodeEnum.SHOP_FRANCHISE_BRAND_NOT_EXITS);
}
FranchiseFeeDO franchiseFeeDO = franchiseFeeMapper.selectByShopId(shopId);
if (franchiseFeeDO == null){
throw new ServiceException(ErrorCodeEnum.UNISSUED_STATEMENT);
}
if (franchiseFeeDO.getPayType() == null
|| (!franchiseFeeDO.getPayType().equals(PayTypeEnum.ONLINE_PAY.getCode())
&&!franchiseFeeDO.getPayType().equals(PayTypeEnum.OFFLINE_PAY.getCode()) )){
throw new ServiceException(ErrorCodeEnum.PAY_TYPE_NOT_EXIST);
}
List<ReceivingBankDO> receivingBankDOList = receivingBankDAO.getByRegionAndFranchiseBrandAndPayType(shopInfo.getRegionId(), Integer.parseInt(shopInfo.getFranchiseBrand()), franchiseFeeDO.getPayType());
if (CollectionUtils.isEmpty(receivingBankDOList)){
throw new ServiceException(ErrorCodeEnum.RECEIVING_BANK_NOT_EXIST);
}
if (receivingBankDOList.size() > 1){
throw new ServiceException(ErrorCodeEnum.THERE_ARE_SEVERAL_RECEIVING_BANK);
}
ReceivingBankResponse response= new ReceivingBankResponse();
response.setPayType(receivingBankDOList.get(0).getPayType());
response.setPayee(receivingBankDOList.get(0).getPayee());
response.setReceivingAccount(receivingBankDOList.get(0).getReceivingAccount());
response.setBankName(receivingBankDOList.get(0).getBankName());
response.setBranchBankName(receivingBankDOList.get(0).getBranchBankName());
return response;
}
}

View File

@@ -52,7 +52,6 @@ import java.util.stream.Stream;
import static com.cool.store.enums.ErrorCodeEnum.*;
import static com.cool.store.enums.UserRoleEnum.*;
import static com.cool.store.enums.WorkflowSubStageStatusEnum.*;
import static com.cool.store.enums.point.ShopSubStageEnum.SHOP_STAGE_8;
import static com.cool.store.enums.point.ShopSubStageEnum.SHOP_STAGE_15;
import static com.cool.store.enums.point.ShopSubStageEnum.SHOP_STAGE_8;
@@ -944,6 +943,8 @@ public class ShopServiceImpl implements ShopService {
case SHOP_SUB_STAGE_STATUS_11:
case SHOP_SUB_STAGE_STATUS_50:
case SHOP_SUB_STAGE_STATUS_140:
case SHOP_SUB_STAGE_STATUS_141:
case SHOP_SUB_STAGE_STATUS_142:
case SHOP_SUB_STAGE_STATUS_171:
case SHOP_SUB_STAGE_STATUS_270:
case SHOP_SUB_STAGE_STATUS_274:

View File

@@ -6,7 +6,6 @@ import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.CommonConstants;
import com.cool.store.constants.RedisConstant;
import com.cool.store.constants.DictConstants;
import com.cool.store.constants.RedisConstant;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.*;
import com.cool.store.dao.fees.WalletPayInfoDAO;
@@ -484,9 +483,6 @@ public class SignFranchiseServiceImpl implements SignFranchiseService, AuditResu
shopInfoDO.setDecorationRequirement(request.getDecorationRequirement());
shopInfoDO.setSpecialInstruction(request.getSpecialInstruction());
shopInfoMapper.updateByPrimaryKeySelective(shopInfoDO);
//添加修改日志
handleDecorartionReq(shopInfoDO.getId(),request.getDecorationLevel(),request.getDecorationRequirement(),
request.getShopDecorationAttributes(),request.getSpecialInstruction(),user);
if (Objects.nonNull(pointInfoById)) {
pointInfoById.setProvince(request.getProvince());
pointInfoById.setCity(request.getCity());
@@ -679,7 +675,6 @@ public class SignFranchiseServiceImpl implements SignFranchiseService, AuditResu
}
}
/**
* 分部内勤/财务审批拒绝
*/
@@ -942,7 +937,6 @@ public class SignFranchiseServiceImpl implements SignFranchiseService, AuditResu
return pushService.pushContract(contractInformationDTO);
} catch (Exception e) {
log.error("推送合同信息失败", e);
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,e.getMessage());
}
}
return null;

View File

@@ -1,12 +1,11 @@
package com.cool.store.service.impl;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.CommonConstants;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.dao.store.StoreBusinessReportDAO;
import com.cool.store.dto.StoreNameDTO;
import com.cool.store.dao.store.StoreMasterSignerInfoDAO;
import com.cool.store.dto.store.*;
@@ -17,10 +16,8 @@ import com.cool.store.dao.SysRoleDao;
import com.cool.store.dto.StoreDTO;
import com.cool.store.dto.UserSimpleDTO;
import com.cool.store.entity.*;
import com.cool.store.entity.store.StoreBusinessReportDO;
import com.cool.store.entity.store.StoreMasterSignerInfoDO;
import com.cool.store.enums.*;
import com.cool.store.enums.master.BrandTypeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.*;
import com.cool.store.request.store.StoreListRequest;
@@ -32,6 +29,8 @@ import com.cool.store.utils.GeoMapUtil;
import com.cool.store.utils.poi.constant.Constants;
import com.cool.store.vo.SysRoleVO;
import com.cool.store.vo.store.StoreListVO;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
@@ -82,8 +81,6 @@ public class StoreServiceImpl implements StoreService {
StoreMasterSignerInfoDAO storeMasterSignerInfoDAO;
@Resource
EnterpriseUserRoleMapper enterpriseUserRoleMapper;
@Resource
StoreBusinessReportDAO storeBusinessReportDAO;
@Override
public PageInfo<StoreDTO> getStoreExtendFieldInfo(Integer pageSize, Integer pageNum, Boolean queryOperations) {
@@ -401,44 +398,6 @@ public class StoreServiceImpl implements StoreService {
return result;
}
@Override
public void saveStoreReport(String date) {
List<StoreBusinessReportDO> reportList = new ArrayList<>();
List<Integer> joinList = Arrays.asList(BrandTypeEnum.JP.getCode(), BrandTypeEnum.ZSJ.getCode(), BrandTypeEnum.MX.getCode());
reportList.addAll(storeReportStatistics(date, joinList, null));
// 处理正新鸡排境内境外
reportList.addAll(storeReportStatistics(date, Collections.singletonList(BrandTypeEnum.JP.getCode()), 1));
reportList.addAll(storeReportStatistics(date, Collections.singletonList(BrandTypeEnum.JP.getCode()), 2));
if (CollectionUtils.isNotEmpty(reportList)) {
storeBusinessReportDAO.insertOrUpdateBatch(reportList);
}
}
private List<StoreBusinessReportDO> storeReportStatistics(String date, List<Integer> joinList, Integer domestic) {
Map<Integer, Integer> totalMap = storeDao.totalOpenStoreReport(date, domestic, joinList);
Map<Integer, Integer> periodBeginMap = storeDao.periodBeginStoreReport(date, domestic, joinList);
Map<Integer, Integer> newMap = storeDao.newOpenStoreReport(date, domestic, joinList);
Map<Integer, Integer> closeMap = storeDao.closeStoreReport(date, domestic, joinList);
List<StoreBusinessReportDO> reportList = new ArrayList<>();
for (Integer joinBrand : joinList) {
Integer periodBeginNum = periodBeginMap.getOrDefault(joinBrand, 0);
Integer newOpenNum = newMap.getOrDefault(joinBrand, 0);
Integer closeNum = closeMap.getOrDefault(joinBrand, 0);
StoreBusinessReportDO report = new StoreBusinessReportDO();
report.setJoinBrand(joinBrand);
report.setDomestic(Objects.nonNull(domestic) ? domestic : 0);
report.setDate(date);
report.setOpenTotalNum(totalMap.getOrDefault(joinBrand, 0));
report.setPeriodBeginNum(periodBeginNum);
report.setNewOpenNum(newOpenNum);
report.setCloseNum(closeNum);
report.setPeriodEndNum(periodBeginNum + newOpenNum - closeNum);
reportList.add(report);
}
return reportList;
}
@Override
public List<AuthStoreUserDTO> authStoreUser(List<String> storeIdList, String positionType) {

View File

@@ -8,10 +8,6 @@ import com.cool.store.dto.recipe.RecipeSpLaunchDTO;
import com.cool.store.dto.recipe.RevenueDataDTO;
import com.cool.store.dto.recipe.RevenueDataQueryDTO;
import com.cool.store.dto.recipe.SalesVolumeDayQueryDTO;
import com.cool.store.dto.GetAccessTokenDTO;
import com.cool.store.dto.food.DishesDTO;
import com.cool.store.dto.store.StoreUserPositionDTO;
import com.cool.store.dto.recipe.SalesVolumeDayQueryDTO;
import com.cool.store.dto.store.StoreUserUpdateDTO;
import com.cool.store.entity.StoreDO;
import com.cool.store.enums.ErrorCodeEnum;
@@ -32,9 +28,7 @@ import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -70,22 +64,6 @@ public class ThirdFoodServiceImpl implements ThirdFoodService {
return executeApiCall(url, dto, String.class);
}
@Override
public List<DishesDTO> getPurchasedDishesList(FoodTokenDTO dto) {
String url = "/v1/recipe/getPurchasedRecipeList";
ParameterizedTypeReference<OpportunityApiResponse<List<DishesDTO>>> responseType =
new ParameterizedTypeReference<OpportunityApiResponse<List<DishesDTO>>>() {};
return listByExecuteApiCall(url, dto, responseType).getData();
}
@Override
public List<DishesDTO> getMyDesignDishesList(FoodTokenDTO dto) {
String url = "/v1/recipe/getRecipeList";
ParameterizedTypeReference<OpportunityApiResponse<List<DishesDTO>>> responseType =
new ParameterizedTypeReference<OpportunityApiResponse<List<DishesDTO>>>() {};
return listByExecuteApiCall(url, dto, responseType).getData();
}
@Override
public StoreUserResponse pushStoreUser(List<StoreUserUpdateDTO> dto) {
String url = "/v1/store/updateStoreUser";
@@ -127,45 +105,6 @@ public class ThirdFoodServiceImpl implements ThirdFoodService {
return BeanUtil.toList(list, RevenueDataVO.class, CopyOptions.create().setFieldMapping(Collections.singletonMap("storeCode", "storeNum")));
}
private <T> T listByExecuteApiCall(String url, Object requestBody, ParameterizedTypeReference<T> responseType) {
// 1. 打印请求前日志
//logRequest(url, requestBody);
try {
Request request = buildRequest(requestBody, url);
try (Response response = okHttpClient.newCall(request).execute()) {
// 2. 获取原始响应内容
String responseBody = response.body().string();
// 3. 打印响应日志
logResponse(url, response.code(), responseBody);
if (!response.isSuccessful()) {
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,
"HTTP请求失败状态码: " + response.code());
}
// 4. 解析响应
JavaType javaType = objectMapper.getTypeFactory().constructType(responseType.getType());
OpportunityApiResponse<T> apiResponse = objectMapper.readValue(responseBody, javaType);
if (apiResponse.getCode() != 200) {
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR, apiResponse.getMsg());
}
return objectMapper.readValue(responseBody, javaType);
}
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
log.error("API调用异常 - URL: {}, 错误: {}", url, e.getMessage(), e);
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR, "接口调用异常: " + e.getMessage());
}
}
private <T> T executeApiCall(String url, Object requestBody, Class<T> responseType) {
// 1. 打印请求前日志
//logRequest(url, requestBody);

View File

@@ -1,191 +0,0 @@
package com.cool.store.service.impl;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.cool.store.constants.RedisConstant;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.liepin.*;
import com.cool.store.response.liepin.*;
import com.cool.store.service.ThirdLiePinService;
import com.cool.store.service.XbbApiCaller;
import com.cool.store.utils.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @Author suzhuhong
* @Date 2025/5/20 15:33
* @Version 1.0
*/
@Service
@Slf4j
public class ThirdLiePinServiceImpl implements ThirdLiePinService {
private XbbApiCaller xbbApiCaller;
private GetAccessTokenRequest getAccessTokenRequest;
private final Lock lock = new ReentrantLock();
@Value("${liePin.appId}")
private String appId;
@Value("${liePin.secretKey}")
private String secretKey;
@Value("${liePin.aesSecretKey}")
private String aesSecretKey;
@Value("${liePin.baseUrl}")
private String liePinBaseUrl;
@Value("${liePin.tenantId}")
private Long tenantId;
@Value("${liePin.mobile}")
private String mobile;
@Resource
OkHttpClient okHttpClient;
@Resource
ObjectMapper objectMapper;
@Autowired
private RedisUtilPool redisUtilPool;
@Resource
private RedisConstantUtil redisConstantUtil;
@PostConstruct
public void init() {
this.xbbApiCaller = new XbbApiCaller(liePinBaseUrl, appId, secretKey, aesSecretKey,objectMapper);
this.getAccessTokenRequest = new GetAccessTokenRequest(tenantId,mobile);
}
@Override
public String getAccessToken(GetAccessTokenRequest request) {
String key = redisConstantUtil.getKeyCommonMethod(RedisConstant.ACCESS_TOKEN_CACHE_PREFIX, String.valueOf(request.getTenant_id()), request.getMobile());
String accessToken = redisUtilPool.getString(key);
if (StringUtil.isNotEmpty(accessToken)){
return accessToken;
}
String url = "/open_api/v2/super/b_applet/access_token";
XbbPostRequest xbbPostRequest = XbbPostRequest.newBuilder().uri(url).jsonString(JSONUtil.toJsonStr(request)).build();
XbbResponse<LiePinTokenInfo> response = xbbApiCaller.post(xbbPostRequest, LiePinTokenInfo.class,getToken());
accessToken = response.getData().getAccess_token();
redisUtilPool.setString(key,accessToken,RedisConstant.ONE_DAY_SECONDS*7);
return accessToken;
}
@Override
public Long addStoreToLiePin(AddStoreRequest addStoreRequest) {
String accessToken = getAccessToken(getAccessTokenRequest);
Map<String, String> queryString = new HashMap<>();
queryString.put("access_token",accessToken);
String url = "/open_api/v2/super/b_applet/store";
XbbPostRequest xbbPostRequest = XbbPostRequest.newBuilder().uri(url).queryParam(queryString).jsonString(JSONUtil.toJsonStr(addStoreRequest)).build();
XbbResponse<StoreInfoResponse> storeInfoResponse = xbbApiCaller.post(xbbPostRequest, StoreInfoResponse.class,getToken());
return storeInfoResponse.getData().getStore_id();
}
@Override
public Long addStoreEmp(AddStoreEmpRequest addStoreEmpRequest) {
String accessToken = getAccessToken(getAccessTokenRequest);
Map<String, String> queryString = new HashMap<>();
queryString.put("access_token",accessToken);
String url = "/open_api/v2/super/b_applet/store/account";
XbbPostRequest xbbPostRequest = XbbPostRequest.newBuilder().uri(url).queryParam(queryString).jsonString(JSONUtil.toJsonStr(addStoreEmpRequest)).build();
XbbResponse<StoreEmpInfoResponse> empInfoResponseXbbResponse = xbbApiCaller.post(xbbPostRequest, StoreEmpInfoResponse.class,getToken());
return empInfoResponseXbbResponse.getData().getAccount_id();
}
@Override
public PathResponse getPath(GetPathRequest getPathRequest) {
String accessToken = getAccessToken(getAccessTokenRequest);
Map<String, String> queryString = new HashMap<>();
queryString.put("access_token",accessToken);
String url = "/open_api/v2/super/b_applet/jump_url";
XbbPostRequest xbbPostRequest = XbbPostRequest.newBuilder().uri(url).queryParam(queryString).jsonString(JSONUtil.toJsonStr(getPathRequest)).build();
XbbResponse<PathResponse> jumpUrl = xbbApiCaller.post(xbbPostRequest, PathResponse.class,getToken());
return jumpUrl.getData();
}
@Override
public String getFilePath(String ossUrl) {
String accessToken = getAccessToken(getAccessTokenRequest);
Map<String, String> queryString = new HashMap<>();
queryString.put("access_token",accessToken);
String url = "/open_api/v2/super/common/upload";
UploadRequest uploadRequest = new UploadRequest(OssUtil.getUrlName(ossUrl), OssUtil.convertPublicOssUrlToBase64(ossUrl));
XbbPostRequest xbbPostRequest = XbbPostRequest.newBuilder().uri(url).queryParam(queryString).jsonString(JSONUtil.toJsonStr(uploadRequest)).build();
XbbResponse<FileResponse> file = xbbApiCaller.post(xbbPostRequest, FileResponse.class,getToken());
return file.getData().getFile_id();
}
/**
* 接口授权token
* @return
*/
public String getToken() {
String key = redisConstantUtil.getKeyCommonMethod(RedisConstant.TOKEN_CACHE_PREFIX, appId,secretKey);
String accessToken = redisUtilPool.getString(key);
if (StringUtil.isNotEmpty(accessToken)){
return accessToken;
}
try {
if (!lock.tryLock(10, TimeUnit.SECONDS)) {
throw new ServiceException("获取token失败");
}
} catch (InterruptedException e) {
throw new ServiceException("获取token失败");
}
try {
Exception error = null;
for (int i = 0; i < 3; i++) {
try {
String urlTemplate = "{}/open_api/access_token?app_id={}&secret_key={}";
String url = StrUtil.format(urlTemplate, liePinBaseUrl, appId, URLUtil.encode(secretKey));
// 创建POST请求并设置请求头
HttpRequest request = HttpUtil.createPost(url).header("Content-Type", "application/json");
String responseBody;
try (HttpResponse httpResponse = request.execute()) {
responseBody = httpResponse.body();
}
// 解析JSON响应
TokenResponse tokenResponse = JSONUtil.toBean(responseBody, TokenResponse.class);
if (!tokenResponse.isSuccess()) {
throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,tokenResponse.getMsg());
}
// 获取缓存的时间 提前半小时过期 重新获取
Long expire = ((tokenResponse.getData().getExpire() - System.currentTimeMillis())/1000)-1800;
redisUtilPool.setString(key,tokenResponse.getData().getToken(),expire.intValue());
return tokenResponse.getData().getToken();
} catch (Exception e) {
log.error("第{}次获取token error{}",i+1,error.getMessage());
ThreadUtil.sleep(2, TimeUnit.SECONDS);
}
}
throw new ServiceException("获取token失败");
} finally {
lock.unlock();
}
}
}

View File

@@ -6,7 +6,6 @@ import com.cool.store.exception.ServiceException;
import com.cool.store.request.oppty.*;
import com.cool.store.response.oppty.*;
import com.cool.store.service.ThirdOpportunityService;
import com.cool.store.utils.CommonContextUtil;
import com.cool.store.utils.JsonUtils;
import com.cool.store.utils.SignatureUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -80,8 +79,8 @@ public class ThirdOpportunityServiceImpl implements ThirdOpportunityService {
@Override
public String berthOperation(BerthOperationRequest requestBody) {
String url = apiUrl+"open/oppty/v1/addBerthInfo";
String profileName = CommonContextUtil.getProfileName();
return "online".equals(profileName) ? executeApiCall(url, requestBody, String.class) : null;
return executeApiCall(url, requestBody, String.class);
}
@Override

View File

@@ -6,10 +6,7 @@ import com.cool.store.constants.CommonConstants;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.*;
import com.cool.store.dto.BigRegionUserDTO;
import com.cool.store.dto.BigRegionUserListDTO;
import com.cool.store.dto.UserDTO;
import com.cool.store.dto.region.BigRegionDTO;
import com.cool.store.entity.*;
import com.cool.store.enums.*;
import com.cool.store.exception.ServiceException;
@@ -17,7 +14,6 @@ import com.cool.store.mapper.RegionMapper;
import com.cool.store.mapper.SysRoleMapper;
import com.cool.store.mapper.UserAuthMappingMapper;
import com.cool.store.request.SysRoleRequest;
import com.cool.store.response.bigdata.ApiResponse;
import com.cool.store.service.UserAuthMappingService;
import com.cool.store.utils.RedisConstantUtil;
import com.cool.store.utils.RedisUtilPool;
@@ -82,11 +78,8 @@ public class UserAuthMappingServiceImpl implements UserAuthMappingService {
private EnterpriseUserRoleDao enterpriseUserRoleDao;
@Autowired
private RegionDao regionDao;
@Resource
BigRegionDAO bigRegionDAO;
@Resource
StoreDao storeDao;
@Autowired
private BigRegionDAO bigRegionDAO;
@Override
@@ -235,22 +228,22 @@ public class UserAuthMappingServiceImpl implements UserAuthMappingService {
// 查找有区域权限的人
List<String> authRegionUserIdList = authWarRegionUser(regionId);
if (CollectionUtils.isEmpty(authRegionUserIdList)) {
return Lists.newArrayList();
return null;
}
Long roleId = userRoleEnum.getCode();
List<String> hasRoleUserIdList = sysRoleMapper.getPositionUserIds(Collections.singletonList(String.valueOf(roleId)));
if (CollectionUtils.isEmpty(hasRoleUserIdList)) {
return Lists.newArrayList();
return null;
}
authRegionUserIdList.retainAll(hasRoleUserIdList);
if (CollectionUtils.isEmpty(authRegionUserIdList)) {
return Lists.newArrayList();
return null;
}
if (CollectionUtils.isNotEmpty(authRegionUserIdList)) {
List<EnterpriseUserDO> userInfoByUserIds = enterpriseUserDAO.getUserInfoByUserIds(authRegionUserIdList);
return userInfoByUserIds;
}
return Lists.newArrayList();
return null;
}
@Override
@@ -273,12 +266,12 @@ public class UserAuthMappingServiceImpl implements UserAuthMappingService {
// 查找有区域权限的人
List<String> authRegionUserIdList = authWarRegionUser(regionId);
if (CollectionUtils.isEmpty(authRegionUserIdList)) {
return Lists.newArrayList();
return null;
}
Long roleId = userRoleEnum.getCode();
List<String> hasRoleUserIdList = sysRoleMapper.getPositionUserIds(Collections.singletonList(String.valueOf(roleId)));
if (CollectionUtils.isEmpty(hasRoleUserIdList)) {
return Lists.newArrayList();
return null;
}
authRegionUserIdList.retainAll(hasRoleUserIdList);
if (CollectionUtils.isEmpty(authRegionUserIdList)) {
@@ -543,42 +536,6 @@ public class UserAuthMappingServiceImpl implements UserAuthMappingService {
return new ArrayList<>();
}
@Override
public ApiResponse<List<BigRegionUserListDTO>> getAllBigRegionSpecialRoleUserList(String storeCode, UserRoleEnum userRoleEnum) {
StoreDO store = storeDao.getByStoreNum(storeCode);
if (Objects.isNull(store)){
return ApiResponse.error(ErrorCodeEnum.STORE_NUM_NOT_FOUND);
}
//如果没有大区 则返回空
if (store.getBranch()==null){
return ApiResponse.success( null);
}
//查询所有启用的大区
List<BigRegionUserDTO> bigRegionByUserId = userAuthMappingMapper.getBigRegionByUserId(Arrays.asList(store.getBranch()), userRoleEnum.getDesc());
//根据区域ID对bigRegionByUserId人员进行分组
Map<Long, List<BigRegionUserDTO>> bigRegionByRegionId = bigRegionByUserId.stream().collect(Collectors.groupingBy(BigRegionUserDTO::getRegionId));
//转为对象BigRegionUserListDTO
List<BigRegionUserListDTO> result = bigRegionByRegionId.entrySet().stream().map(entry -> {
BigRegionUserListDTO dto = new BigRegionUserListDTO();
dto.setRegionId(entry.getKey());
// 获取对应区域的大区信息
if (CollectionUtils.isNotEmpty(entry.getValue())){
BigRegionUserDTO regionDTO = entry.getValue().get(0);
dto.setRegionName(regionDTO.getRegionName());
}
// 将 BigRegionUserDTO 转换为 UserDTO
List<UserDTO> userDTOList = entry.getValue().stream().map(bigRegionUser -> {
UserDTO userDTO = new UserDTO();
userDTO.setName(bigRegionUser.getName());
userDTO.setMobile(bigRegionUser.getMobile());
return userDTO;
}).collect(Collectors.toList());
dto.setSpecialRoleUserList(userDTOList);
return dto;
}).collect(Collectors.toList());
return ApiResponse.success(result);
}
private List<String> extractNumbers(String regionPath) {
List<String> regionIds = new ArrayList<>();
Pattern pattern = Pattern.compile("\\d+");

View File

@@ -10,7 +10,6 @@ import com.cool.store.enums.*;
import com.cool.store.exception.ServiceException;
import com.cool.store.http.WechatRest;
import com.cool.store.mapper.HyPartnerUserChannelMapper;
import com.cool.store.oss.OssClientService;
import com.cool.store.request.MobileUpdateRequest;
import com.cool.store.service.WechatMiniAppService;
import com.cool.store.utils.RedisUtilPool;
@@ -25,13 +24,10 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.text.MessageFormat;
import java.util.Date;
import java.util.Objects;
import static com.cool.store.utils.easyExcel.EasyExcelUtil.getUploadPath;
/**
* @author zhangchenbiao
* @FileName: WechatMiniAppServiceImpl
@@ -56,8 +52,6 @@ public class WechatMiniAppServiceImpl implements WechatMiniAppService {
HyOpenAreaInfoDAO hyOpenAreaInfoDAO;
@Resource
PartnerUserWechatBindDAO partnerUserWechatBindDAO;
@Resource
private OssClientService ossClientService;
@Value("${weixin.appId}")
private String wxAppId;
@Value("${weixin.appSecret}")
@@ -68,8 +62,6 @@ public class WechatMiniAppServiceImpl implements WechatMiniAppService {
private Integer exhibition;
@Value("${recommended.channel.id}")
private Integer recommended;
@Value("${mybatis.configuration.variables.enterpriseId}")
private String eid;
@Override
public PartnerUserInfoVO miniProgramLogin(MiniProgramLoginDTO param) {
@@ -294,42 +286,4 @@ public class WechatMiniAppServiceImpl implements WechatMiniAppService {
return null;
}
private String delCacheAndGetAccessToken() {
String cacheAccessToken = "wechat_mini_" + wxAppId;
redisUtilPool.delKey(cacheAccessToken);
return wechatRest.getAccessToken(wxAppId, wxAppSecret);
}
@Override
public String createQrCode(String page, String scene, String width) {
String accessToken = wechatRest.getAccessToken(wxAppId, wxAppSecret);
if (StringUtils.isBlank(accessToken)) {
log.error("token获取失败");
return null;
}
byte[] qrCode = null;
try {
qrCode = wechatRest.createQrCode(accessToken, page, scene, width);
} catch (ServiceException e) {
if (ErrorCodeEnum.WX_ACCESS_TOKEN_INVALID.getCode() == e.getErrorCode()) {
accessToken = delCacheAndGetAccessToken();
qrCode = wechatRest.createQrCode(accessToken, page, scene, width);
}
}
if (qrCode == null || qrCode.length == 0) {
return null;
}
try {
// 生成唯一文件名
String fileName = getUploadPath(eid) + "qrcode" + UUIDUtils.get32UUID() + ".png";
ByteArrayInputStream inputStream = new ByteArrayInputStream(qrCode);
String url = ossClientService.putObject(fileName, inputStream, (long) qrCode.length, "image/png");
log.info("二维码上传OSS成功url:{}", url);
return url;
} catch (Exception e) {
log.error("二维码上传OSS失败", e);
}
return null;
}
}

View File

@@ -5,13 +5,11 @@ import com.cool.store.constants.RedisConstant;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.EnterpriseUserDAO;
import com.cool.store.dao.StoreDao;
import com.cool.store.dao.WithdrawApplicationDAO;
import com.cool.store.dao.wallet.WalletTradeDAO;
import com.cool.store.dto.wallet.AccountWithdrawerDTO;
import com.cool.store.dto.wallet.TradeRecordDTO;
import com.cool.store.dto.wallet.WithdrawApplicationDTO;
import com.cool.store.entity.StoreDO;
import com.cool.store.entity.WithdrawApplicationDO;
import com.cool.store.entity.wallet.WalletTradeDO;
import com.cool.store.enums.ErrorCodeEnum;
@@ -30,7 +28,6 @@ import com.cool.store.utils.RedisUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
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;
@@ -38,14 +35,12 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.cool.store.enums.wallet.WalletTradeModuleEnum.STANDARD_STORE;
import static com.cool.store.enums.wallet.WalletTradeModuleEnum.TRANSFER;
/**
@@ -70,9 +65,6 @@ public class WithdrawApplicationServiceImpl implements WithdrawApplicationServic
@Resource
EnterpriseUserDAO enterpriseUserDAO;
@Resource
StoreDao storeDao;
private static final String WITHDRAW_ORDER_PREFIX = "TX";
@Override
@@ -85,19 +77,8 @@ public class WithdrawApplicationServiceImpl implements WithdrawApplicationServic
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet());
Map<String, String> userNameMap = enterpriseUserDAO.getUserNameMap(new ArrayList<>(userIdList));
// 获取门店ID列表并查询门店名称
Set<String> storeIdList = responses.stream()
.filter(x -> StringUtils.isNotBlank(x.getRelateStoreId()))
.map(WithdrawApplicationDTO::getRelateStoreId)
.collect(Collectors.toSet());
Map<String, StoreDO> storeNameMap = storeDao.getStoreMapByStoreIds(new ArrayList<>(storeIdList));
responses.stream().forEach(x->{
x.setCreateUserName(userNameMap.get(x.getCreateUserId()));
StoreDO storeDO = storeNameMap.get(x.getRelateStoreId());
if (storeDO!=null){
x.setRelateStoreName(storeDO.getStoreName());
}
});
return new PageInfo<>(responses);
}
@@ -115,8 +96,6 @@ public class WithdrawApplicationServiceImpl implements WithdrawApplicationServic
.amount(request.getAmount())
.bankCardNo(request.getBankCardNo())
.bankName(request.getBankName())
.relateStoreId(request.getRelateStoreId())
.remark(request.getRemark())
.status(AllocationPayStatusEnum.UNPAID.getStatus())
.createUserId(userId)
.createTime(new Date())

View File

@@ -1,29 +0,0 @@
package com.cool.store.service.renewal;
import com.cool.store.request.renewal.RenewalApplicationCreateRequest;
import com.cool.store.request.renewal.RenewalApplicationQueryRequest;
import com.cool.store.request.renewal.RenewalApprovalRequest;
import com.cool.store.request.renewal.RenewalFranchiseeConfirmRequest;
import com.cool.store.vo.PartnerUserInfoVO;
import com.cool.store.vo.renewal.RenewalApplicationDetailVO;
import com.cool.store.vo.renewal.RenewalApplicationListVO;
import com.github.pagehelper.PageInfo;
public interface RenewalApplicationService {
PageInfo<RenewalApplicationListVO> queryRenewalApplicationList(RenewalApplicationQueryRequest request);
RenewalApplicationDetailVO getRenewalApplicationDetail(Long renewalId);
Boolean createRenewalApplication(RenewalApplicationCreateRequest request);
Boolean franchiseeConfirm(RenewalFranchiseeConfirmRequest request, PartnerUserInfoVO user);
Boolean operationsConsultantApproval(RenewalApprovalRequest request);
Boolean regionalConsultantApproval(RenewalApprovalRequest request);
Boolean groupEngineeringApproval(RenewalApprovalRequest request);
void autoGenerateRenewalApplications();
}

View File

@@ -1,557 +0,0 @@
package com.cool.store.service.renewal.impl;
import cn.hutool.core.collection.CollStreamUtil;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.EnterpriseUserDAO;
import com.cool.store.dao.RegionDao;
import com.cool.store.dao.StoreDao;
import com.cool.store.dao.contract.ContractMasterDAO;
import com.cool.store.dao.renewal.RenewalApplicationDAO;
import com.cool.store.dao.renewal.RenewalRenovateApprovalDAO;
import com.cool.store.dao.renewal.RenewalApplicationSignerInfoDAO;
import com.cool.store.dao.store.StoreMasterSignerInfoDAO;
import com.cool.store.entity.EnterpriseUserDO;
import com.cool.store.entity.RegionDO;
import com.cool.store.entity.StoreDO;
import com.cool.store.entity.approval.CommonApprovalLogDO;
import com.cool.store.entity.contract.ContractMasterDO;
import com.cool.store.entity.renewal.RenewalApplicationDO;
import com.cool.store.entity.renewal.RenewalApplicationSignerInfoDO;
import com.cool.store.entity.renewal.RenewalRenovateApprovalDO;
import com.cool.store.entity.store.StoreMasterSignerInfoDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.UserRoleEnum;
import com.cool.store.enums.approval.ApprovalResultEnum;
import com.cool.store.enums.master.BrandTypeEnum;
import com.cool.store.enums.renewal.RenewalNodeEnum;
import com.cool.store.enums.renewal.RenewalStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.request.renewal.RenewalApplicationCreateRequest;
import com.cool.store.request.renewal.RenewalApplicationQueryRequest;
import com.cool.store.request.renewal.RenewalApprovalRequest;
import com.cool.store.request.renewal.RenewalFranchiseeConfirmRequest;
import com.cool.store.service.UserAuthMappingService;
import com.cool.store.service.approval.CommonApprovalLogService;
import com.cool.store.service.renewal.RenewalApplicationService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.GenerateNoUtil;
import com.cool.store.utils.poi.StringUtils;
import com.cool.store.vo.PartnerUserInfoVO;
import com.cool.store.vo.approval.ApprovalGroupedVO;
import com.cool.store.vo.renewal.ContractRelatedInfoVO;
import com.cool.store.vo.renewal.RenewalApplicationDetailVO;
import com.cool.store.vo.renewal.RenewalApplicationListVO;
import com.cool.store.vo.renewal.RenewalRenovateApprovalVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static javassist.CtClass.version;
@Service
@RequiredArgsConstructor
@Slf4j
public class RenewalApplicationServiceImpl implements RenewalApplicationService {
private final RenewalApplicationDAO renewalApplicationDAO;
private final ContractMasterDAO contractMasterDAO;
private final StoreDao storeDao;
private final RegionDao regionDao;
private final EnterpriseUserDAO enterpriseUserDAO;
private final CommonApprovalLogService commonApprovalLogService;
private final UserAuthMappingService userAuthMappingService;
private final RenewalRenovateApprovalDAO renewalRenovateApprovalDAO;
private final StoreMasterSignerInfoDAO storeMasterSignerInfoDAO;
private final RenewalApplicationSignerInfoDAO renewalApplicationSignerInfoDAO;
private final com.cool.store.dao.approval.CommonApprovalLogDAO commonApprovalLogDAO;
@Override
public PageInfo<RenewalApplicationListVO> queryRenewalApplicationList(RenewalApplicationQueryRequest request) {
if (request.getKeyword() != null && !request.getKeyword().isEmpty()) {
request.setQueryStore(true);
}
List<String> regionIds = null;
if (request.getRegionId() != null) {
regionIds = Collections.singletonList(String.valueOf(request.getRegionId()));
}
PageHelper.startPage(request.getPageNum(), request.getPageSize());
List<RenewalApplicationListVO> list = renewalApplicationDAO.queryRenewalApplicationList(request, regionIds);
PageInfo<RenewalApplicationListVO> pageInfo = new PageInfo<>(list);
// 填充状态名称
list.forEach(vo -> vo.setStatusName(RenewalStatusEnum.getNameByStatus(vo.getStatus())));
// 批量查询签约人信息并填充
if (CollectionUtils.isNotEmpty(list)) {
List<String> applicationNos = list.stream().map(RenewalApplicationListVO::getApplicationNo).collect(Collectors.toList());
Map<String, RenewalApplicationSignerInfoDO> signerMap = renewalApplicationSignerInfoDAO.getByApplicationNos(applicationNos);
List<String> storeCodeList = list.stream().map(RenewalApplicationListVO::getStoreCode).collect(Collectors.toList());
List<StoreDO> storeList = storeDao.getStoreNumByStoreCodes(storeCodeList);
Map<String, StoreDO> map = CollStreamUtil.toMap(storeList, StoreDO::getStoreNum, v -> v);
List<Long> regionIdList = storeList.stream()
.flatMap(store -> Stream.of(store.getRegionId(), store.getBranch()))
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
Map<Long, String> regionNameMap = regionDao.getRegionNameMap(regionIdList);
List<String> userIds = storeList.stream().map(StoreDO::getJoinSupervision).collect(Collectors.toList());
Map<String, String> userNameMap = enterpriseUserDAO.getUserNameMap(userIds);
list.forEach(vo -> {
RenewalApplicationSignerInfoDO signer = signerMap.get(vo.getApplicationNo());
if (signer != null) {
vo.setSigner1Name(signer.getSigner1Name());
vo.setSigner1Mobile(signer.getSigner1Mobile());
vo.setSigner2Name(signer.getSigner2Name());
vo.setSigner2Mobile(signer.getSigner2Mobile());
}
StoreDO store = map.get(vo.getStoreCode());
if (store!=null){
vo.setStoreName(store.getStoreName());
vo.setStoreAddress(store.getStoreAddress());
vo.setBrandName(BrandTypeEnum.getDescByCode(store.getJoinBrand()));
if (StringUtils.isNotBlank(store.getJoinSupervision())){
vo.setRecruitmentManager(userNameMap.get(store.getJoinSupervision()));
}
vo.setRegionName(regionNameMap.get(store.getRegionId()));
vo.setBranchName(regionNameMap.get(store.getBranch()));
}
});
}
return pageInfo;
}
@Override
public RenewalApplicationDetailVO getRenewalApplicationDetail(Long renewalId) {
RenewalApplicationDO renewalDO = renewalApplicationDAO.getById(renewalId);
if (renewalDO == null) {
throw new ServiceException(ErrorCodeEnum.RENEWAL_APPLY_NOT_EXIST);
}
RenewalApplicationDetailVO detailVO = new RenewalApplicationDetailVO();
detailVO.setRenewalId(renewalDO.getId());
detailVO.setApplicationNo(renewalDO.getApplicationNo());
detailVO.setStoreCode(renewalDO.getStoreCode());
detailVO.setContractExpireDate(renewalDO.getContractExpireDate());
detailVO.setIsRenovate(renewalDO.getIsRenovate());
detailVO.setStatus(renewalDO.getStatus());
detailVO.setStatusName(RenewalStatusEnum.getNameByStatus(renewalDO.getStatus()));
detailVO.setRemark(renewalDO.getRemark());
detailVO.setOriginalContractNo(renewalDO.getOriginalContractNo());
detailVO.setCreateUserName(renewalDO.getCreateUserName());
detailVO.setCreatedTime(renewalDO.getCreatedTime());
// 查询门店信息补充
if (renewalDO.getStoreCode() != null) {
StoreDO store = storeDao.getByStoreNum(renewalDO.getStoreCode());
if (store != null) {
detailVO.setStoreName(store.getStoreName());
detailVO.setStoreAddress(store.getStoreAddress());
detailVO.setBrandName(BrandTypeEnum.getDescByCode(store.getJoinBrand()));
detailVO.setStoreStatus(store.getStoreStatus());
if (StringUtils.isNotBlank(store.getJoinSupervision())){
String userName = enterpriseUserDAO.getUserName(store.getJoinSupervision());
detailVO.setRecruitmentManager(userName);
}
Map<Long, String> regionNameMap = regionDao.getRegionNameMap(Arrays.asList(store.getBranch(), store.getRegionId()));
detailVO.setRegionName(regionNameMap.get(store.getRegionId()));
detailVO.setBranchName(regionNameMap.get(store.getBranch()));
}
}
// 查询关联合同信息
if (renewalDO.getOriginalContractNo() != null) {
ContractMasterDO contractDO = contractMasterDAO.getByContractNo(renewalDO.getOriginalContractNo());
if (contractDO != null) {
ContractRelatedInfoVO contractInfo = new ContractRelatedInfoVO();
contractInfo.setContractNo(contractDO.getContractNo());
contractInfo.setBrandName(contractDO.getBrandName());
contractInfo.setSignDate(contractDO.getSignDate());
contractInfo.setContractType(contractDO.getContractType());
contractInfo.setStartDate(contractDO.getStartDate());
contractInfo.setEndDate(contractDO.getEndDate());
detailVO.setContractInfo(contractInfo);
}
}
// 查询签约人信息快照
RenewalApplicationSignerInfoDO signerInfo = renewalApplicationSignerInfoDAO.getByApplicationNo(renewalDO.getApplicationNo());
if (signerInfo != null) {
detailVO.setSigner1Name(signerInfo.getSigner1Name());
detailVO.setSigner1Mobile(signerInfo.getSigner1Mobile());
detailVO.setSigner2Name(signerInfo.getSigner2Name());
detailVO.setSigner2Mobile(signerInfo.getSigner2Mobile());
}
// 查询审批记录
ApprovalGroupedVO approvalBatches = commonApprovalLogService.getApprovalRecordsGroupedByVersion(renewalDO.getApplicationNo());
detailVO.setApprovalBatches(approvalBatches);
if (detailVO.getIsRenovate()==1){
RenewalRenovateApprovalDO byApplicationNo = renewalRenovateApprovalDAO.getByApplicationNo(renewalDO.getApplicationNo());
RenewalRenovateApprovalVO renewalRenovateApprovalVO = new RenewalRenovateApprovalVO();
BeanUtil.copyProperties(byApplicationNo,renewalRenovateApprovalVO);
detailVO.setRenewalRenovateApprovalVO(renewalRenovateApprovalVO);
}
return detailVO;
}
@Override
@Transactional
public Boolean createRenewalApplication(RenewalApplicationCreateRequest request) {
LoginUserInfo currentUser = CurrentUserHolder.getUser();
// 查询门店信息
StoreDO store = storeDao.getByStoreId(request.getStoreId());
if (store == null) {
throw new ServiceException(ErrorCodeEnum.STORE_NOT_EXIST);
}
// 查询当前门店最新合同
ContractMasterDO latestContract = contractMasterDAO.getLatestContractByStoreCode(store.getStoreNum());
if (latestContract!=null&&latestContract.getRenewalCreated() != null && latestContract.getRenewalCreated() == 1) {
throw new ServiceException(ErrorCodeEnum.CURRENT_SHOP_EXIST_APPLY);
}
// 生成申请编号
String applicationNo = GenerateNoUtil.generateNo("XQ");
// 构建续签申请
RenewalApplicationDO renewalDO = RenewalApplicationDO.builder()
.applicationNo(applicationNo)
.storeCode(store.getStoreNum())
.isDeleted(0)
.status(RenewalStatusEnum.PENDING_FRANCHISEE.getStatus())
.isRenovate(0)
.remark(request.getRemark())
.createUserName(currentUser.getName())
.createUserId(currentUser.getUserId())
.applyTime(new Date())
.build();
if (latestContract!=null){
renewalDO.setOriginalContractNo(latestContract.getContractNo());
renewalDO.setContractExpireDate(latestContract.getEndDate());
}
renewalApplicationDAO.insertSelective(renewalDO);
// 更新合同续签标记
if (latestContract!=null){
contractMasterDAO.updateRenewalCreated(latestContract.getId(), 1);
}
// 保存签约人信息快照
StoreMasterSignerInfoDO signerInfo = storeMasterSignerInfoDAO.getByStoreId(store.getStoreId());
if (signerInfo != null) {
RenewalApplicationSignerInfoDO signerSnapshot = RenewalApplicationSignerInfoDO.builder()
.applicationNo(applicationNo)
.signer1Name(signerInfo.getSigner1Name())
.signer1Mobile(signerInfo.getSigner1Mobile())
.signer2Name(signerInfo.getSigner2Name())
.signer2Mobile(signerInfo.getSigner2Mobile())
.createdTime(new Date())
.updatedTime(new Date())
.build();
renewalApplicationSignerInfoDAO.insertSelective(signerSnapshot);
}
return true;
}
@Override
@Transactional
public Boolean franchiseeConfirm(RenewalFranchiseeConfirmRequest request, PartnerUserInfoVO userInfoVO) {
RenewalApplicationDO renewalDO = renewalApplicationDAO.getById(request.getRenewalId());
if (renewalDO == null) {
throw new ServiceException(ErrorCodeEnum.RENEWAL_APPLY_NOT_EXIST);
}
if (!RenewalStatusEnum.PENDING_FRANCHISEE.getStatus().equals(renewalDO.getStatus())) {
throw new ServiceException(ErrorCodeEnum.NOT_SUPPORT_OPERATION);
}
if (request.getConfirmed()) {
// 确认续签 -> 待运营顾问审核
renewalDO.setStatus(RenewalStatusEnum.PENDING_OPS.getStatus());
renewalApplicationDAO.updateByPrimaryKeySelective(renewalDO);
// 写入审批记录:加盟商提交记录
commonApprovalLogService.insertSingleRecord(
renewalDO.getApplicationNo(), userInfoVO.getPartnerId(), userInfoVO.getUsername(),
RenewalNodeEnum.FRANCHISEE_CONFIRM.getCode(), RenewalNodeEnum.FRANCHISEE_CONFIRM.getName()
);
// 获取区域信息
StoreDO store = storeDao.getByStoreNum(renewalDO.getStoreCode());
RegionDO regionDO = regionDao.getRegionByStoreId(store.getStoreId());
// 生成运营顾问审批节点
List<String> auditUserIds = getAuditUserIds(regionDO != null ? regionDO.getId() : null, UserRoleEnum.SUPERVISION);
List<CommonApprovalLogDO> approveRecords = new ArrayList<>();
for (String userId : auditUserIds) {
EnterpriseUserDO user = enterpriseUserDAO.getUserInfoById(userId);
String userName = user != null ? user.getName() : "";
approveRecords.add(CommonApprovalLogDO.builder()
.nodeCode(RenewalNodeEnum.OPS_CONSULTANT.getCode())
.nodeName(RenewalNodeEnum.OPS_CONSULTANT.getName())
.handleUserId(userId)
.handleUserName(userName)
.build());
}
if (CollectionUtils.isNotEmpty(approveRecords)) {
commonApprovalLogService.batchInsertApprovalRecords(renewalDO.getApplicationNo(), approveRecords);
}
} else {
// 不续签
renewalDO.setStatus(RenewalStatusEnum.NOT_RENEWED.getStatus());
renewalApplicationDAO.updateByPrimaryKeySelective(renewalDO);
}
return true;
}
@Override
@Transactional
public Boolean operationsConsultantApproval(RenewalApprovalRequest request) {
RenewalApplicationDO renewalDO = renewalApplicationDAO.getById(request.getRenewalId());
if (renewalDO == null) {
throw new ServiceException(ErrorCodeEnum.RENEWAL_APPLY_NOT_EXIST);
}
if (!RenewalStatusEnum.PENDING_OPS.getStatus().equals(renewalDO.getStatus())) {
throw new ServiceException(ErrorCodeEnum.NOT_SUPPORT_OPERATION);
}
LoginUserInfo currentUser = CurrentUserHolder.getUser();
if (request.getPass()) {
// 翻新信息处理
if (request.getIsRenovate() != null && request.getIsRenovate() == 1) {
renewalDO.setIsRenovate(1);
RenewalRenovateApprovalDO renovateDO = RenewalRenovateApprovalDO.builder()
.applicationNo(renewalDO.getApplicationNo())
.shopAreaId(request.getShopAreaId())
.decorationAttributes(request.getDecorationAttributes())
.decorationLevel(request.getDecorationLevel())
.decorationRequirement(request.getDecorationRequirement())
.specialInstruction(request.getSpecialInstruction())
.videoUrl(request.getVideoUrl())
.shopFrontPhotoUrl(request.getShopFrontPhotoUrl())
.build();
renewalRenovateApprovalDAO.insertSelective(renovateDO);
}
// 通过 -> 待片区顾问审核
renewalDO.setStatus(RenewalStatusEnum.PENDING_REGION.getStatus());
renewalApplicationDAO.updateByPrimaryKeySelective(renewalDO);
commonApprovalLogService.updateNodeApprovalStatus(
renewalDO.getApplicationNo(),
RenewalNodeEnum.OPS_CONSULTANT.getCode(),
ApprovalResultEnum.PASS.getResult(),
currentUser.getUserId(), currentUser.getName(),
request.getRemark(), true,
getRegionIdByStoreCode(renewalDO.getStoreCode())
);
} else {
// 拒绝
renewalDO.setStatus(RenewalStatusEnum.REJECTED.getStatus());
renewalApplicationDAO.updateByPrimaryKeySelective(renewalDO);
commonApprovalLogService.updateNodeApprovalStatus(
renewalDO.getApplicationNo(),
RenewalNodeEnum.OPS_CONSULTANT.getCode(),
ApprovalResultEnum.REJECT.getResult(),
currentUser.getUserId(), currentUser.getName(),
request.getRemark(), false, null
);
}
return true;
}
@Override
@Transactional
public Boolean regionalConsultantApproval(RenewalApprovalRequest request) {
LoginUserInfo currentUser = CurrentUserHolder.getUser();
RenewalApplicationDO renewalDO = renewalApplicationDAO.getById(request.getRenewalId());
if (renewalDO == null) {
throw new ServiceException(ErrorCodeEnum.RENEWAL_APPLY_NOT_EXIST);
}
if (!RenewalStatusEnum.PENDING_REGION.getStatus().equals(renewalDO.getStatus())) {
throw new ServiceException(ErrorCodeEnum.NOT_SUPPORT_OPERATION);
}
if (request.getPass()) {
// 通过 -> 待集团工程部审核
renewalDO.setStatus(RenewalStatusEnum.PENDING_GROUP.getStatus());
renewalApplicationDAO.updateByPrimaryKeySelective(renewalDO);
commonApprovalLogService.updateNodeApprovalStatus(
renewalDO.getApplicationNo(),
RenewalNodeEnum.REGION_CONSULTANT.getCode(),
ApprovalResultEnum.PASS.getResult(),
currentUser.getUserId(), currentUser.getName(),
request.getRemark(), true,
getRegionIdByStoreCode(renewalDO.getStoreCode())
);
} else {
// 拒绝
renewalDO.setStatus(RenewalStatusEnum.REJECTED.getStatus());
renewalApplicationDAO.updateByPrimaryKeySelective(renewalDO);
commonApprovalLogService.updateNodeApprovalStatus(
renewalDO.getApplicationNo(),
RenewalNodeEnum.REGION_CONSULTANT.getCode(),
ApprovalResultEnum.REJECT.getResult(),
currentUser.getUserId(), currentUser.getName(),
request.getRemark(), false, null
);
}
return true;
}
@Override
@Transactional
public Boolean groupEngineeringApproval(RenewalApprovalRequest request) {
RenewalApplicationDO renewalDO = renewalApplicationDAO.getById(request.getRenewalId());
if (renewalDO == null) {
throw new ServiceException(ErrorCodeEnum.RENEWAL_APPLY_NOT_EXIST);
}
if (!RenewalStatusEnum.PENDING_GROUP.getStatus().equals(renewalDO.getStatus())) {
throw new ServiceException(ErrorCodeEnum.NOT_SUPPORT_OPERATION);
}
LoginUserInfo currentUser = CurrentUserHolder.getUser();
Long version = getCurrentVersion(renewalDO.getApplicationNo());
if (request.getPass()) {
// 通过 -> 续签中
renewalDO.setStatus(RenewalStatusEnum.RENEWAL_ING.getStatus());
renewalApplicationDAO.updateByPrimaryKeySelective(renewalDO);
commonApprovalLogService.updateNodeApprovalStatus(
renewalDO.getApplicationNo(),
RenewalNodeEnum.GROUP_ENGINEERING.getCode(),
ApprovalResultEnum.PASS.getResult(),
currentUser.getUserId(), currentUser.getName(),
request.getRemark(), false, null
);
} else {
// 拒绝
renewalDO.setStatus(RenewalStatusEnum.REJECTED.getStatus());
renewalApplicationDAO.updateByPrimaryKeySelective(renewalDO);
commonApprovalLogService.updateNodeApprovalStatus(
renewalDO.getApplicationNo(),
RenewalNodeEnum.GROUP_ENGINEERING.getCode(),
ApprovalResultEnum.REJECT.getResult(),
currentUser.getUserId(), currentUser.getName(),
request.getRemark(), false, null
);
}
return true;
}
@Override
@Transactional
public void autoGenerateRenewalApplications() {
// 查询90天内到期且未生成续签的合同
List<ContractMasterDO> contracts = contractMasterDAO.queryContractsNearExpiry(90);
if (CollectionUtils.isEmpty(contracts)) {
log.info("没有即将到期的合同需要生成续签申请");
return;
}
for (ContractMasterDO contract : contracts) {
try {
// 再次检查renewalCreated状态防止并发
ContractMasterDO fresh = contractMasterDAO.getById(contract.getId());
if (fresh == null || fresh.getRenewalCreated() == 1) {
continue;
}
String applicationNo = GenerateNoUtil.generateNo("XQ");
RenewalApplicationDO renewalDO = RenewalApplicationDO.builder()
.applicationNo(applicationNo)
.storeCode(contract.getStoreCode())
.originalContractNo(contract.getContractNo())
.contractExpireDate(contract.getEndDate())
.isDeleted(0)
.status(RenewalStatusEnum.PENDING_FRANCHISEE.getStatus())
.isRenovate(0)
.remark("系统自动生成")
.createUserName("系统")
.applyTime(new Date())
.build();
renewalApplicationDAO.insertSelective(renewalDO);
// 保存签约人信息快照
StoreDO store = storeDao.getByStoreNum(contract.getStoreCode());
if (store != null) {
StoreMasterSignerInfoDO signerInfo = storeMasterSignerInfoDAO.getByStoreId(store.getStoreId());
if (signerInfo != null) {
RenewalApplicationSignerInfoDO signerSnapshot = RenewalApplicationSignerInfoDO.builder()
.applicationNo(applicationNo)
.signer1Name(signerInfo.getSigner1Name())
.signer1Mobile(signerInfo.getSigner1Mobile())
.signer2Name(signerInfo.getSigner2Name())
.signer2Mobile(signerInfo.getSigner2Mobile())
.createdTime(new Date())
.updatedTime(new Date())
.build();
renewalApplicationSignerInfoDAO.insertSelective(signerSnapshot);
}
}
// 更新续签标记
contractMasterDAO.updateRenewalCreated(contract.getId(), 1);
log.info("自动生成续签申请: applicationNo={}, storeCode={}", applicationNo, contract.getStoreCode());
} catch (Exception e) {
log.error("自动生成续签申请失败: contractId={}", contract.getId(), e);
}
}
}
/**
* 获取申请当前批次版本号
* 同一批次提交的所有审批记录使用相同的版本号
*/
private Long getCurrentVersion(String applicationNo) {
return GenerateNoUtil.generateVersion();
}
/**
* 根据门店编码获取区域ID
*/
private Long getRegionIdByStoreCode(String storeCode) {
StoreDO store = storeDao.getByStoreNum(storeCode);
if (store != null) {
RegionDO region = regionDao.getRegionByStoreId(store.getStoreId());
if (region != null) {
return region.getId();
}
}
return null;
}
/**
* 获取审批人ID列表
*/
private List<String> getAuditUserIds(Long regionId, UserRoleEnum userRoleEnum) {
List<EnterpriseUserDO> users = userAuthMappingService.getAllUserByRoleEnumAndRegionId(userRoleEnum, regionId);
return ListUtils.emptyIfNull(users).stream()
.map(EnterpriseUserDO::getUserId)
.distinct()
.collect(Collectors.toList());
}
}

View File

@@ -114,7 +114,7 @@ public class VisitRecordServiceImpl implements VisitRecordService {
.stream()
.map(Long::valueOf)
.collect(Collectors.toList());
List<BigRegionDTO> bigRegionList = bigRegionDAO.queryAllBigRegion(null, null, null, null);
List<BigRegionDTO> bigRegionList = bigRegionDAO.queryAllBigRegion(null, null, null);
Set<Long> bigRegionIds = CollStreamUtil.toSet(bigRegionList, BigRegionDTO::getRegionId);
authRegionIds.retainAll(bigRegionIds);
if (CollectionUtils.isEmpty(authRegionIds)) {

View File

@@ -30,7 +30,6 @@ 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.fees.WalletPayInfoService;
import com.cool.store.service.impl.CommonService;
import com.cool.store.service.wallet.*;
import com.cool.store.utils.BeanUtil;
@@ -83,7 +82,6 @@ public class WalletServiceImpl implements WalletService {
private final UserAuthMappingService userAuthMappingService;
private final CommonService commonService;
private final WalletTradeService walletTradeService;
private final WalletPayInfoService walletPayInfoService;
@Value("${wallet.org.id}")
private Long orgId;
@@ -560,10 +558,6 @@ public class WalletServiceImpl implements WalletService {
if (orgFlag){
tradeRecodePageRequest.setOrgId(orgId);
}
if (StringUtils.isNotEmpty(request.getExpenseTypeCode())){
tradeRecodePageRequest.setFeeItemId(walletPayInfoService.getFeeItemId(request.getExpenseTypeCode()));
}
TradeRecordListDTO tradeRecordListDTO = walletApiService.getTradeRecordList(tradeRecodePageRequest);
return toPageInfo(tradeRecordListDTO.getPageData(), TradeRecordDTO.class, tradeRecordListDTO.getPage());
}

View File

@@ -99,7 +99,7 @@ public class EasyExcelUtil {
}
public static String getUploadPath(String eid) {
private String getUploadPath(String eid) {
String time = DateUtil.format(new Date(), "yyMM");
return "eid" + "/" + eid + "/" + time + "/";
}

View File

@@ -1,227 +0,0 @@
package com.cool.store.utils.easyExcel;
import com.cool.store.dto.StoreImageExportDTO;
import com.cool.store.oss.OssClientService;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
/**
* @Author suzhuhong
* @Date 2025/11/20 18:53
* @Version 1.0
*/
@Service
public class StoreImageExcelExporter {
@Resource
private OssClientService ossClientService;
/**
* 导出带图片的门店信息到Excel
* @param dataList 门店图片数据列表
* @param response HTTP响应对象
* @param fileName 导出文件名
*/
/**
* 导出带图片的门店信息到Excel
* @param dataList 门店图片数据列表
* @param response HTTP响应对象
* @param fileName 导出文件名
*/
public String exportStoreImages(List<StoreImageExportDTO> dataList,
HttpServletResponse response,
String fileName) throws Exception {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("门店图片信息");
// 设置表头
Row headerRow = sheet.createRow(0);
CellStyle headerStyle = createHeaderStyle(workbook);
Cell storeCodeHeader = headerRow.createCell(0);
storeCodeHeader.setCellValue("门店编码");
storeCodeHeader.setCellStyle(headerStyle);
Cell storeNameHeader = headerRow.createCell(1);
storeNameHeader.setCellValue("门店名称");
storeNameHeader.setCellStyle(headerStyle);
Cell imageHeader = headerRow.createCell(2);
imageHeader.setCellValue("图片");
imageHeader.setCellStyle(headerStyle);
// 创建绘图容器
Drawing<?> drawing = sheet.createDrawingPatriarch();
// 填充数据
for (int i = 0; i < dataList.size(); i++) {
StoreImageExportDTO item = dataList.get(i);
Row row = sheet.createRow(i + 1);
// 设置行高以便显示图片
row.setHeightInPoints(300);
// 门店编码
Cell storeCodeCell = row.createCell(0);
storeCodeCell.setCellValue(item.getStoreCode());
// 门店名称
Cell storeNameCell = row.createCell(1);
storeNameCell.setCellValue(item.getStoreName());
// 插入图片到第3列(索引2)
if (item.getImageUrl() != null && !item.getImageUrl().isEmpty()) {
insertImageToCell(workbook, drawing, row, i, item.getImageUrl());
}
}
// 设置列宽
sheet.setColumnWidth(0, 20 * 256); // 门店编码列宽
sheet.setColumnWidth(1, 30 * 256); // 门店名称列宽
sheet.setColumnWidth(2, 50 * 256);
sheet.setColumnWidth(3, 50 * 256);
sheet.setColumnWidth(4, 50 * 256);
sheet.setColumnWidth(5, 50 * 256);
sheet.setColumnWidth(6, 50 * 256);
sheet.setColumnWidth(7, 50 * 256);
sheet.setColumnWidth(8, 50 * 256);
// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
workbook.write(byteArrayOutputStream);
workbook.close();
// 准备上传到OSS
byte[] bytes = byteArrayOutputStream.toByteArray();
long size = bytes.length;
InputStream inputStream = new ByteArrayInputStream(bytes);
// 提取文件名(不含扩展名)
String objectName = fileName;
if (fileName.contains(".")) {
objectName = fileName.substring(0, fileName.lastIndexOf("."));
}
// 上传到OSS并返回访问URL
return ossClientService.putObject(objectName + ".xlsx", inputStream, size,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
/**
* 在指定列中垂直排列显示多张图片
*/
private void insertImageToCell(Workbook workbook, Drawing<?> drawing, Row row, int rowIndex, String imageUrl) {
if (imageUrl == null || imageUrl.isEmpty()) {
return;
}
String[] imageUrls = imageUrl.split(";");
int imageCount = Math.min(imageUrls.length, 10);
if (imageCount == 0) {
return;
}
try {
// 根据图片数量调整行高
row.setHeightInPoints(300);
// 计算每张图片的宽度(平均分配)
for (int i = 0; i < imageCount; i++) {
String singleImageUrl = imageUrls[i].trim();
if (singleImageUrl.isEmpty()) {
continue;
}
byte[] imageBytes = downloadImage(singleImageUrl);
if (imageBytes != null) {
int pictureIdx = workbook.addPicture(imageBytes, getImageType(singleImageUrl));
CreationHelper helper = workbook.getCreationHelper();
ClientAnchor anchor = helper.createClientAnchor();
// 水平排列:每张图片在相同的行,但不同的列位置
anchor.setCol1(2 + i); // 起始列递增
anchor.setRow1(rowIndex+1); // 相同的行
anchor.setCol2(3 + i); // 结束列递增
anchor.setRow2(rowIndex + 2); // 相同的结束行
anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
Picture picture = drawing.createPicture(anchor, pictureIdx);
}
}
} catch (Exception e) {
Cell errorCell = row.createCell(2);
errorCell.setCellValue("图片加载失败: " + e.getMessage());
}
}
/**
* 创建表头样式
*/
private static CellStyle createHeaderStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
Font font = workbook.createFont();
font.setBold(true);
style.setFont(font);
style.setAlignment(HorizontalAlignment.CENTER);
return style;
}
/**
* 下载网络图片
*/
private byte[] downloadImage(String imageUrl) throws Exception {
URL url = new URL(imageUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.setRequestMethod("GET");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (InputStream inputStream = connection.getInputStream()) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
return outputStream.toByteArray();
}
/**
* 根据文件扩展名判断图片类型
*/
private int getImageType(String imageUrl) {
if (imageUrl.toLowerCase().endsWith(".png")) {
return Workbook.PICTURE_TYPE_PNG;
} else if (imageUrl.toLowerCase().endsWith(".jpg") || imageUrl.toLowerCase().endsWith(".jpeg")) {
return Workbook.PICTURE_TYPE_JPEG;
} else if (imageUrl.toLowerCase().endsWith(".gif")) {
return Workbook.PICTURE_TYPE_JPEG;
} else {
return Workbook.PICTURE_TYPE_JPEG; // 默认JPEG
}
}
}

View File

@@ -140,8 +140,8 @@ public class ExcelUtil<T> {
* @param is 输入流
* @return 转换后集合
*/
public List<T> importExcel(InputStream is,Integer titleRows) throws Exception {
return importExcel(StringUtils.EMPTY, is, titleRows);
public List<T> importExcel(InputStream is) throws Exception {
return importExcel(StringUtils.EMPTY, is);
}
/**
@@ -162,7 +162,7 @@ public class ExcelUtil<T> {
* @param is 输入流
* @return 转换后集合
*/
public List<T> importExcel(String sheetName, InputStream is,Integer titleRows) throws Exception {
public List<T> importExcel(String sheetName, InputStream is) throws Exception {
this.type = Excel.Type.IMPORT;
this.wb = WorkbookFactory.create(is);
List<T> list = null;
@@ -218,7 +218,7 @@ public class ExcelUtil<T> {
// 定义一个map用于存放excel列的序号和field.
Map<String, Integer> cellMap = new HashMap<>(16);
// 获取表头
Row heard = sheet.getRow(titleRows);
Row heard = sheet.getRow(0);
for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) {
Cell cell = heard.getCell(i);
if (ObjectUtil.isNotNull(cell)) {
@@ -245,10 +245,8 @@ public class ExcelUtil<T> {
}
}
}
//数据读取行数 默认表头+1
Integer startRow = heard.getRowNum()+1;
// 将数据填入集合
list = fillCollection(sheet, rows, fieldsMap, startRow);
list = fillCollection(sheet, rows, fieldsMap);
}
return list;
}
@@ -1132,10 +1130,10 @@ public class ExcelUtil<T> {
* @throws InstantiationException 实例创建异常
* @throws IllegalAccessException 实例创建异常
*/
private List<T> fillCollection(Sheet sheet, int rows, Map<Integer, Field> fieldsMap,Integer startRow) throws InstantiationException, IllegalAccessException {
private List<T> fillCollection(Sheet sheet, int rows, Map<Integer, Field> fieldsMap) throws InstantiationException, IllegalAccessException {
List<T> list = new ArrayList<>();
int j=startRow;
for (int i = j; i < rows; i++) {
int j=1;
for (int i = 0; i < rows-1; i++) {
// 从第2行开始取数据,默认第一行是表头.
Row row = sheet.getRow(j);
j++;