Merge #59 into master from cc_2021104_twelve_points

fix:十二分问题修复

* cc_2021104_twelve_points: (58 commits squashed)

  - fix:启用禁用规则合并

  - Merge branch 'refs/heads/master' into cc_2021104_twelve_points

  - fix:惩处规则列表新增描述字段

  - fix:新增用户管辖门店列表接口

  - fix:门店列表接口新增门店积分字段

  - fix:查询问题修复;新增草稿状态

  - fix:申请单审批补充审批人字段

  - fix:修改门店积分限制0-12

  - fix:积分流水接口修复;申请单查询接口添加日期筛选

  - fix:惩处单查询提供惩处待处理、惩处已处理状态筛选

  - fix:惩处单复议申请查询异常修复

  - fix:小程序惩处单详情接口字段补充

  - fix:查询字段补充

  - fix

  - fix:转义

  - fix

  - fix:新增撤销复议申请单接口

  - fix:补充字段

  - fix:补充字段

  - fix:新增门店分数接口

  - fix:申请单新增筛选条件

  - fix:门店积分接口返回参数修改

  - fix:小程序规则分页查询接口改为Post

  - fix:问题修复

  - fix:十二分导入

  - fix:导入状态部分失败改为失败

  - fix:字段补充

  - fix:异步下Excel导入图片临时文件被清理的问题

  - fix:扣分申请导入图片路径修改并使用CDN

  - fix:导入图片上传oss文件类型修改为图片

  - fix:批量审批

  - fix:批量审批新增备注字段

  - fix:字段补充

  - Merge branch 'master' into cc_2021104_twelve_points
    
    # Conflicts:
    #	coolstore-partner-common/src/main/java/com/cool/store/constants/RedisConstant.java
    #	coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java
    #	coolstore-partner-dao/src/main/java/com/cool/store/dao/StoreDao.java
    #	coolstore-partner-dao/src/main/java/com/cool/store/mapper/StoreMapper.java
    #	coolstore-partner-dao/src/main/resources/mapper/StoreMapper.xml
    #	coolstore-partner-web/src/main/java/com/cool/store/controller/webb/PCStoreController.java

  - fix:字典项新增排序、编辑删除权限、关联字典项

  - Merge branch 'master' into cc_2021104_twelve_points

  - fix:十二分值-扣分列表申请复议截止日期格式

  - fix:去除appealEndDate格式校验

  - Merge remote-tracking branch 'origin/cc_20260128_dict_update' into cc_20260205_twelve_points_v2

  - Merge branch 'cc_20260128_dict_update' into cc_2021104_twelve_points

  - fix:字典回显包含已删除字典项

  - Merge branch 'master' into cc_2021104_twelve_points

  - Merge remote-tracking branch 'origin/cc_20260205_twelve_points_v2' into cc_2021104_twelve_points

  - fix:去除惩处单审批阶段;复议申请单证明图片非必填

  - fix:复议拒绝后惩处单直接生效

  - fix:扣分申请单证明图片改为非必填

  - fix

  - fix:字段转义

  - fix:惩处待处理包含带生效数据

  - fix:字段转义

  - fix:警告单金额和积分初始化为0

  - fix

  - fix:小程序接口字段转义

  - Merge branch 'master' into cc_2021104_twelve_points

  - fix:十二分审批记录展示待审批人

  - fix

  - fix:惩处单复议申请逾期检查改为延时队列

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

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

CR-link: https://codeup.aliyun.com/692ea314dec569489f6f167c/hangzhou/java/custom_zxjp/change/59
This commit is contained in:
王非凡
2026-03-12 09:29:50 +00:00
committed by 正新
parent 170e77fd14
commit 3b8ed0a3b8
12 changed files with 181 additions and 48 deletions

View File

