fix:十二分制-奖惩规则

This commit is contained in:
wangff
2025-11-07 15:12:25 +08:00
parent 85a411bc9a
commit a3d0f9572c
41 changed files with 1534 additions and 38 deletions

View File

@@ -232,4 +232,7 @@ public class CommonConstants {
public static final int REFRESH_TOKEN_EXPIRE = 30 * 24 * 60 * 60; public static final int REFRESH_TOKEN_EXPIRE = 30 * 24 * 60 * 60;
public static final int BATCH_SIZE = 200; public static final int BATCH_SIZE = 200;
public static final Integer INDEX_ZERO = 0;
public static final Integer INDEX_ONE = 1;
} }

View File

@@ -315,6 +315,16 @@ public enum ErrorCodeEnum {
JOIN_MODE_NOT_ALLOW_OPERATE(1610012,"加盟部人员只能新建加盟店或联营店,请确认!",null), JOIN_MODE_NOT_ALLOW_OPERATE(1610012,"加盟部人员只能新建加盟店或联营店,请确认!",null),
STORE_NOT_FIND(1610013,"门店不存在",null), STORE_NOT_FIND(1610013,"门店不存在",null),
/**
* 181 十二分制
*/
TP_NOT_EXIST_RULE(1810000, "不存在该规则", null),
TP_MONTH_EXIST_APPLY(1810001, "该门店一个月内存在相同项目的加分申请", null),
TP_SCORE_EQUAL_TWELVE(1810002, "该门店已满12分无法申请加分", null),
TP_NOT_EXIST_PENDING_AUDIT(1810003, "申请单不存在待审批记录", null),
TP_NOT_EXIST_APPLY_FORM(1810004, "不存在申请单", null),
TP_APPLY_AUDIT_COMPLETED(1810005, "该申请单已审批", null),
TP_EXISTS_PENDING_APPLY(1810006, "存在待审批的申请单", null),
; ;

View File

@@ -0,0 +1,38 @@
package com.cool.store.enums.tp;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* <p>
* 十二分制-单据状态 枚举类
* </p>
*
* @author wangff
* @since 2025/11/5
*/
@Getter
@AllArgsConstructor
public enum TpFormStatusEnum {
PENDING("pending", "审批中"),
PASS("pass", "审批通过"),
REJECT("reject", "审批拒绝"),
EFFECTIVE("effective", "已生效"),
CANCEL("cancel", "已作废"),
;
private final String status;
private final String msg;
public static String getMsgByStatus(String status) {
for (TpFormStatusEnum value : values()) {
if (value.status.equals(status)) {
return value.msg;
}
}
return null;
}
}

View File

@@ -0,0 +1,44 @@
package com.cool.store.enums.tp;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* <p>
* 十二分制-单据类型 枚举类
* </p>
*
* @author wangff
* @since 2025/11/6
*/
@Getter
@AllArgsConstructor
public enum TpFormTypeEnum {
REWARD(0, "加分申请单"),
WARNING(1, "警告书"),
PENALTY(2, "处罚书"),
;
private final Integer type;
private final String msg;
public static String getMsgByType(Integer type) {
for (TpFormTypeEnum value : values()) {
if (value.type.equals(type)) {
return value.msg;
}
}
return null;
}
public static TpFormTypeEnum getByType(Integer type) {
for (TpFormTypeEnum value : values()) {
if (value.type.equals(type)) {
return value;
}
}
return null;
}
}

View File

@@ -0,0 +1,35 @@
package com.cool.store.enums.tp;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* <p>
* 十二分制-缴费状态 枚举类
* </p>
*
* @author wangff
* @since 2025/11/5
*/
@Getter
@AllArgsConstructor
public enum TpPayStatusEnum {
UNPAID(0, "未缴费"),
NO_NEED_PAY(1, "无需缴费"),
PAID(2, "已缴费")
;
private final Integer status;
private final String msg;
public static String getMsgByStatus(Integer status) {
for (TpPayStatusEnum value : values()) {
if (value.status.equals(status)) {
return value.msg;
}
}
return null;
}
}

View File

@@ -1,5 +1,7 @@
package com.cool.store.utils; package com.cool.store.utils;
import com.cool.store.enums.tp.TpFormTypeEnum;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
@@ -15,16 +17,30 @@ public class TpHelper {
private final static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyMMddHHmmssSSS"); private final static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyMMddHHmmssSSS");
/** /**
* 生成惩处单号 * 生成奖惩规则编码
* @param isReward 是否为加分规则
* @return 规则编码
*/ */
public static String generatePenaltyRuleCode() { public static String generateRuleNo(boolean isReward) {
return "CC" + generateCode(); return (isReward ? "JR" : "CR") + generateCode();
} }
/** /**
* 生成加分单 * 生成积分流水
*/ */
public static String generateRewardRuleCode() { public static String generateScoreJournalNo() {
return "JF" + generateCode(); return "LS" + generateCode();
}
/**
* 生成申请单号
* @param applyType 单据类型
* @return 申请单号
*/
public static String generateApplyNo(Integer applyType) {
TpFormTypeEnum type = TpFormTypeEnum.getByType(applyType);
if (type == null) return null;
return (TpFormTypeEnum.REWARD.equals(type) ? "JF" : TpFormTypeEnum.PENALTY.equals(type) ? "CF" : "JG") + generateCode();
} }
private static String generateCode() { private static String generateCode() {

View File

@@ -1,5 +1,6 @@
package com.cool.store.dao; package com.cool.store.dao;
import cn.hutool.core.collection.CollStreamUtil;
import com.cool.store.dto.store.StoreOrderTimeDTO; import com.cool.store.dto.store.StoreOrderTimeDTO;
import com.cool.store.entity.StoreDO; import com.cool.store.entity.StoreDO;
import com.cool.store.mapper.StoreMapper; import com.cool.store.mapper.StoreMapper;
@@ -7,11 +8,12 @@ import com.cool.store.response.MiniShopsResponse;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList; import java.math.BigDecimal;
import java.util.List; import java.util.*;
@Repository @Repository
public class StoreDao { public class StoreDao {
@@ -30,6 +32,13 @@ public class StoreDao {
return storeMapper.getByStoreId(storeId); return storeMapper.getByStoreId(storeId);
} }
public StoreDO getEffectiveByStoreId(String storeId) {
if(StringUtils.isBlank(storeId)) {
return null;
}
return storeMapper.getEffectiveByStoreId(storeId);
}
public List<StoreDO> getEffectiveStoreByStoreIds(List<String> storeIdList) { public List<StoreDO> getEffectiveStoreByStoreIds(List<String> storeIdList) {
if(CollectionUtils.isEmpty(storeIdList)) { if(CollectionUtils.isEmpty(storeIdList)) {
return Lists.newArrayList(); return Lists.newArrayList();
@@ -102,4 +111,39 @@ public class StoreDao {
public List<StoreDO> getAllStoreIdAndNum(List<String> storeStatus) { public List<StoreDO> getAllStoreIdAndNum(List<String> storeStatus) {
return storeMapper.getAllStoreIdAndNum(storeStatus); return storeMapper.getAllStoreIdAndNum(storeStatus);
} }
/**
* 查询门店积分
* @param storeId 门店id
* @return 积分
*/
public BigDecimal getStoreScore(@Param("storeId") String storeId) {
BigDecimal score = storeMapper.getStoreScore(storeId);
if (Objects.isNull(score)) {
return BigDecimal.valueOf(12.0);
}
return score;
}
/**
* 根据门店id查询门店映射
* @param storeIds 门店id列表
* @return 门店id->门店
*/
public Map<String, StoreDO> getStoreMapByStoreIds(List<String> storeIds) {
if (CollectionUtils.isNotEmpty(storeIds)) {
return Collections.emptyMap();
}
List<StoreDO> storeList = storeMapper.getStoreByStoreIds(storeIds);
return CollStreamUtil.toMap(storeList, StoreDO::getStoreId, v -> v);
}
/**
* 更新门店积分
* @param storeId 门店id
* @param score 积分
*/
public boolean updateStoreScore(String storeId, BigDecimal score) {
return storeMapper.updateStoreScore(storeId, score) > 0;
}
} }

View File

@@ -0,0 +1,121 @@
package com.cool.store.dao.tp;
import com.cool.store.entity.tp.TpApplyFormDO;
import com.cool.store.enums.tp.TpFormStatusEnum;
import com.cool.store.enums.tp.TpFormTypeEnum;
import com.cool.store.mapper.tp.TpApplyFormMapper;
import com.cool.store.request.tp.TpApplyQueryRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.entity.Example;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* <p>
* 十二分制-申请单DAO
* </p>
*
* @author wangff
* @since 2025/11/5
*/
@Repository
@RequiredArgsConstructor
public class TpApplyFormDAO {
private final TpApplyFormMapper tpApplyFormMapper;
/**
* 新增
*/
public boolean insertSelective(TpApplyFormDO tpApplyFormDO) {
return tpApplyFormMapper.insertSelective(tpApplyFormDO) > 0;
}
/**
* 编辑
*/
public boolean updateSelective(TpApplyFormDO tpApplyFormDO) {
return tpApplyFormMapper.updateByPrimaryKeySelective(tpApplyFormDO) > 0;
}
public boolean insertOrUpdate(TpApplyFormDO tpApplyFormDO) {
if (Objects.isNull(tpApplyFormDO.getId())) {
return tpApplyFormMapper.insertSelective(tpApplyFormDO) > 0;
} else {
return tpApplyFormMapper.updateByPrimaryKeySelective(tpApplyFormDO) > 0;
}
}
/**
* 一个月内是否存在相同加分申请
* @param storeId 门店id
* @param ruleId 规则id
* @return 是否存在
*/
public boolean existPassRewardForm(String storeId, Long ruleId) {
Example example = new Example(TpApplyFormDO.class);
example.createCriteria()
.andEqualTo("type", 0)
.andEqualTo("storeId", storeId)
.andEqualTo("ruleId", ruleId)
.andEqualTo("status", TpFormStatusEnum.PASS.getStatus())
.andGreaterThan("approveTime", LocalDate.now().minusMonths(1));
return tpApplyFormMapper.selectCountByExample(example) > 0;
}
/**
* 根据id查询
*/
public TpApplyFormDO getById(Long id) {
return tpApplyFormMapper.selectByPrimaryKey(id);
}
/**
* 查询有效记录列表
* @param request 申请单查询Request
* @return 申请单列表
*/
public List<TpApplyFormDO> getEffectiveList(TpApplyQueryRequest request) {
return tpApplyFormMapper.getEffectiveList(request);
}
/**
* 查询门店相同规则的惩处单数量
* @param storeId 门店id
* @param ruleId 规则id
* @return 数量
*/
public int getPenaltyCount(String storeId, Long ruleId) {
Example example = new Example(TpApplyFormDO.class);
example.createCriteria()
.andEqualTo("storeId", storeId)
.andEqualTo("ruleId", ruleId)
.andIn("status", Arrays.asList(TpFormStatusEnum.PASS.getStatus(), TpFormStatusEnum.EFFECTIVE.getStatus()))
.andNotEqualTo("type", TpFormTypeEnum.REWARD.getType());
return tpApplyFormMapper.selectCountByExample(example);
}
/**
* 是否存在待审批的申请单
* @param storeId 门店id
* @param ruleId 规则id
* @param isReward 是否是加分申请
* @return 是否存在
*/
public boolean existsPendingApply(String storeId, Long ruleId, boolean isReward) {
Example example = new Example(TpApplyFormDO.class);
Example.Criteria criteria = example.createCriteria()
.andEqualTo("storeId", storeId)
.andEqualTo("ruleId", ruleId)
.andEqualTo("status", TpFormStatusEnum.PENDING.getStatus());
if (isReward) {
criteria.andEqualTo("type", TpFormTypeEnum.REWARD.getType());
} else {
criteria.andNotEqualTo("type", TpFormTypeEnum.REWARD.getType());
}
return tpApplyFormMapper.selectCountByExample(example) > 0;
}
}

View File

@@ -0,0 +1,122 @@
package com.cool.store.dao.tp;
import com.cool.store.entity.tp.TpAuditRecordDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.tp.TpAuditRecordMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import java.util.Date;
import java.util.Objects;
/**
* <p>
* 十二分制-审批记录DAO
* </p>
*
* @author wangff
* @since 2025/11/6
*/
@Repository
@RequiredArgsConstructor
public class TpAuditRecordDAO {
private final TpAuditRecordMapper tpAuditRecordMapper;
/**
* 新增提交记录
* @param applyId 申请单id
* @param applyType 单据类型0加分单 1警告书 2处罚书
* @param userId 申请人id
* @param userName 申请人名称
*/
public void addSubmitRecord(Long applyId, Integer applyType, String userId, String userName) {
Date now = new Date();
TpAuditRecordDO recordDO = TpAuditRecordDO.builder()
.applyType(applyType)
.applyId(applyId)
.recordType(1)
.auditStatus(1)
.handlerUserId(userId)
.handlerUserName(userName)
.receiveTaskTime(now)
.finishTaskTime(now)
.build();
tpAuditRecordMapper.insertSelective(recordDO);
}
/**
* 新增审批记录
* @param applyId 申请单id
* @param applyType 单据类型0加分单 1警告书 2处罚书
*/
public void addApproveRecord(Long applyId, Integer applyType) {
Date now = new Date();
TpAuditRecordDO recordDO = TpAuditRecordDO.builder()
.applyType(applyType)
.applyId(applyId)
.recordType(2)
.auditStatus(0)
.receiveTaskTime(now)
.finishTaskTime(now)
.build();
tpAuditRecordMapper.insertSelective(recordDO);
}
/**
* 首次发起流程
* @param applyId 申请单id
* @param applyType 单据类型0加分单 1警告书 2处罚书
* @param userId 申请人id
* @param userName 申请人名称
*/
public void addRecord(Long applyId, Integer applyType, String userId, String userName) {
addSubmitRecord(applyId, applyType, userId, userName);
addApproveRecord(applyId, applyType);
}
/**
* 根据申请单id查询待审批记录
* @param applyId 申请单id
* @param applyType 单据类型0加分单 1警告书 2处罚书
* @return 审批记录
*/
public TpAuditRecordDO getPendingRecordByApplyId(Long applyId, Integer applyType) {
TpAuditRecordDO recordDO = TpAuditRecordDO.builder()
.applyId(applyId)
.applyType(applyType)
.auditStatus(0)
.build();
return tpAuditRecordMapper.selectOne(recordDO);
}
/**
* 根据申请单id审批待处理的审批记录
* @param applyId 申请单id
* @param applyType 单据类型0加分单 1警告书 2处罚书
* @param userId 审批人id
* @param userName 审批人名称
* @param auditStatus 审批状态
* @param remark 备注
* @param auditTime 审批时间
*/
public void auditPendingRecordByApplyId(Long applyId, Integer applyType, String userId, String userName, Integer auditStatus, String remark, Date auditTime) {
TpAuditRecordDO auditRecordDO = getPendingRecordByApplyId(applyId, applyType);
if (Objects.isNull(auditRecordDO)) {
throw new ServiceException(ErrorCodeEnum.TP_NOT_EXIST_PENDING_AUDIT);
}
auditRecordDO.setAuditStatus(auditStatus);
auditRecordDO.setRemark(remark);
auditRecordDO.setHandlerUserId(userId);
auditRecordDO.setHandlerUserName(userName);
auditRecordDO.setFinishTaskTime(auditTime);
updateKeySelective(auditRecordDO);
}
/**
* 编辑
*/
public void updateKeySelective(TpAuditRecordDO recordDO) {
tpAuditRecordMapper.updateByPrimaryKeySelective(recordDO);
}
}

View File

@@ -1,5 +1,6 @@
package com.cool.store.dao.tp; package com.cool.store.dao.tp;
import cn.hutool.core.collection.CollStreamUtil;
import com.cool.store.entity.tp.TpRuleDO; import com.cool.store.entity.tp.TpRuleDO;
import com.cool.store.mapper.tp.TpRuleMapper; import com.cool.store.mapper.tp.TpRuleMapper;
import com.cool.store.request.tp.TpRuleQueryRequest; import com.cool.store.request.tp.TpRuleQueryRequest;
@@ -9,7 +10,9 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.entity.Example; import tk.mybatis.mapper.entity.Example;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
/** /**

View File

@@ -0,0 +1,27 @@
package com.cool.store.dao.tp;
import com.cool.store.entity.tp.TpScoreJournalDO;
import com.cool.store.mapper.tp.TpScoreJournalMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
/**
* <p>
* 十二分制-积分流水DAO
* </p>
*
* @author wangff
* @since 2025/11/6
*/
@Repository
@RequiredArgsConstructor
public class TpScoreJournalDAO {
private final TpScoreJournalMapper tpScoreJournalMapper;
/**
* 新增
*/
public void insertSelective(TpScoreJournalDO record) {
tpScoreJournalMapper.insertSelective(record);
}
}

View File

@@ -7,6 +7,7 @@ import com.cool.store.response.MiniShopsResponse;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
@Mapper @Mapper
@@ -14,7 +15,11 @@ public interface StoreMapper {
StoreDO getByStoreId(@Param("storeId") String storeId); StoreDO getByStoreId(@Param("storeId") String storeId);
StoreDO getEffectiveByStoreId(@Param("storeId") String storeId);
List<StoreDO> getEffectiveStoreByStoreIds(@Param("storeIds") List<String> storeIds); List<StoreDO> getEffectiveStoreByStoreIds(@Param("storeIds") List<String> storeIds);
List<StoreDO> getStoreByStoreIds(@Param("storeIds") List<String> storeIds);
/** /**
* 根据区域Id查询所有门店(包含所有区域子节点) * 根据区域Id查询所有门店(包含所有区域子节点)
* @param regionId * @param regionId
@@ -59,4 +64,18 @@ public interface StoreMapper {
* 查询所有门店id和门店编码 * 查询所有门店id和门店编码
*/ */
List<StoreDO> getAllStoreIdAndNum(@Param("storeStatus") List<String> storeStatus); List<StoreDO> getAllStoreIdAndNum(@Param("storeStatus") List<String> storeStatus);
/**
* 查询门店积分
* @param storeId 门店id
* @return 积分
*/
BigDecimal getStoreScore(@Param("storeId") String storeId);
/**
* 更新门店积分
* @param storeId 门店id
* @param score 积分
*/
int updateStoreScore(String storeId, BigDecimal score);
} }

View File

@@ -1,7 +1,17 @@
package com.cool.store.mapper.tp; package com.cool.store.mapper.tp;
import com.cool.store.entity.tp.TpApplyFormDO; import com.cool.store.entity.tp.TpApplyFormDO;
import com.cool.store.request.tp.TpApplyQueryRequest;
import tk.mybatis.mapper.common.Mapper; import tk.mybatis.mapper.common.Mapper;
import java.util.List;
public interface TpApplyFormMapper extends Mapper<TpApplyFormDO> { public interface TpApplyFormMapper extends Mapper<TpApplyFormDO> {
/**
* 查询有效记录列表
* @param request 申请单查询Request
* @return 申请单列表
*/
List<TpApplyFormDO> getEffectiveList(TpApplyQueryRequest request);
} }

View File

@@ -58,6 +58,12 @@
where store_id = #{storeId} where store_id = #{storeId}
</select> </select>
<select id="getEffectiveByStoreId" resultMap="BaseResultMap">
select *
from store_${enterpriseId}
where store_id = #{storeId} AND is_delete = 'effective'
</select>
<select id="getEffectiveStoreByStoreIds" resultMap="BaseResultMap"> <select id="getEffectiveStoreByStoreIds" resultMap="BaseResultMap">
select * select *
from store_${enterpriseId} from store_${enterpriseId}
@@ -69,6 +75,18 @@
</if> </if>
</select> </select>
<select id="getStoreByStoreIds" resultMap="BaseResultMap">
select *
from store_${enterpriseId}
<where>
<if test="storeIds != null">
<foreach collection="storeIds" item="item" separator="," open="and store_id in (" close=")">
#{item}
</foreach>
</if>
</where>
</select>
<select id="listStoreByRegionId" resultMap="BaseResultMap"> <select id="listStoreByRegionId" resultMap="BaseResultMap">
select * select *
from store_${enterpriseId} from store_${enterpriseId}
@@ -255,4 +273,15 @@
</foreach> </foreach>
</if> </if>
</select> </select>
<select id="getStoreScore" resultType="java.math.BigDecimal">
SELECT score FROM store_extend_info_${enterpriseId}
WHERE store_id = #{storeId}
</select>
<insert id="updateStoreScore">
INSERT INTO store_extend_info_${enterpriseId} (store_id, score) VALUES (#{storeId}, #{score})
ON DUPLICATE KEY UPDATE
score = values(score)
</insert>
</mapper> </mapper>

View File

@@ -17,6 +17,7 @@
<result column="source" jdbcType="BIT" property="source" /> <result column="source" jdbcType="BIT" property="source" />
<result column="approve_user_id" jdbcType="VARCHAR" property="approveUserId" /> <result column="approve_user_id" jdbcType="VARCHAR" property="approveUserId" />
<result column="approve_time" jdbcType="TIMESTAMP" property="approveTime" /> <result column="approve_time" jdbcType="TIMESTAMP" property="approveTime" />
<result column="is_draft" jdbcType="TINYINT" property="isDraft" />
<result column="create_user_id" jdbcType="VARCHAR" property="createUserId" /> <result column="create_user_id" jdbcType="VARCHAR" property="createUserId" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" /> <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" /> <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />

View File

@@ -9,17 +9,22 @@
<result column="type" jdbcType="BIT" property="type" /> <result column="type" jdbcType="BIT" property="type" />
<result column="apply_no" jdbcType="VARCHAR" property="applyNo" /> <result column="apply_no" jdbcType="VARCHAR" property="applyNo" />
<result column="store_id" jdbcType="VARCHAR" property="storeId" /> <result column="store_id" jdbcType="VARCHAR" property="storeId" />
<result column="project_category" jdbcType="VARCHAR" property="projectCategory" />
<result column="rule_id" jdbcType="BIGINT" property="ruleId" /> <result column="rule_id" jdbcType="BIGINT" property="ruleId" />
<result column="rule_no" jdbcType="VARCHAR" property="ruleNo" />
<result column="problem_classification" jdbcType="VARCHAR" property="problemClassification" />
<result column="project_category" jdbcType="VARCHAR" property="projectCategory" />
<result column="project_name" jdbcType="VARCHAR" property="projectName" />
<result column="is_full" jdbcType="BIT" property="isFull" /> <result column="is_full" jdbcType="BIT" property="isFull" />
<result column="point" jdbcType="DECIMAL" property="point" /> <result column="score" jdbcType="DECIMAL" property="score" />
<result column="remark" jdbcType="VARCHAR" property="remark" /> <result column="remark" jdbcType="VARCHAR" property="remark" />
<result column="amount" jdbcType="DECIMAL" property="amount" /> <result column="amount" jdbcType="DECIMAL" property="amount" />
<result column="appeal_end_date" jdbcType="DATE" property="appealEndDate" /> <result column="appeal_end_date" jdbcType="DATE" property="appealEndDate" />
<result column="status" jdbcType="BIT" property="status" /> <result column="status" jdbcType="VARCHAR" property="status" />
<result column="pay_status" jdbcType="BIT" property="payStatus" /> <result column="pay_status" jdbcType="BIT" property="payStatus" />
<result column="is_draft" jdbcType="BIT" property="isDraft" /> <result column="is_draft" jdbcType="BIT" property="isDraft" />
<result column="source" jdbcType="TINYINT" property="source" />
<result column="apply_user_id" jdbcType="VARCHAR" property="applyUserId" /> <result column="apply_user_id" jdbcType="VARCHAR" property="applyUserId" />
<result column="apply_user_name" jdbcType="VARCHAR" property="applyUserName" />
<result column="approve_user_id" jdbcType="VARCHAR" property="approveUserId" /> <result column="approve_user_id" jdbcType="VARCHAR" property="approveUserId" />
<result column="approve_time" jdbcType="TIMESTAMP" property="approveTime" /> <result column="approve_time" jdbcType="TIMESTAMP" property="approveTime" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" /> <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
@@ -27,4 +32,49 @@
<result column="deleted" jdbcType="BIT" property="deleted" /> <result column="deleted" jdbcType="BIT" property="deleted" />
<result column="proof_urls" jdbcType="LONGVARCHAR" property="proofUrls" /> <result column="proof_urls" jdbcType="LONGVARCHAR" property="proofUrls" />
</resultMap> </resultMap>
<sql id="Base_Column_List">
id, type, apply_no, store_id, rule_id, rule_no, problem_classification, project_category, project_name,
is_full, score, remark, amount, appeal_end_date, status, pay_status, is_draft, source, apply_user_id,
apply_user_name, approve_user_id, approve_time, create_time, update_time, deleted, proof_urls
</sql>
<select id="getEffectiveList" parameterType="com.cool.store.request.tp.TpApplyQueryRequest" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM zxjp_tp_apply_form a
<if test="storeNameOrNum != null and storeNameOrNum != ''">
INNER JOIN store_${enterpriseId} b ON a.store_id = b.store_id AND b.is_delete = 'effective'
</if>
<where>
<if test="applyNo != null and applyNo != ''">
AND a.apply_no LIKE CONCAT('%', #{applyNo}, '%')
</if>
<if test="projectCategory != null and projectCategory != ''">
AND a.project_category = #{projectCategory}
</if>
<if test="ruleId != null and ruleId != ''">
AND a.rule_id = #{ruleId}
</if>
<if test="status != null and status != ''">
AND a.status = #{status}
</if>
<if test="type != null">
AND a.type = #{type}
</if>
<if test="payStatus != null">
AND a.pay_status = #{payStatus}
</if>
<if test="score != null">
AND a.score = #{score}
</if>
<if test="isPenalty != null and isPenalty">
AND a.type != 0
</if>
<if test="storeNameOrNum != null and storeNameOrNum != ''">
AND (b.store_name LIKE CONCAT('%', #{storeNameOrNum}, '%')
OR b.store_num LIKE CONCAT('%', #{storeNameOrNum}, '%')
</if>
</where>
</select>
</mapper> </mapper>

View File

@@ -12,6 +12,7 @@
<result column="audit_status" jdbcType="BIT" property="auditStatus" /> <result column="audit_status" jdbcType="BIT" property="auditStatus" />
<result column="remark" jdbcType="VARCHAR" property="remark" /> <result column="remark" jdbcType="VARCHAR" property="remark" />
<result column="handler_user_id" jdbcType="VARCHAR" property="handlerUserId" /> <result column="handler_user_id" jdbcType="VARCHAR" property="handlerUserId" />
<result column="handler_user_name" jdbcType="VARCHAR" property="handlerUserName" />
<result column="receive_task_time" jdbcType="TIMESTAMP" property="receiveTaskTime" /> <result column="receive_task_time" jdbcType="TIMESTAMP" property="receiveTaskTime" />
<result column="finish_task_time" jdbcType="TIMESTAMP" property="finishTaskTime" /> <result column="finish_task_time" jdbcType="TIMESTAMP" property="finishTaskTime" />
<result column="deleted" jdbcType="BIT" property="deleted" /> <result column="deleted" jdbcType="BIT" property="deleted" />

View File

@@ -6,13 +6,13 @@
WARNING - @mbg.generated WARNING - @mbg.generated
--> -->
<id column="id" jdbcType="BIGINT" property="id" /> <id column="id" jdbcType="BIGINT" property="id" />
<result column="rule_code" jdbcType="VARCHAR" property="ruleCode" /> <result column="rule_no" jdbcType="VARCHAR" property="ruleNo" />
<result column="type" jdbcType="BIT" property="type" /> <result column="type" jdbcType="BIT" property="type" />
<result column="problem_classification" jdbcType="VARCHAR" property="problemClassification" /> <result column="problem_classification" jdbcType="VARCHAR" property="problemClassification" />
<result column="project_category" jdbcType="VARCHAR" property="projectCategory" /> <result column="project_category" jdbcType="VARCHAR" property="projectCategory" />
<result column="project_name" jdbcType="VARCHAR" property="projectName" /> <result column="project_name" jdbcType="VARCHAR" property="projectName" />
<result column="warning_limit" jdbcType="INTEGER" property="warningLimit" /> <result column="warning_limit" jdbcType="INTEGER" property="warningLimit" />
<result column="point" jdbcType="DECIMAL" property="point" /> <result column="score" jdbcType="DECIMAL" property="score" />
<result column="amount" jdbcType="DECIMAL" property="amount" /> <result column="amount" jdbcType="DECIMAL" property="amount" />
<result column="appeal_deadline" jdbcType="INTEGER" property="appealDeadline" /> <result column="appeal_deadline" jdbcType="INTEGER" property="appealDeadline" />
<result column="status" jdbcType="BIT" property="status" /> <result column="status" jdbcType="BIT" property="status" />

View File

@@ -13,7 +13,7 @@
<result column="join_model" jdbcType="BIT" property="joinModel" /> <result column="join_model" jdbcType="BIT" property="joinModel" />
<result column="store_type" jdbcType="BIT" property="storeType" /> <result column="store_type" jdbcType="BIT" property="storeType" />
<result column="store_name" jdbcType="VARCHAR" property="storeName" /> <result column="store_name" jdbcType="VARCHAR" property="storeName" />
<result column="occur_score" jdbcType="DECIMAL" property="occurScore" /> <result column="occur_score" jdbcType="VARCHAR" property="occurScore" />
<result column="occur_date" jdbcType="DATE" property="occurDate" /> <result column="occur_date" jdbcType="DATE" property="occurDate" />
<result column="occur_before_score" jdbcType="DECIMAL" property="occurBeforeScore" /> <result column="occur_before_score" jdbcType="DECIMAL" property="occurBeforeScore" />
<result column="occur_after_score" jdbcType="DECIMAL" property="occurAfterScore" /> <result column="occur_after_score" jdbcType="DECIMAL" property="occurAfterScore" />

View File

@@ -70,7 +70,7 @@ public class TpAppealFormDO {
private Integer status; private Integer status;
/** /**
* 来源0crm 1小程序 * 来源0非小程序 1小程序
*/ */
private Integer source; private Integer source;
@@ -85,6 +85,12 @@ public class TpAppealFormDO {
*/ */
@Column(name = "approve_time") @Column(name = "approve_time")
private Date approveTime; private Date approveTime;
/**
* 是否为草稿 0否 1是
*/
@Column(name = "is_draft")
private Integer isDraft;
/** /**
* 创建人id * 创建人id

View File

@@ -1,8 +1,12 @@
package com.cool.store.entity.tp; package com.cool.store.entity.tp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date; import java.util.Date;
import javax.persistence.*; import javax.persistence.*;
@@ -16,6 +20,9 @@ import javax.persistence.*;
*/ */
@Table(name = "zxjp_tp_apply_form") @Table(name = "zxjp_tp_apply_form")
@Data @Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class TpApplyFormDO { public class TpApplyFormDO {
/** /**
* id * id
@@ -41,6 +48,24 @@ public class TpApplyFormDO {
@Column(name = "store_id") @Column(name = "store_id")
private String storeId; private String storeId;
/**
* 规则id项目类型
*/
@Column(name = "rule_id")
private Long ruleId;
/**
* 规则编码
*/
@Column(name = "rule_no")
private String ruleNo;
/**
* 问题分类
*/
@Column(name = "problem_classification")
private String problemClassification;
/** /**
* 项目大类 * 项目大类
*/ */
@@ -48,10 +73,10 @@ public class TpApplyFormDO {
private String projectCategory; private String projectCategory;
/** /**
* 规则id项目类型 * 项目名称
*/ */
@Column(name = "rule_id") @Column(name = "project_name")
private Long ruleId; private String projectName;
/** /**
* 是否加满 * 是否加满
@@ -62,7 +87,7 @@ public class TpApplyFormDO {
/** /**
* 分值 * 分值
*/ */
private BigDecimal point; private BigDecimal score;
/** /**
* 备注 * 备注
@@ -70,7 +95,7 @@ public class TpApplyFormDO {
private String remark; private String remark;
/** /**
* 罚款金额 * 金额
*/ */
private BigDecimal amount; private BigDecimal amount;
@@ -78,12 +103,12 @@ public class TpApplyFormDO {
* 申请复议截止日期 * 申请复议截止日期
*/ */
@Column(name = "appeal_end_date") @Column(name = "appeal_end_date")
private Date appealEndDate; private LocalDate appealEndDate;
/** /**
* 状态 * 状态
*/ */
private Integer status; private String status;
/** /**
* 缴费状态0未缴费 1无需缴费 2已缴费 * 缴费状态0未缴费 1无需缴费 2已缴费
@@ -97,12 +122,24 @@ public class TpApplyFormDO {
@Column(name = "is_draft") @Column(name = "is_draft")
private Integer isDraft; private Integer isDraft;
/**
* 来源0非小程序 1小程序
*/
@Column(name = "source")
private Integer source;
/** /**
* 申请人id * 申请人id
*/ */
@Column(name = "apply_user_id") @Column(name = "apply_user_id")
private String applyUserId; private String applyUserId;
/**
* 申请人名称
*/
@Column(name = "apply_user_name")
private String applyUserName;
/** /**
* 审批人id * 审批人id
*/ */

View File

@@ -1,6 +1,9 @@
package com.cool.store.entity.tp; package com.cool.store.entity.tp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date; import java.util.Date;
import javax.persistence.*; import javax.persistence.*;
@@ -15,6 +18,9 @@ import javax.persistence.*;
*/ */
@Table(name = "zxjp_tp_audit_record") @Table(name = "zxjp_tp_audit_record")
@Data @Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class TpAuditRecordDO { public class TpAuditRecordDO {
/** /**
* id * id
@@ -24,7 +30,7 @@ public class TpAuditRecordDO {
private Long id; private Long id;
/** /**
* 单类型0加分申请 1复议申请 * 单类型0加分单 1警告书 2处罚书
*/ */
@Column(name = "apply_type") @Column(name = "apply_type")
private Integer applyType; private Integer applyType;
@@ -58,6 +64,12 @@ public class TpAuditRecordDO {
@Column(name = "handler_user_id") @Column(name = "handler_user_id")
private String handlerUserId; private String handlerUserId;
/**
* 处理人名称
*/
@Column(name = "handler_user_name")
private String handlerUserName;
/** /**
* 收到任务时间 * 收到任务时间
*/ */

View File

@@ -30,8 +30,8 @@ public class TpRuleDO {
/** /**
* 规则编码 * 规则编码
*/ */
@Column(name = "rule_code") @Column(name = "rule_no")
private String ruleCode; private String ruleNo;
/** /**
* 规则类型0扣分 1加分 * 规则类型0扣分 1加分
@@ -65,7 +65,7 @@ public class TpRuleDO {
/** /**
* 分值 * 分值
*/ */
private BigDecimal point; private BigDecimal score;
/** /**
* 罚款金额 * 罚款金额

View File

@@ -1,6 +1,10 @@
package com.cool.store.entity.tp; package com.cool.store.entity.tp;
import com.cool.store.entity.StoreDO;
import com.cool.store.utils.TpHelper;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
@@ -16,6 +20,8 @@ import javax.persistence.*;
*/ */
@Table(name = "zxjp_tp_score_journal") @Table(name = "zxjp_tp_score_journal")
@Data @Data
@AllArgsConstructor
@NoArgsConstructor
public class TpScoreJournalDO { public class TpScoreJournalDO {
/** /**
* id * id
@@ -70,7 +76,7 @@ public class TpScoreJournalDO {
* 发生分值 * 发生分值
*/ */
@Column(name = "occur_score") @Column(name = "occur_score")
private BigDecimal occurScore; private String occurScore;
/** /**
* 发生日期 * 发生日期
@@ -91,7 +97,7 @@ public class TpScoreJournalDO {
private BigDecimal occurAfterScore; private BigDecimal occurAfterScore;
/** /**
* 单据来源0加分申请单 2惩处申请单 * 单据类型0加分单 1警告书 2处罚书
*/ */
@Column(name = "apply_type") @Column(name = "apply_type")
private Integer applyType; private Integer applyType;
@@ -137,4 +143,24 @@ public class TpScoreJournalDO {
*/ */
@Column(name = "update_time") @Column(name = "update_time")
private Date updateTime; private Date updateTime;
public TpScoreJournalDO(StoreDO storeDO, TpApplyFormDO formDO, String occurScore, BigDecimal occurBeforeScore, BigDecimal occurAfterScore) {
this.journalNo = TpHelper.generateScoreJournalNo();
this.storeId = storeDO.getStoreId();
this.storeNum = storeDO.getStoreNum();
this.joinBrand = storeDO.getJoinBrand();
this.joinModel = storeDO.getJoinModel();
this.storeType = storeDO.getStoreType();
this.storeName = storeDO.getStoreName();
this.occurScore = occurScore;
this.occurDate = new Date();
this.occurBeforeScore = occurBeforeScore;
this.occurAfterScore = occurAfterScore;
this.applyType = formDO.getType();
this.applyNo = formDO.getApplyNo();
this.projectCategory = formDO.getProjectCategory();
this.projectName = formDO.getProjectName();
this.ruleId = formDO.getRuleId();
this.ruleNo = formDO.getRuleNo();
}
} }

View File

@@ -0,0 +1,31 @@
package com.cool.store.request.tp;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* <p>
* 申请单审批Request
* </p>
*
* @author wangff
* @since 2025/11/6
*/
@Data
public class TpApplyAuditRequest {
@ApiModelProperty("申请单id")
@NotNull(message = "申请单id不能为空")
private Long applyId;
@ApiModelProperty(value = "单据类型0加分单 1警告书 2处罚书", hidden = true)
private Integer applyType;
@ApiModelProperty("审批状态 1通过 2拒绝")
@NotNull(message = "审批状态不能为空")
private Integer auditStatus;
@ApiModelProperty("备注")
private String remark;
}

View File

@@ -0,0 +1,45 @@
package com.cool.store.request.tp;
import com.cool.store.common.PageBasicInfo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* <p>
* 申请单查询Request
* </p>
*
* @author wangff
* @since 2025/11/6
*/
@Data
public class TpApplyQueryRequest extends PageBasicInfo {
@ApiModelProperty("申请单号")
private String applyNo;
@ApiModelProperty("门店名称或编码")
private String storeNameOrNum;
@ApiModelProperty("项目大类")
private String projectCategory;
@ApiModelProperty("规则id")
private String ruleId;
@ApiModelProperty("状态")
private String status;
@ApiModelProperty(value = "单据类型0加分单 1警告书 2处罚书")
private Integer type;
@ApiModelProperty("缴款状态0未缴费 1无需缴费 2已缴费")
private Integer payStatus;
@ApiModelProperty("分值")
private BigDecimal score;
@ApiModelProperty(value = "是惩处单", hidden = true)
private Boolean isPenalty;
}

View File

@@ -0,0 +1,49 @@
package com.cool.store.request.tp;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* <p>
* 奖惩申请Request
* </p>
*
* @author wangff
* @since 2025/11/5
*/
@Data
public class TpApplyRequest {
@ApiModelProperty("id")
private Long id;
@ApiModelProperty("门店id")
@NotNull(message = "门店id不能为空")
private String storeId;
@ApiModelProperty("规则id")
@NotNull(message = "规则id不能为空")
private Long ruleId;
@ApiModelProperty("备注")
private String remark;
@ApiModelProperty("是否为草稿 0否 1是")
@NotNull(message = "是否为草稿不能为空")
private Integer isDraft;
@ApiModelProperty(value = "来源0非小程序 1小程序", hidden = true)
private Integer source;
@ApiModelProperty(value = "申请人id", hidden = true)
private String applyUserId;
@ApiModelProperty(value = "申请人名称", hidden = true)
private String applyUserName;
@ApiModelProperty("证明图片列表,逗号隔开")
@NotBlank(message = "证明图片列表不能为空")
private String proofUrls;
}

View File

@@ -42,7 +42,7 @@ public class TpPenaltyRuleUpdateRequest {
@ApiModelProperty("扣分值") @ApiModelProperty("扣分值")
@NotNull(message = "扣分值不能为空", groups = {InsertGroup.class, UpdateGroup.class}) @NotNull(message = "扣分值不能为空", groups = {InsertGroup.class, UpdateGroup.class})
private BigDecimal point; private BigDecimal score;
@ApiModelProperty("罚款金额") @ApiModelProperty("罚款金额")
@NotNull(message = "罚款金额不能为空", groups = {InsertGroup.class, UpdateGroup.class}) @NotNull(message = "罚款金额不能为空", groups = {InsertGroup.class, UpdateGroup.class})

View File

@@ -37,7 +37,7 @@ public class TpRewardRuleUpdateRequest {
private Integer isFull; private Integer isFull;
@ApiModelProperty("加分值") @ApiModelProperty("加分值")
private BigDecimal point; private BigDecimal score;
@ApiModelProperty("启用状态0未启用 1启用") @ApiModelProperty("启用状态0未启用 1启用")
@NotNull(message = "启用状态不能为空", groups = {InsertGroup.class, UpdateGroup.class}) @NotNull(message = "启用状态不能为空", groups = {InsertGroup.class, UpdateGroup.class})

View File

@@ -0,0 +1,83 @@
package com.cool.store.vo.tp;
import com.cool.store.annotation.DictField;
import com.cool.store.enums.tp.TpFormStatusEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* <p>
* 申请表单列表基础VO
* </p>
*
* @author wangff
* @since 2025/11/6
*/
@Data
public class TpApplyListBaseVO {
@ApiModelProperty("id")
private Long id;
@ApiModelProperty("申请单号")
private String applyNo;
@ApiModelProperty("规则id项目类型")
private Long ruleId;
@ApiModelProperty("规则编码")
private String ruleNo;
@ApiModelProperty("项目大类")
private String projectCategory;
@ApiModelProperty("项目大类名称")
@DictField
private String projectCategoryName;
@ApiModelProperty("分值")
private BigDecimal score;
@ApiModelProperty("项目名称")
private String projectName;
@ApiModelProperty("门店id")
private String storeId;
@ApiModelProperty("门店编码")
private String storeNum;
@ApiModelProperty("门店名称")
private String storeName;
@ApiModelProperty("审批人")
private String approveUserId;
@ApiModelProperty("审批人名称")
private String approveUserName;
@ApiModelProperty("状态")
private String status;
@ApiModelProperty("状态名称")
private String statusName;
@ApiModelProperty("备注")
private String remark;
@ApiModelProperty("申请人名称")
private String applyUserName;
@ApiModelProperty("申请时间")
private Date createTime;
@ApiModelProperty("审核时间")
private Date approveTime;
public String getStatusName() {
return TpFormStatusEnum.getMsgByStatus(this.status);
}
}

View File

@@ -0,0 +1,79 @@
package com.cool.store.vo.tp;
import com.cool.store.annotation.DictField;
import com.cool.store.enums.tp.TpFormTypeEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
/**
* <p>
* 惩处申请详情VO
* </p>
*
* @author wangff
* @since 2025/11/6
*/
@Data
public class TpPenaltyApplyDetailVO {
@ApiModelProperty("id")
private Long id;
@ApiModelProperty("申请单号")
private String applyNo;
@ApiModelProperty("门店id")
private String storeId;
@ApiModelProperty("门店编码")
private String storeNum;
@ApiModelProperty("门店名称")
private String storeName;
@ApiModelProperty("单据类型")
private Integer type;
@ApiModelProperty("单据类型名称")
private String typeName;
@ApiModelProperty("规则id项目类型")
private Long ruleId;
@ApiModelProperty("项目大类")
private String projectCategory;
@ApiModelProperty("项目大类名称")
@DictField
private String projectCategoryName;
@ApiModelProperty("项目名称")
private String projectName;
@ApiModelProperty("分值")
private BigDecimal score;
@ApiModelProperty("金额")
private BigDecimal amount;
@ApiModelProperty("申请复议截止日期")
private LocalDate appealEndDate;
@ApiModelProperty("备注")
private String remark;
@ApiModelProperty("是否为草稿 0否 1是")
private Integer isDraft;
@ApiModelProperty("证明图片列表")
private String proofUrls;
@ApiModelProperty("状态")
private String status;
public String getTypeName() {
return TpFormTypeEnum.getMsgByType(this.type);
}
}

View File

@@ -0,0 +1,47 @@
package com.cool.store.vo.tp;
import com.cool.store.enums.tp.TpFormTypeEnum;
import com.cool.store.enums.tp.TpPayStatusEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
/**
* <p>
* 惩处申请单列表VO
* </p>
*
* @author wangff
* @since 2025/11/6
*/
@Data
public class TpPenaltyApplyListVO extends TpApplyListBaseVO {
@ApiModelProperty("单据类型")
private Integer type;
@ApiModelProperty("单据类型名称")
private String typeName;
@ApiModelProperty("金额")
private BigDecimal amount;
@ApiModelProperty("申请复议截止日期")
private LocalDate appealEndDate;
@ApiModelProperty("缴费状态")
private Integer payStatus;
@ApiModelProperty("缴费状态名称")
private String payStatusName;
public String getTypeName() {
return TpFormTypeEnum.getMsgByType(this.type);
}
public String getPayStatusName() {
return TpPayStatusEnum.getMsgByStatus(this.payStatus);
}
}

View File

@@ -20,7 +20,7 @@ public class TpPenaltyRuleDetailVO {
private Long id; private Long id;
@ApiModelProperty("规则编码") @ApiModelProperty("规则编码")
private String ruleCode; private String ruleNo;
@ApiModelProperty("问题分类") @ApiModelProperty("问题分类")
private String problemClassification; private String problemClassification;
@@ -43,7 +43,7 @@ public class TpPenaltyRuleDetailVO {
private Integer warningLimit; private Integer warningLimit;
@ApiModelProperty("扣分值") @ApiModelProperty("扣分值")
private BigDecimal point; private BigDecimal score;
@ApiModelProperty("罚款金额") @ApiModelProperty("罚款金额")
private BigDecimal amount; private BigDecimal amount;

View File

@@ -20,7 +20,7 @@ public class TpPenaltyRuleListVO {
private Long id; private Long id;
@ApiModelProperty("规则编码") @ApiModelProperty("规则编码")
private String ruleCode; private String ruleNo;
@ApiModelProperty("问题分类") @ApiModelProperty("问题分类")
private String problemClassification; private String problemClassification;
@@ -43,7 +43,7 @@ public class TpPenaltyRuleListVO {
private Integer warningLimit; private Integer warningLimit;
@ApiModelProperty("扣分值") @ApiModelProperty("扣分值")
private BigDecimal point; private BigDecimal score;
@ApiModelProperty("罚款金额") @ApiModelProperty("罚款金额")
private BigDecimal amount; private BigDecimal amount;

View File

@@ -0,0 +1,64 @@
package com.cool.store.vo.tp;
import com.cool.store.annotation.DictField;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* <p>
* 加分申请详情VO
* </p>
*
* @author wangff
* @since 2025/11/6
*/
@Data
public class TpRewardApplyDetailVO {
@ApiModelProperty("id")
private Long id;
@ApiModelProperty("申请单号")
private String applyNo;
@ApiModelProperty("门店id")
private String storeId;
@ApiModelProperty("门店编码")
private String storeNum;
@ApiModelProperty("门店名称")
private String storeName;
@ApiModelProperty("规则id项目类型")
private Long ruleId;
@ApiModelProperty("项目大类")
private String projectCategory;
@ApiModelProperty("项目大类名称")
@DictField
private String projectCategoryName;
@ApiModelProperty("项目名称")
private String projectName;
@ApiModelProperty("是否加满")
private Integer isFull;
@ApiModelProperty("分值")
private BigDecimal score;
@ApiModelProperty("备注")
private String remark;
@ApiModelProperty("是否为草稿 0否 1是")
private Integer isDraft;
@ApiModelProperty("证明图片列表")
private String proofUrls;
@ApiModelProperty("状态")
private String status;
}

View File

@@ -0,0 +1,16 @@
package com.cool.store.vo.tp;
import lombok.Data;
/**
* <p>
* 加分申请单列表VO
* </p>
*
* @author wangff
* @since 2025/11/6
*/
@Data
public class TpRewardApplyListVO extends TpApplyListBaseVO {
}

View File

@@ -20,7 +20,7 @@ public class TpRewardRuleDetailVO {
private Long id; private Long id;
@ApiModelProperty("规则编码") @ApiModelProperty("规则编码")
private String ruleCode; private String ruleNo;
@ApiModelProperty("项目大类") @ApiModelProperty("项目大类")
private String projectCategory; private String projectCategory;
@@ -36,7 +36,7 @@ public class TpRewardRuleDetailVO {
private Integer isFull; private Integer isFull;
@ApiModelProperty("加分值") @ApiModelProperty("加分值")
private BigDecimal point; private BigDecimal score;
@ApiModelProperty("启用状态0未启用 1启用") @ApiModelProperty("启用状态0未启用 1启用")
private Integer status; private Integer status;

View File

@@ -0,0 +1,77 @@
package com.cool.store.service.tp;
import com.cool.store.request.tp.TpApplyAuditRequest;
import com.cool.store.request.tp.TpApplyQueryRequest;
import com.cool.store.request.tp.TpApplyRequest;
import com.cool.store.vo.tp.TpPenaltyApplyDetailVO;
import com.cool.store.vo.tp.TpPenaltyApplyListVO;
import com.cool.store.vo.tp.TpRewardApplyDetailVO;
import com.cool.store.vo.tp.TpRewardApplyListVO;
import com.github.pagehelper.PageInfo;
/**
* <p>
* 十二分制-申请单 服务类
* </p>
*
* @author wangff
* @since 2025/11/5
*/
public interface TpApplyService {
/**
* 加分申请提交
* @param request 奖惩申请Request
* @return 是否成功
*/
Boolean rewardApplySubmit(TpApplyRequest request);
/**
* 加分申请单详情
* @param applyId 申请单id
* @return 加分申请详情VO
*/
TpRewardApplyDetailVO rewardDetail(Long applyId);
/**
* 加分申请单分页查询
* @param request 申请单查询Request
* @return 加分申请单VO列表
*/
PageInfo<TpRewardApplyListVO> rewardPage(TpApplyQueryRequest request);
/**
* 扣分申请提交
* @param request 奖惩申请Request
* @return 是否成功
*/
Boolean penaltyApplySubmit(TpApplyRequest request);
/**
* 惩处申请单详情
* @param applyId 申请单id
* @return 惩处申请详情VO
*/
TpPenaltyApplyDetailVO penaltyDetail(Long applyId);
/**
* 惩处申请单分页查询
* @param request 申请单查询Request
* @return 惩处申请单列表VO列表
*/
PageInfo<TpPenaltyApplyListVO> penaltyPage(TpApplyQueryRequest request);
/**
* 加分申请审批
* @param request 申请单审批Request
* @return 是否成功
*/
Boolean rewardAudit(TpApplyAuditRequest request);
/**
* 惩处申请审批
* @param request 申请单审批Request
* @return 是否成功
*/
Boolean penaltyAudit(TpApplyAuditRequest request);
}

View File

@@ -0,0 +1,283 @@
package com.cool.store.service.tp.impl;
import cn.hutool.core.collection.CollStreamUtil;
import com.cool.store.constants.CommonConstants;
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.tp.TpApplyFormDAO;
import com.cool.store.dao.tp.TpAuditRecordDAO;
import com.cool.store.dao.tp.TpRuleDAO;
import com.cool.store.dao.tp.TpScoreJournalDAO;
import com.cool.store.entity.StoreDO;
import com.cool.store.entity.tp.TpApplyFormDO;
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.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.request.tp.TpApplyAuditRequest;
import com.cool.store.request.tp.TpApplyQueryRequest;
import com.cool.store.request.tp.TpApplyRequest;
import com.cool.store.service.dict.impl.DictService;
import com.cool.store.service.tp.TpApplyService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.TpHelper;
import com.cool.store.vo.tp.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
/**
* <p>
* 十二分制-申请单 服务实现类
* </p>
*
* @author wangff
* @since 2025/11/5
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class TpApplyServiceImpl implements TpApplyService {
private final TpRuleDAO tpRuleDAO;
private final TpApplyFormDAO tpApplyFormDAO;
private final StoreDao storeDao;
private final TpAuditRecordDAO tpAuditRecordDAO;
private final DictService dictService;
private final TpScoreJournalDAO tpScoreJournalDAO;
private final EnterpriseUserDAO enterpriseUserDAO;
@Override
@Transactional
public Boolean rewardApplySubmit(TpApplyRequest request) {
// 1.每个门店一个月内相同加分项仅能申请一次
// 2.门店分值=12时所有加分项不允许申请
boolean isDraft = CommonConstants.INDEX_ONE.equals(request.getIsDraft());
if (!isDraft && tpApplyFormDAO.existPassRewardForm(request.getStoreId(), request.getRuleId())) {
throw new ServiceException(ErrorCodeEnum.TP_MONTH_EXIST_APPLY);
}
if (!isDraft && tpApplyFormDAO.existsPendingApply(request.getStoreId(), request.getRuleId(), true)) {
throw new ServiceException(ErrorCodeEnum.TP_EXISTS_PENDING_APPLY);
}
BigDecimal score = storeDao.getStoreScore(request.getStoreId());
if (!isDraft && BigDecimal.valueOf(12.0).compareTo(score.setScale(1, RoundingMode.DOWN)) == 0) {
throw new ServiceException(ErrorCodeEnum.TP_SCORE_EQUAL_TWELVE);
}
TpApplyFormDO formDO = BeanUtil.toBean(request, TpApplyFormDO.class);
boolean isInsert = Objects.isNull(request.getId());
if (isInsert) {
formDO.setApplyNo(TpHelper.generateApplyNo(TpFormTypeEnum.REWARD.getType()));
formDO.setType(TpFormTypeEnum.REWARD.getType());
formDO.setStatus(TpFormStatusEnum.PENDING.getStatus());
formDO.setPayStatus(TpPayStatusEnum.NO_NEED_PAY.getStatus());
}
fillRuleFields(formDO);
tpApplyFormDAO.insertOrUpdate(formDO);
// 第一次提交后添加审批记录
if (isInsert && !isDraft) {
tpAuditRecordDAO.addRecord(formDO.getId(), TpFormTypeEnum.REWARD.getType(), request.getApplyUserId(), request.getApplyUserName());
}
return true;
}
@Override
public TpRewardApplyDetailVO rewardDetail(Long applyId) {
TpApplyFormDO formDO = tpApplyFormDAO.getById(applyId);
if (Objects.nonNull(formDO)) {
TpRewardApplyDetailVO vo = BeanUtil.toBean(formDO, TpRewardApplyDetailVO.class);
dictService.fillDictField(vo);
StoreDO storeDO = storeDao.getByStoreId(vo.getStoreId());
if (Objects.nonNull(storeDO)) {
vo.setStoreNum(storeDO.getStoreNum());
vo.setStoreName(storeDO.getStoreName());
}
return vo;
}
return null;
}
@Override
public PageInfo<TpRewardApplyListVO> rewardPage(TpApplyQueryRequest request) {
PageHelper.startPage(request.getPageNum(), request.getPageSize());
List<TpApplyFormDO> list = tpApplyFormDAO.getEffectiveList(request);
PageInfo<TpApplyFormDO> page = new PageInfo<>(list);
PageInfo<TpRewardApplyListVO> newPage = BeanUtil.toPage(page, TpRewardApplyListVO.class);
fillListFields(newPage.getList());
return newPage;
}
@Override
@Transactional
public Boolean penaltyApplySubmit(TpApplyRequest request) {
TpApplyFormDO formDO = BeanUtil.toBean(request, TpApplyFormDO.class);
// 如果存在审批中的申请,则不允许再次提交
boolean isDraft = CommonConstants.INDEX_ONE.equals(request.getIsDraft());
if (!isDraft && tpApplyFormDAO.existsPendingApply(request.getStoreId(), request.getRuleId(), false)) {
throw new ServiceException(ErrorCodeEnum.TP_EXISTS_PENDING_APPLY);
}
boolean isInsert = Objects.isNull(request.getId());
fillRuleFields(formDO);
if (isInsert) {
formDO.setApplyNo(TpHelper.generateApplyNo(formDO.getType()));
formDO.setStatus(TpFormStatusEnum.PENDING.getStatus());
}
tpApplyFormDAO.insertOrUpdate(formDO);
// 第一次提交后添加审批记录
if (isInsert && !isDraft) {
tpAuditRecordDAO.addRecord(formDO.getId(), TpFormTypeEnum.PENALTY.getType(), request.getApplyUserId(), request.getApplyUserName());
}
return true;
}
@Override
public TpPenaltyApplyDetailVO penaltyDetail(Long applyId) {
TpApplyFormDO formDO = tpApplyFormDAO.getById(applyId);
if (Objects.nonNull(formDO)) {
TpPenaltyApplyDetailVO vo = BeanUtil.toBean(formDO, TpPenaltyApplyDetailVO.class);
dictService.fillDictField(vo);
StoreDO storeDO = storeDao.getByStoreId(vo.getStoreId());
if (Objects.nonNull(storeDO)) {
vo.setStoreNum(storeDO.getStoreNum());
vo.setStoreName(storeDO.getStoreName());
}
return vo;
}
return null;
}
@Override
public PageInfo<TpPenaltyApplyListVO> penaltyPage(TpApplyQueryRequest request) {
request.setIsPenalty(true);
PageHelper.startPage(request.getPageNum(), request.getPageSize());
List<TpApplyFormDO> list = tpApplyFormDAO.getEffectiveList(request);
PageInfo<TpApplyFormDO> page = new PageInfo<>(list);
PageInfo<TpPenaltyApplyListVO> newPage = BeanUtil.toPage(page, TpPenaltyApplyListVO.class);
fillListFields(newPage.getList());
return newPage;
}
@Override
@Transactional
public Boolean rewardAudit(TpApplyAuditRequest request) {
TpApplyFormDO formDO = tpApplyFormDAO.getById(request.getApplyId());
if (Objects.isNull(formDO)) {
throw new ServiceException(ErrorCodeEnum.TP_NOT_EXIST_APPLY_FORM);
}
if (!TpFormStatusEnum.PENDING.getStatus().equals(formDO.getStatus())) {
throw new ServiceException(ErrorCodeEnum.TP_APPLY_AUDIT_COMPLETED);
}
if (tpApplyFormDAO.existPassRewardForm(formDO.getStoreId(), formDO.getRuleId())) {
throw new ServiceException(ErrorCodeEnum.TP_MONTH_EXIST_APPLY);
}
Date now = new Date();
// 修改申请单审批数据
formDO.setStatus(CommonConstants.INDEX_ONE.equals(request.getAuditStatus()) ? TpFormStatusEnum.PASS.getStatus() : TpFormStatusEnum.REJECT.getStatus());
formDO.setApproveTime(now);
tpApplyFormDAO.updateSelective(formDO);
LoginUserInfo user = CurrentUserHolder.getUser();
// 处理审批记录
tpAuditRecordDAO.auditPendingRecordByApplyId(request.getApplyId(), request.getApplyType(), user.getUserId(), user.getName(), request.getAuditStatus(), request.getRemark(), now);
// 审批通过后门店积分变动
scoreChange(formDO);
return null;
}
@Override
public Boolean penaltyAudit(TpApplyAuditRequest request) {
return null;
}
/**
* 门店积分变动
*/
private void scoreChange(TpApplyFormDO formDO) {
if (TpFormStatusEnum.PASS.getStatus().equals(formDO.getStatus())) {
BigDecimal occurBeforeScore = storeDao.getStoreScore(formDO.getStoreId());
BigDecimal occurAfterScore = null;
String occurScore = "";
if (TpFormTypeEnum.REWARD.getType().equals(formDO.getType())) {
// 加分
if (CommonConstants.INDEX_ONE.equals(formDO.getIsFull())) {
occurAfterScore = BigDecimal.valueOf(12.0);
occurScore = "加满";
} else {
occurAfterScore = occurBeforeScore.add(formDO.getScore());
occurScore = "+" + formDO.getScore().toString();
}
} else if (TpFormTypeEnum.PENALTY.getType().equals(formDO.getType())) {
occurAfterScore = occurBeforeScore.subtract(formDO.getScore());
occurScore = "-" + formDO.getScore().toString();
}
// 修改门店积分
if (Objects.nonNull(occurAfterScore)) {
storeDao.updateStoreScore(formDO.getStoreId(), occurAfterScore);
}
StoreDO storeDO = storeDao.getEffectiveByStoreId(formDO.getStoreId());
if (Objects.isNull(storeDO)) {
throw new ServiceException(ErrorCodeEnum.STORE_NOT_FIND);
}
// 添加积分流水
tpScoreJournalDAO.insertSelective(new TpScoreJournalDO(storeDO, formDO, occurScore, occurBeforeScore, occurAfterScore));
}
}
/**
* 填充规则相关字段
*/
private void fillRuleFields(TpApplyFormDO formDO) {
TpRuleDO ruleDO = tpRuleDAO.getById(formDO.getRuleId());
if (Objects.isNull(ruleDO)) {
throw new ServiceException(ErrorCodeEnum.TP_NOT_EXIST_RULE);
}
formDO.setRuleNo(ruleDO.getRuleNo());
formDO.setProblemClassification(ruleDO.getProblemClassification());
formDO.setProjectCategory(ruleDO.getProjectCategory());
formDO.setProjectName(ruleDO.getProjectName());
formDO.setIsFull(ruleDO.getIsFull());
formDO.setScore(ruleDO.getScore());
formDO.setAmount(ruleDO.getAmount());
formDO.setAppealEndDate(LocalDate.now().plusDays(ruleDO.getAppealDeadline()));
if (CommonConstants.INDEX_ZERO.equals(ruleDO.getType())) {
// 如果是扣分规则,判断警告次数
int penaltyCount = tpApplyFormDAO.getPenaltyCount(formDO.getStoreId(), formDO.getRuleId());
formDO.setType(ruleDO.getWarningLimit().compareTo(penaltyCount) <= 0 ? TpFormTypeEnum.PENALTY.getType() : TpFormTypeEnum.WARNING.getType());
// 是否缴费
formDO.setPayStatus(Objects.nonNull(ruleDO.getAmount()) && BigDecimal.ZERO.compareTo(ruleDO.getAmount()) < 0 ? TpPayStatusEnum.UNPAID.getStatus() : TpPayStatusEnum.NO_NEED_PAY.getStatus());
}
}
/**
* 填充列表相关字段
*/
private void fillListFields(List<? extends TpApplyListBaseVO> list) {
if (CollectionUtils.isNotEmpty(list)) return;
dictService.fillDictField(list);
Set<String> storeIds = CollStreamUtil.toSet(list, TpApplyListBaseVO::getStoreId);
Set<String> approveUserIds = CollStreamUtil.toSet(list, TpApplyListBaseVO::getApproveUserId);
Map<String, StoreDO> storeMap = storeDao.getStoreMapByStoreIds(new ArrayList<>(storeIds));
Map<String, String> userNameMap = enterpriseUserDAO.getUserNameMap(new ArrayList<>(approveUserIds));
for (TpApplyListBaseVO vo : list) {
StoreDO storeDO = storeMap.get(vo.getStoreId());
if (Objects.nonNull(storeDO)) {
vo.setStoreName(storeDO.getStoreName());
vo.setStoreNum(storeDO.getStoreNum());
}
vo.setApproveUserName(userNameMap.get(vo.getApproveUserId()));
}
}
}

View File

@@ -37,7 +37,7 @@ public class TpRuleServiceImpl implements TpRuleService {
@Override @Override
public Boolean insertPenaltyRule(TpPenaltyRuleUpdateRequest request) { public Boolean insertPenaltyRule(TpPenaltyRuleUpdateRequest request) {
TpRuleDO tpRuleDO = BeanUtil.toBean(request, TpRuleDO.class); TpRuleDO tpRuleDO = BeanUtil.toBean(request, TpRuleDO.class);
tpRuleDO.setRuleCode(TpHelper.generatePenaltyRuleCode()); tpRuleDO.setRuleNo(TpHelper.generateRuleNo(false));
tpRuleDO.setType(0); tpRuleDO.setType(0);
return tpRuleDAO.insertSelective(tpRuleDO); return tpRuleDAO.insertSelective(tpRuleDO);
} }
@@ -72,7 +72,7 @@ public class TpRuleServiceImpl implements TpRuleService {
@Override @Override
public Boolean insertRewardRule(TpRewardRuleUpdateRequest request) { public Boolean insertRewardRule(TpRewardRuleUpdateRequest request) {
TpRuleDO tpRuleDO = BeanUtil.toBean(request, TpRuleDO.class); TpRuleDO tpRuleDO = BeanUtil.toBean(request, TpRuleDO.class);
tpRuleDO.setRuleCode(TpHelper.generateRewardRuleCode()); tpRuleDO.setRuleNo(TpHelper.generateRuleNo(true));
tpRuleDO.setType(1); tpRuleDO.setType(1);
return tpRuleDAO.insertSelective(tpRuleDO); return tpRuleDAO.insertSelective(tpRuleDO);
} }

View File

@@ -0,0 +1,68 @@
package com.cool.store.controller.webb;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.enums.tp.TpFormTypeEnum;
import com.cool.store.request.tp.TpApplyAuditRequest;
import com.cool.store.request.tp.TpApplyQueryRequest;
import com.cool.store.request.tp.TpApplyRequest;
import com.cool.store.response.ResponseResult;
import com.cool.store.service.tp.TpApplyService;
import com.cool.store.vo.tp.TpRewardApplyDetailVO;
import com.cool.store.vo.tp.TpRewardApplyListVO;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotNull;
/**
* <p>
* 十二分制-申请单 前端控制器
* </p>
*
* @author wangff
* @since 2025/11/6
*/
@Api(tags = "十二分制-奖惩规则")
@RestController
@RequestMapping("/pc/tp/apply")
@RequiredArgsConstructor
public class TpApplyController {
private final TpApplyService tpApplyService;
@ApiOperation("加分申请提交or保存")
@PostMapping("/rewardApplySubmit")
public ResponseResult<Boolean> rewardApplySubmit(@RequestBody @Validated TpApplyRequest request) {
LoginUserInfo user = CurrentUserHolder.getUser();
request.setSource(0);
request.setApplyUserId(user.getUserId());
request.setApplyUserName(user.getName());
return ResponseResult.success(tpApplyService.rewardApplySubmit(request));
}
@ApiOperation("加分申请单详情")
@GetMapping("/rewardDetail")
@ApiImplicitParam(name = "applyId", value = "加分申请单id", required = true, dataType = "Long", paramType = "query")
public ResponseResult<TpRewardApplyDetailVO> rewardDetail(@NotNull(message = "加分申请单id不能为空") Long applyId) {
return ResponseResult.success(tpApplyService.rewardDetail(applyId));
}
@ApiOperation("加分申请单分页查询")
@GetMapping("/rewardPage")
public ResponseResult<PageInfo<TpRewardApplyListVO> > rewardPage(TpApplyQueryRequest request) {
request.setType(TpFormTypeEnum.REWARD.getType());
return ResponseResult.success(tpApplyService.rewardPage(request));
}
@ApiOperation("加分申请审批")
@PostMapping("/rewardAudit")
public ResponseResult<Boolean> rewardAudit(@RequestBody @Validated TpApplyAuditRequest request) {
request.setApplyType(TpFormTypeEnum.REWARD.getType());
return ResponseResult.success(tpApplyService.rewardAudit(request));
}
}