@@ -341,7 +341,7 @@ public class RedisConstant {
* 建店资料总部订货收款账户信息
*/
public static final String BUILD_RECEIVE_BANK_INFO = "zxjp_build_receive_bank_info";
/**
* 加盟线下收款银行默认配置
*/
@@ -352,6 +352,12 @@ public class RedisConstant {
*/
public static final String TP_PENALTY_APPLY_IMPORT_LOCK = "tp_penalty_apply_import_lock";
/**
* 十二分审批按钮权限id
*/
public static final String TP_AUDIT_AUTH_MENU_ID = "tp_audit_auth_menu_id";
public static final String STANDARD_STORE_PAY_LOCK_KEY = "standard_store_pay_lock_key:{0}";
/**

View File

@@ -38,6 +38,7 @@ public enum RocketMqGroupEnum {
STORE_MASTER_ISSUE("store_master_issue", new ArrayList<>(Arrays.asList(RocketMqTagEnum.STORE_MASTER_ISSUE))),
VISIT_RECORD_INVALID("visit_record_invalid", new ArrayList<>(Arrays.asList(RocketMqTagEnum.VISIT_RECORD_INVALID))),
TP_PENALTY_APPEAL_OVERDUE("tp_penalty_appeal_overdue", new ArrayList<>(Arrays.asList(RocketMqTagEnum.TP_PENALTY_APPEAL_OVERDUE))),
;
private final String group;

View File

@@ -22,6 +22,7 @@ public enum RocketMqTagEnum {
DELAY_SHOP_DECORATION_ASSIGN("shop_decoration_assign","门店装修分配"),
STORE_MASTER_ISSUE("store_master_issue","门店主数据下发"),
VISIT_RECORD_INVALID("visit_record_invalid", "拜访记录失效"),
TP_PENALTY_APPEAL_OVERDUE("tp_penalty_appeal_overdue", "十二分惩处单复议逾期"),
;

View File

@@ -137,48 +137,13 @@ public class TpAuditRecordDAO {
* @param applyId 申请单id
* @return 审批记录列表
*/
public List<AuditInfoResponse> getAuditRecordList(Long applyId) {
public List<TpAuditRecordDO> getAuditRecordList(Long applyId) {
Example example = new Example(TpAuditRecordDO.class);
example.createCriteria()
.andEqualTo("applyId", applyId)
.andNotEqualTo("auditStatus", 0)
.andEqualTo("deleted", 0);
example.setOrderByClause("create_time ASC");
List<TpAuditRecordDO> recordList = tpAuditRecordMapper.selectByExample(example);
List<AuditInfoResponse> result = new ArrayList<>();
for (TpAuditRecordDO auditRecordDO : recordList) {
AuditInfoResponse response = AuditInfoResponse.builder()
.type(getAuditInfoType(auditRecordDO))
.execute(auditRecordDO.getRecordType() - 1)
.status(CommonConstants.INDEX_ZERO.equals(auditRecordDO.getAuditStatus()) ? 0 : 1)
.createTime(auditRecordDO.getReceiveTaskTime())
.remark(auditRecordDO.getRemark())
.actualUserId(auditRecordDO.getHandlerUserId())
.build();
List<AuditInfoResponse.AuditUserInfoVO> auditUserList = Collections.singletonList(
new AuditInfoResponse.AuditUserInfoVO(auditRecordDO.getHandlerUserId(), auditRecordDO.getHandlerUserName(), null)
);
response.setList(auditUserList);
result.add(response);
}
return result;
}
private Integer getAuditInfoType(TpAuditRecordDO auditRecordDO) {
if (CommonConstants.INDEX_ONE.equals(auditRecordDO.getRecordType())) {
return OperationLogAuditEnum.SUBMIT_AUDIT.getCode();
} else {
switch (auditRecordDO.getAuditStatus()) {
case 0:
return OperationLogAuditEnum.WAIT_AUDIT.getCode();
case 1:
return OperationLogAuditEnum.PASS.getCode();
case 2:
return OperationLogAuditEnum.REFUSE.getCode();
default:
return null;
}
}
return tpAuditRecordMapper.selectByExample(example);
}
/**

View File

@@ -1,6 +1,7 @@
package com.cool.store.mapper;
import com.cool.store.dto.UserRoleDTO;
import com.cool.store.dto.openPreparation.UserNameDTO;
import com.cool.store.dto.store.StoreUserDTO;
import com.cool.store.entity.EnterpriseUserRole;
import com.cool.store.entity.SysRoleDO;
@@ -115,6 +116,8 @@ public interface SysRoleMapper {
*/
List<String> getPositionUserIds( @Param("positionIds") List<String> positionIds);
List<UserNameDTO> getPositionUsers(@Param("positionIds") List<String> positionIds);
List<EnterpriseUserRole> selectUserRoleBySourceAndUserId(@Param("source") String source ,
@Param("userIdList") List<String> userIdList);

View File

@@ -296,6 +296,17 @@
and eu.active = true
</select>
<select id="getPositionUsers" resultType="com.cool.store.dto.openPreparation.UserNameDTO">
select eu.user_id, eu.name from
enterprise_user_role_${enterpriseId} eur
left join enterprise_user_${enterpriseId} eu USING(user_id)
where eur.role_id in
<foreach collection="positionIds" item="roleId" open="(" separator="," close=")">
#{roleId}
</foreach>
and eu.active = true
</select>
<select id="selectUserByDingRole" resultType="java.lang.String">
select b.user_id from sys_role_${enterpriseId} a
left join enterprise_user_role_${enterpriseId} b on a.id=b.role_id

View File

@@ -35,4 +35,8 @@ public class TpAppealListVO extends TpApplyListBaseVO {
@ApiModelProperty("复议详细理由")
private String appealDetailReason;
@ApiModelProperty("项目名称")
@DictField
private String projectNameName;
}

View File

@@ -8,10 +8,7 @@ import com.aliyun.openservices.ons.api.bean.Subscription;
import com.cool.store.constants.CommonConstants;
import com.cool.store.enums.RocketMqGroupEnum;
import com.cool.store.mq.RocketMqConfig;
import com.cool.store.mq.consumer.listener.ShopDecorationAssignListener;
import com.cool.store.mq.consumer.listener.StoreUserUpdateListener;
import com.cool.store.mq.consumer.listener.VisitRecordListener;
import com.cool.store.mq.consumer.listener.XfsgTrainingPersonSyncListener;
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;
@@ -41,6 +38,8 @@ public class ConsumerClient {
private ShopDecorationAssignListener shopDecorationAssignListener;
@Resource
private VisitRecordListener visitRecordListener;
@Resource
private TpPenaltyAppealListener tpPenaltyAppealListener;
/**
* 获取通用配置
@@ -133,4 +132,17 @@ public class ConsumerClient {
return consumerBean;
}
@Bean(initMethod = "start", destroyMethod = "shutdown")
public ConsumerBean tpPenaltyAppealOverdue() {
RocketMqGroupEnum groupEnum = RocketMqGroupEnum.TP_PENALTY_APPEAL_OVERDUE;
ConsumerBean consumerBean = new ConsumerBean();
//配置文件
Properties properties = getCommonProperties(groupEnum);
consumerBean.setProperties(properties);
Map<Subscription, MessageListener> commonSubscriptionTable = getCommonSubscriptionTable(groupEnum, tpPenaltyAppealListener);
//订阅多个topic如上面设置
consumerBean.setSubscriptionTable(commonSubscriptionTable);
return consumerBean;
}
}

View File

@@ -0,0 +1,53 @@
package com.cool.store.mq.consumer.listener;
import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.MessageListener;
import com.cool.store.constants.CommonConstants;
import com.cool.store.service.tp.TpApplyService;
import com.cool.store.utils.RedisUtilPool;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
/**
* <p>
* 十二分惩处单复议申请逾期
* </p>
*
* @author wangff
* @since 2026/3/10
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class TpPenaltyAppealListener implements MessageListener {
private final RedisUtilPool redisUtilPool;
private final TpApplyService tpApplyService;
@Override
public Action consume(Message message, ConsumeContext consumeContext) {
String text = new String(message.getBody());
if (StringUtils.isBlank(text)) {
log.info("消息体为空,tag:{},messageId:{}", message.getTag(), message.getMsgID());
return Action.CommitMessage;
}
String lockKey = "TpPenaltyAppealListener:" + message.getMsgID();
boolean lock = redisUtilPool.setNxExpire(lockKey, message.getMsgID(), CommonConstants.NORMAL_LOCK_TIMES);
if (lock) {
try {
tpApplyService.appealOverdue(Long.valueOf(text));
} catch (Exception e) {
log.error("TpPenaltyAppealListener consume error", e);
return Action.ReconsumeLater;
} finally {
redisUtilPool.delKey(lockKey);
}
log.info("消费成功,tag:{},messageId:{},reqBody={}", message.getTag(), message.getMsgID(), text);
return Action.CommitMessage;
}
return Action.ReconsumeLater;
}
}

View File

@@ -156,6 +156,12 @@ public interface TpApplyService {
*/
Boolean acceptPenalty(Long applyId);
/**
* 复议逾期
* @param applyId 惩处申请单id
*/
void appealOverdue(Long applyId);
/**
* 完成缴费
* @param applyId 惩处申请单id

View File

@@ -10,20 +10,23 @@ import com.cool.store.dao.EnterpriseUserDAO;
import com.cool.store.dao.StoreDao;
import com.cool.store.dao.tp.*;
import com.cool.store.dto.ImportOaOldShopDataErrorDTO;
import com.cool.store.dto.openPreparation.UserNameDTO;
import com.cool.store.dto.tp.TpPenaltyImportErrorDTO;
import com.cool.store.entity.ImportTaskDO;
import com.cool.store.entity.StoreDO;
import com.cool.store.entity.tp.TpApplyFormDO;
import com.cool.store.entity.tp.TpAuditRecordDO;
import com.cool.store.entity.tp.TpRuleDO;
import com.cool.store.entity.tp.TpScoreJournalDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.FileTypeEnum;
import com.cool.store.enums.ImportTaskStatusEnum;
import com.cool.store.enums.*;
import com.cool.store.enums.tp.TpFormStatusEnum;
import com.cool.store.enums.tp.TpFormTypeEnum;
import com.cool.store.enums.tp.TpPayStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.ImportTaskMapper;
import com.cool.store.mapper.SysRoleMapper;
import com.cool.store.mapper.SysRoleMenuMapper;
import com.cool.store.mq.producer.SimpleMessageService;
import com.cool.store.oss.OssClientService;
import com.cool.store.request.tp.*;
import com.cool.store.response.AuditInfoResponse;
@@ -41,6 +44,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
@@ -57,6 +61,7 @@ import java.time.LocalDateTime;
import java.time.ZoneId;
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;
@@ -86,8 +91,13 @@ public class TpApplyServiceImpl implements TpApplyService {
@Resource(name = "generalThreadPool")
private ThreadPoolTaskExecutor executor;
private final EasyExcelUtil easyExcelUtil;
private final SysRoleMenuMapper sysRoleMenuMapper;
private final SimpleMessageService simpleMessageService;
@Value("${mybatis.configuration.variables.enterpriseId}")
private String eid;
@Autowired
private SysRoleMapper sysRoleMapper;
@Override
@Transactional
@@ -163,6 +173,8 @@ public class TpApplyServiceImpl implements TpApplyService {
// 第一次提交后添加审批记录
if (!isDraft) {
tpAuditRecordDAO.firstAddRecord(formDO.getId(), formDO.getType(), request.getApplyUserId(), request.getApplyUserName());
// 发送延时任务
simpleMessageService.send(String.valueOf(formDO.getId()), RocketMqTagEnum.TP_PENALTY_APPEAL_OVERDUE, formDO.getAppealEndDate().getTime());
}
return true;
}
@@ -314,7 +326,56 @@ public class TpApplyServiceImpl implements TpApplyService {
@Override
public List<AuditInfoResponse> getAuditRecordList(Long applyId) {
return tpAuditRecordDAO.getAuditRecordList(applyId);
List<TpAuditRecordDO> list = tpAuditRecordDAO.getAuditRecordList(applyId);
List<AuditInfoResponse> result = new ArrayList<>();
for (TpAuditRecordDO auditRecordDO : list) {
AuditInfoResponse response = AuditInfoResponse.builder()
.type(getAuditInfoType(auditRecordDO))
.execute(auditRecordDO.getRecordType() - 1)
.status(CommonConstants.INDEX_ZERO.equals(auditRecordDO.getAuditStatus()) ? 0 : 1)
.createTime(auditRecordDO.getReceiveTaskTime())
.remark(auditRecordDO.getRemark())
.actualUserId(auditRecordDO.getHandlerUserId())
.build();
if (CommonConstants.INDEX_ZERO.equals(auditRecordDO.getAuditStatus())) {
// 待审批记录根据功能权限分解待审批人
String menuId = redisUtilPool.hashGet(RedisConstant.TP_AUDIT_AUTH_MENU_ID, String.valueOf(auditRecordDO.getApplyType()));
if (StringUtils.isNotBlank(menuId)) {
List<Long> roleIds = sysRoleMenuMapper.listSysRoleMenuIdByMenuId(PlatFormTypeEnum.PC.getCode(), Long.valueOf(menuId));
// 根据角色分解用户
if (CollectionUtils.isNotEmpty(roleIds)) {
List<UserNameDTO> users = sysRoleMapper.getPositionUsers(roleIds.stream().map(String::valueOf).collect(Collectors.toList()));
List<AuditInfoResponse.AuditUserInfoVO> auditUserList = CollStreamUtil.toList(users, v -> new AuditInfoResponse.AuditUserInfoVO(v.getUserId(), v.getName(), null));
response.setList(auditUserList);
result.add(response);
}
}
} else {
List<AuditInfoResponse.AuditUserInfoVO> auditUserList = Collections.singletonList(
new AuditInfoResponse.AuditUserInfoVO(auditRecordDO.getHandlerUserId(), auditRecordDO.getHandlerUserName(), null)
);
response.setList(auditUserList);
result.add(response);
}
}
return result;
}
private Integer getAuditInfoType(TpAuditRecordDO auditRecordDO) {
if (CommonConstants.INDEX_ONE.equals(auditRecordDO.getRecordType())) {
return OperationLogAuditEnum.SUBMIT_AUDIT.getCode();
} else {
switch (auditRecordDO.getAuditStatus()) {
case 0:
return OperationLogAuditEnum.WAIT_AUDIT.getCode();
case 1:
return OperationLogAuditEnum.PASS.getCode();
case 2:
return OperationLogAuditEnum.REFUSE.getCode();
default:
return null;
}
}
}
@Override
@@ -380,6 +441,16 @@ public class TpApplyServiceImpl implements TpApplyService {
return true;
}
@Override
@Transactional
public void appealOverdue(Long applyId) {
TpApplyFormDO formDO = tpApplyFormDAO.getEffectiveById(applyId);
if (Objects.nonNull(formDO) && (TpFormStatusEnum.PASS.getStatus().equals(formDO.getStatus()) || TpFormStatusEnum.INEFFECTIVE.getStatus().equals(formDO.getStatus()))) {
tpApplyFormDAO.updateStatus(applyId, TpFormStatusEnum.EFFECTIVE);
scoreChange(formDO);
}
}
@Override
public Boolean completePayment(Long applyId) {
TpApplyFormDO formDO = tpApplyFormDAO.getEffectiveById(applyId);
@@ -450,7 +521,7 @@ public class TpApplyServiceImpl implements TpApplyService {
*/
@Override
public void scoreChange(TpApplyFormDO formDO) {
if (TpFormStatusEnum.PASS.getStatus().equals(formDO.getStatus())) {
if (TpFormStatusEnum.PASS.getStatus().equals(formDO.getStatus()) || TpFormStatusEnum.INEFFECTIVE.getStatus().equals(formDO.getStatus()) && TpFormTypeEnum.isPenalty(formDO.getType())) {
BigDecimal occurBeforeScore = storeDao.getStoreScore(formDO.getStoreId());
BigDecimal occurAfterScore = null;
String occurScore = "";

View File

@@ -539,7 +539,7 @@ public class XxlJobHandler {
int pageNum = 1;
int pageSize = CommonConstants.BATCH_SIZE;
TpApplyQueryRequest request = new TpApplyQueryRequest();
request.setStatusList(Collections.singletonList(TpFormStatusEnum.PASS.getStatus()));
request.setStatusList(Arrays.asList(TpFormStatusEnum.PASS.getStatus(), TpFormStatusEnum.INEFFECTIVE.getStatus()));
request.setIsPenalty(true);
request.setIsDraft(0);
request.setOverdue(true);