Merge #31 into master from cc_2021104_twelve_points

十二分

* cc_2021104_twelve_points: (34 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

Signed-off-by: 王非凡 <accounts_67eba0c5fee9c49c80c8e2b4@mail.teambition.com>
Reviewed-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/31
This commit is contained in:
王非凡
2026-01-23 06:48:53 +00:00
committed by 正新
parent 1b1684f373
commit 41ae24478d
39 changed files with 998 additions and 46 deletions

View File

@@ -331,9 +331,14 @@ public class RedisConstant {
* 每刻退款用户信息
*/
public static final String MK_USER_MAPPING = "zxjp_mk_user_mapping";
/**
* 建店资料总部订货收款账户信息
*/
public static final String BUILD_RECEIVE_BANK_INFO = "zxjp_build_receive_bank_info";
/**
* 十二分导入锁
*/
public static final String TP_PENALTY_APPLY_IMPORT_LOCK = "tp_penalty_apply_import_lock";
}

View File

@@ -368,6 +368,8 @@ public enum ErrorCodeEnum {
TP_PENALTY_APPLY_UNABLE_ACCEPT(1810009, "该处罚单无法认缴", null),
TP_PENALTY_APPLY_INEFFECTIVE(1810010, "该处罚单未生效无法完成缴费", null),
TP_PENALTY_APPLY_NO_NEED_PAY(1810011, "该处罚单无需缴费", null),
TP_EXIST_PENDING_IMPORT_TASK(1810012, "存在导入中的任务,请稍后再试", null),
TP_NOT_EXIST_FORM_TYPE(1810013, "不存在该表单类型", null),
CITY_PLANNING_EXISTS(1820001, "同年份同季度同省市已存在规划,不能重复添加", null),
;

View File

@@ -27,6 +27,8 @@ public enum FileTypeEnum {
IMPORT_FITMENT_SHOP_STAGE_DATA_ERROR_LIST("OaOldShopStageDataErrorList", "导入装修阶段完成数据错误列表 "),
SELLING_DETAILS_REPORT("sellingDetailsReport", "开店明细报表"),
PRE_FRY_QUALIFICATION_APPLY_EXPORT("preFryQualificationApplyExport", "预炸品资质申请导出"),
TP_PENALTY_IMPORT("tpPenaltyImport", "十二分惩处申请单导入"),
TP_PENALTY_ERROR_EXPORT("tpPenaltyErrorExport", "十二分惩处申请单导入错误列表"),
;
private String fileType;
private String desc;

View File

@@ -1,5 +1,7 @@
package com.cool.store.enums;
import java.util.Objects;
/**
* @Author: WangShuo
* @Date: 2025/01/08/下午5:51
@@ -55,6 +57,9 @@ public enum JoinModeEnum {
}
public static String getDescByCode(Integer code) {
if (Objects.isNull(code)) {
return null;
}
for (JoinModeEnum e : JoinModeEnum.values()) {
if (e.getCode() == code) {
return e.desc;

View File

@@ -14,6 +14,7 @@ import lombok.Getter;
@Getter
@AllArgsConstructor
public enum TpFormStatusEnum {
DRAFT("draft", "草稿"),
PENDING("pending", "审批中"),
PASS("pass", "审批通过"),

View File

@@ -131,6 +131,19 @@ public class StoreDao {
return score;
}
/**
* 根据门店id查询门店编码
* @param storeIds 门店id列表
* @return store_id -> score
*/
public Map<String, BigDecimal> getScoreByStoreIds(List<String> storeIds) {
if (CollectionUtils.isEmpty(storeIds)) {
return Collections.emptyMap();
}
List<Map<String, Object>> list = storeMapper.getScoreByStoreIds(storeIds);
return CollStreamUtil.toMap(list, v -> MapUtils.getString(v, "storeId"), v -> BigDecimal.valueOf(MapUtils.getDouble(v, "score")));
}
/**
* 根据门店id查询门店映射
* @param storeIds 门店id列表
@@ -211,4 +224,14 @@ public class StoreDao {
);
}
/**
* 根据区域id查询门店列表
* @param regionIds 区域id
* @param keyword 门店名称或门店编码
* @return 门店列表
*/
public List<StoreDO> getStoreByRegionIds(List<String> regionIds, String keyword) {
return storeMapper.getStoreByRegionIds(regionIds, keyword);
}
}

View File

@@ -134,7 +134,12 @@ public class TpApplyFormDAO {
* @return 申请单
*/
public TpApplyFormDO getAppealByPenaltyId(Long penaltyId) {
return tpApplyFormMapper.selectOne(TpApplyFormDO.builder().penaltyId(penaltyId).deleted(0).build());
Example example = new Example(TpApplyFormDO.class);
example.createCriteria()
.andEqualTo("penaltyId", penaltyId)
.andEqualTo("deleted", 0)
.andIn("status", Arrays.asList(TpFormStatusEnum.PENDING.getStatus(), TpFormStatusEnum.PASS.getStatus(), TpFormStatusEnum.EFFECTIVE.getStatus()));
return tpApplyFormMapper.selectOneByExample(example);
}
/**

View File

@@ -61,6 +61,13 @@ public class TpRuleDAO {
return tpRuleMapper.selectByPrimaryKey(id);
}
/**
* 根据规则编码查询启用的规则
*/
public TpRuleDO getEnableByCode(String ruleNo) {
return tpRuleMapper.selectOne(TpRuleDO.builder().ruleNo(ruleNo).status(1).deleted(0).build());
}
public List<TpRuleDO> getEffectiveList(TpRuleQueryRequest request) {
Example example = new Example(TpRuleDO.class);
Example.Criteria criteria = example.createCriteria();

View File

@@ -75,6 +75,13 @@ public interface StoreMapper {
*/
BigDecimal getStoreScore(@Param("storeId") String storeId);
/**
* 根据门店id查询门店编码
* @param storeIds 门店id列表
* @return store_id -> score
*/
List<Map<String, Object>> getScoreByStoreIds(@Param("storeIds") List<String> storeIds);
/**
* 更新门店积分
* @param storeId 门店id
@@ -131,4 +138,12 @@ public interface StoreMapper {
@Param("city") String city,
@Param("openStartTime") LocalDate openStartTime,
@Param("openEndTime") LocalDate openEndTime);
/**
* 根据区域id查询门店列表
* @param regionIds 区域id
* @param keyword 门店名称或门店编码
* @return 门店列表
*/
List<StoreDO> getStoreByRegionIds(@Param("regionIds") List<String> regionIds, @Param("keyword") String keyword);
}

View File

@@ -281,6 +281,14 @@
WHERE store_id = #{storeId}
</select>
<select id="getScoreByStoreIds" resultType="java.util.Map">
SELECT store_id storeId, score FROM store_extend_info_${enterpriseId}
WHERE store_id IN
<foreach item="storeId" collection="storeIds" separator="," open="(" close=")">
#{storeId}
</foreach>
</select>
<insert id="updateStoreScore">
INSERT INTO store_extend_info_${enterpriseId} (store_id, score) VALUES (#{storeId}, #{score})
ON DUPLICATE KEY UPDATE
@@ -355,4 +363,21 @@
AND open_time &lt;= #{openEndTime}
</if>
</select>
<select id="getStoreByRegionIds" resultMap="BaseResultMap">
SELECT * FROM store_${enterpriseId}
<where>
is_delete = 'effective' AND store_status != 'closed'
<if test="keyword != null and keyword != ''">
AND (store_name LIKE concat('%', #{keyword}, '%') OR store_num LIKE concat('%', #{keyword}, '%'))
</if>
<if test="regionIds != null and !regionIds.isEmpty()">
AND (
<foreach collection="regionIds" item="regionId" separator=" OR ">
region_path LIKE concat('%/', #{regionId}, '/%')
</foreach>
)
</if>
</where>
</select>
</mapper>

View File

@@ -45,8 +45,15 @@
penalty_id, applicant_name, phone, appeal_reason, appeal_detail_reason
</sql>
<sql id="Base_Column_List_A">
a.id,a.type,a.apply_no,a.store_id,a.rule_id,a.rule_no,a.problem_classification,a.project_category,
a.project_name,a.is_full,a.score,a.remark,a.amount,a.appeal_end_date,a.status,a.pay_status,a.is_draft,
a.source,a.apply_user_id,a.apply_user_name,a.approve_user_id,a.approve_time,a.create_time,a.update_time,
a.deleted,a.proof_urls,a.penalty_id,a.applicant_name,a.phone,a.appeal_reason,a.appeal_detail_reason
</sql>
<select id="getEffectiveList" parameterType="com.cool.store.request.tp.TpApplyQueryRequest" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
SELECT <include refid="Base_Column_List_A" />
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'
@@ -82,7 +89,7 @@
</if>
<if test="storeNameOrNum != null and storeNameOrNum != ''">
AND (b.store_name LIKE CONCAT('%', #{storeNameOrNum}, '%')
OR b.store_num LIKE CONCAT('%', #{storeNameOrNum}, '%')
OR b.store_num LIKE CONCAT('%', #{storeNameOrNum}, '%'))
</if>
<if test="appealReason != null and appealReason != ''">
AND a.appeal_reason LIKE CONCAT('%', #{appealReason}, '%')
@@ -93,6 +100,21 @@
<if test="overdue != null and overdue">
AND a.appeal_end_date &lt; CURRENT_DATE
</if>
<if test="startTime != null">
AND a.create_time >= #{startTime}
</if>
<if test="endTime != null">
AND a.create_time &lt;= #{endTime}
</if>
<if test="penaltyStatus != null and penaltyStatus == 1">
AND a.status = 'pass' AND (a.pay_status = 0 OR a.pay_status = 1)
</if>
<if test="penaltyStatus != null and penaltyStatus == 2">
AND (a.status = 'effective' AND (a.pay_status = 0 OR a.pay_status = 2) OR a.status = 'cancel')
</if>
<if test="storeId != null and storeId != ''">
AND a.store_id = #{storeId}
</if>
</where>
ORDER BY a.create_time DESC
</select>

View File

@@ -16,7 +16,7 @@ public class ImportOaOldShopDataErrorDTO {
@ExcelProperty(value = "门店编码", order = 1)
@ColumnWidth(30)
private String shopCode;
@ExcelProperty(value = "门店", order = 2)
@ExcelProperty(value = "惩处规则编码", order = 2)
@ColumnWidth(30)
private String shopName;
@ExcelProperty(value = "错误原因", order =3)

View File

@@ -0,0 +1,32 @@
package com.cool.store.dto.tp;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* <p>
* 惩处申请单导入错误DTO
* </p>
*
* @author wangff
* @since 2026/1/9
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TpPenaltyImportErrorDTO {
@ExcelProperty(value = "门店编码", order = 1)
@ColumnWidth(30)
private String storeNum;
@ExcelProperty(value = "惩处规则编码", order = 3)
@ColumnWidth(30)
private String ruleNo;
@ExcelProperty(value = "错误原因", order =3)
@ColumnWidth(40)
private String errorReason;
}

View File

@@ -0,0 +1,19 @@
package com.cool.store.request.store;
import com.cool.store.common.PageBasicInfo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* <p>
* 根据区域查询门店Request
* </p>
*
* @author wangff
* @since 2025/12/29
*/
@Data
public class StoreListRequest extends PageBasicInfo {
@ApiModelProperty("门店编码或门店名称")
private String keyword;
}

View File

@@ -1,7 +1,9 @@
package com.cool.store.request.tp;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
@@ -14,6 +16,8 @@ import javax.validation.constraints.NotNull;
* @since 2025/11/6
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TpApplyAuditRequest {
@ApiModelProperty("申请单id")
@NotNull(message = "申请单id不能为空")

View File

@@ -0,0 +1,21 @@
package com.cool.store.request.tp;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* <p>
* 十二分申请单idRequest
* </p>
*
* @author wangff
* @since 2026/1/8
*/
@Data
public class TpApplyIdRequest {
@ApiModelProperty("申请单id")
@NotNull(message = "申请单id不能为空")
private Long applyId;
}

View File

@@ -1,15 +1,12 @@
package com.cool.store.request.tp;
import com.cool.store.common.PageBasicInfo;
import com.cool.store.constants.CommonConstants;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
@@ -27,6 +24,9 @@ public class TpApplyQueryRequest extends PageBasicInfo {
@ApiModelProperty("门店名称或编码")
private String storeNameOrNum;
@ApiModelProperty("门店id")
private String storeId;
@ApiModelProperty("项目大类")
private String projectCategory;
@@ -56,4 +56,13 @@ public class TpApplyQueryRequest extends PageBasicInfo {
@ApiModelProperty(value = "是否已逾期", hidden = true)
private Boolean overdue;
@ApiModelProperty("开始时间")
private Date startTime;
@ApiModelProperty("结束时间")
private Date endTime;
@ApiModelProperty("惩处状态1惩处待处理 2惩处已处理")
private Integer penaltyStatus;
}

View File

@@ -0,0 +1,34 @@
package com.cool.store.request.tp;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* <p>
* 申请单批量审批Request
* </p>
*
* @author wangff
* @since 2026/1/20
*/
@Data
public class TpBatchAuditRequest {
@ApiModelProperty("申请单类型")
@NotNull(message = "申请单类型不能为空")
private Integer type;
@ApiModelProperty("审批状态 1通过 2拒绝")
@NotNull(message = "审批状态不能为空")
private Integer auditStatus;
@ApiModelProperty("申请单id列表")
@NotEmpty(message = "申请单id不能为空")
private List<Long> applyIds;
@ApiModelProperty("备注")
private String remark;
}

View File

@@ -0,0 +1,27 @@
package com.cool.store.request.tp;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* <p>
* 十二分规则启用Request
* </p>
*
* @author wangff
* @since 2025/12/25
*/
@Data
public class TpRuleEnableRequest {
@ApiModelProperty("规则id列表")
@NotEmpty(message = "规则id列表不能为空")
private List<Long> ruleIds;
@ApiModelProperty("是否启用0禁用 1启用")
@NotNull(message = "是否启用不能为空")
private Integer status;
}

View File

@@ -0,0 +1,40 @@
package com.cool.store.vo.store;
import com.cool.store.enums.StoreStatusEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* <p>
* 门店列表VO
* </p>
*
* @author wangff
* @since 2025/12/29
*/
@Data
public class StoreListVO {
@ApiModelProperty("门店ID")
private String storeId;
@ApiModelProperty("门店名称")
private String storeName;
@ApiModelProperty("门店编号")
private String storeNum;
@ApiModelProperty("门店状态")
private String storeStatus;
@ApiModelProperty("门店状态名称")
private String storeStatusName;
@ApiModelProperty("门店积分")
private BigDecimal score;
public String getStoreStatusName() {
return StoreStatusEnum.getName(this.storeStatus);
}
}

View File

@@ -1,6 +1,7 @@
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;
@@ -56,4 +57,14 @@ public class TpAppealFormDetailVO {
@ApiModelProperty("处罚单")
private TpPenaltyApplyDetailVO penaltyDetail;
@ApiModelProperty("状态")
private String status;
@ApiModelProperty("状态名称")
private String statusName;
public String getStatusName() {
return TpFormStatusEnum.getMsgByStatus(this.status);
}
}

View File

@@ -0,0 +1,37 @@
package com.cool.store.vo.tp;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* <p>
* 申请单批量审批结果VO
* </p>
*
* @author wangff
* @since 2026/1/20
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TpBatchAuditVO {
@ApiModelProperty("id")
private Long applyId;
@ApiModelProperty("申请单号")
private String applyNo;
@ApiModelProperty("审批结果1审批成功 2审批失败")
private Integer status;
@ApiModelProperty("失败原因")
private String failReason;
public TpBatchAuditVO(Long applyId, Integer status, String failReason) {
this.applyId = applyId;
this.status = status;
this.failReason = failReason;
}
}

View File

@@ -50,4 +50,10 @@ public class TpPenaltyRuleListVO {
@ApiModelProperty("启用状态0未启用 1启用")
private Integer status;
@ApiModelProperty("项目描述")
private String remark;
@ApiModelProperty("复议申请时效")
private Integer appealDeadline;
}

View File

@@ -85,7 +85,7 @@ public class TpScoreJournalVO {
return BrandTypeEnum.getDescByCode(this.joinBrand);
}
public String getJoinModelNam() {
public String getJoinModelName() {
return JoinModeEnum.getDescByCode(this.joinModel);
}

View File

@@ -0,0 +1,30 @@
package com.cool.store.vo.tp;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* <p>
* 门店积分VO
* </p>
*
* @author wangff
* @since 2026/1/9
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TpStoreScoreVO {
@ApiModelProperty("门店名称")
private String storeName;
@ApiModelProperty("门头照")
private String avatar;
@ApiModelProperty("积分")
private BigDecimal score;
}

View File

@@ -1,6 +1,7 @@
package com.cool.store.vo.tp.mini;
import com.cool.store.annotation.DictField;
import com.cool.store.enums.tp.TpFormStatusEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -35,4 +36,14 @@ public class MiniTpAppealVO {
@ApiModelProperty("证明材料")
private String proofUrls;
@ApiModelProperty("状态")
private String status;
@ApiModelProperty("状态名称")
private String statusName;
public String getStatusName() {
return TpFormStatusEnum.getMsgByStatus(this.status);
}
}

View File

@@ -66,6 +66,9 @@ public class MiniTpPenaltyApplyVO {
@ApiModelProperty("复议申请")
private MiniTpAppealVO appeal;
@ApiModelProperty("金额")
private BigDecimal amount;
public String getStatusName() {
return TpFormStatusEnum.getMsgByStatus(this.status);
}

View File

@@ -1,5 +1,6 @@
package com.cool.store.oss;
import cn.hutool.core.date.DateUtil;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
@@ -13,6 +14,7 @@ import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.io.InputStream;
import java.util.Date;
/**
* Created by gavin on 15/8/5.
@@ -33,6 +35,10 @@ public class OssClientService {
@Value("${oss.host}")
private String ossHost;
@Value("${cdn.url:null}")
private String cdnUrl;
@Value("${oss.file.dir:null}")
private String dir;
private OSSClient client = null;
@@ -146,6 +152,11 @@ public class OssClientService {
putObject(fileName, inputStream, contentLength, contentType);
}
public String putObjectWithoutPrefix(String fileName, InputStream inputStream, Long contentLength, String contentType) throws Exception {
String time = DateUtil.format(new Date(), "yyMM");
return putObject(dir + time + "/" + fileName, inputStream, contentLength, contentType);
}
/**
* 上传文件到阿里云OSS
*
@@ -167,7 +178,7 @@ public class OssClientService {
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName, inputStream, meta);
log.info("uploadBaseImage, send...");
PutObjectResult p = ossClient.putObject(putObjectRequest.withProgressListener(new PutObjectProgressListener()));
String url = "https://"+bucketName+"."+endpoint +"/"+ fileName;
String url = cdnUrl + fileName;
log.info("uploadBaseImage, send overurl:{}", url);
return url;

View File

@@ -0,0 +1,61 @@
package com.cool.store.request.tp;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* 扣分申请单导入行 DTO不含图片列
* 第1行为说明忽略
* 第2行为表头
* 从第3行开始为数据行
* A 门店编码
* B 惩处规则编码
* C 扣分分值
* D 罚款金额
* E 复议申请时效(天)
* F 备注
* G~L 证明图片1~6由监听器处理
*/
@Data
public class TpPenaltyImportRowDTO {
/**
* 门店编码
*/
@ExcelProperty(index = 0)
private String storeNum;
/**
* 惩处规则编码
*/
@ExcelProperty(index = 1)
private String ruleNo;
/**
* 扣分分值
*/
@ExcelProperty(index = 2)
private BigDecimal score;
/**
* 罚款金额
*/
@ExcelProperty(index = 3)
private BigDecimal amount;
/**
* 复议申请时效(天)
*/
@ExcelProperty(index = 4)
private Integer AppealDeadline;
/**
* 备注
*/
@ExcelProperty(index = 5)
private String remark;
}

View File

@@ -4,7 +4,9 @@ import com.cool.store.dto.StoreDTO;
import com.cool.store.dto.StoreNameDTO;
import com.cool.store.dto.store.AuthStoreUserDTO;
import com.cool.store.dto.store.StoreUserPositionDTO;
import com.cool.store.request.store.StoreListRequest;
import com.cool.store.response.MiniShopsResponse;
import com.cool.store.vo.store.StoreListVO;
import com.github.pagehelper.PageInfo;
import java.util.List;
@@ -42,4 +44,9 @@ public interface StoreService {
List<String> groupIdList,
List<String> regionIdList);
/**
* 获取当前用户权限区域下的门店列表
*/
PageInfo<StoreListVO> getAuthStoreList(StoreListRequest request);
}

View File

@@ -1,10 +1,10 @@
package com.cool.store.service.impl;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.dto.StoreNameDTO;
import com.cool.store.dao.store.StoreMasterSignerInfoDAO;
import com.cool.store.dto.store.AuthStoreUserDTO;
@@ -21,11 +21,14 @@ import com.cool.store.entity.store.StoreMasterSignerInfoDO;
import com.cool.store.enums.*;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.*;
import com.cool.store.request.store.StoreListRequest;
import com.cool.store.response.MiniShopsResponse;
import com.cool.store.service.StoreService;
import com.cool.store.service.UserAuthMappingService;
import com.cool.store.utils.BeanUtil;
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;
@@ -38,6 +41,7 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -281,6 +285,29 @@ public class StoreServiceImpl implements StoreService {
return authStoreUsers;
}
@Override
public PageInfo<StoreListVO> getAuthStoreList(StoreListRequest request) {
String userId = CurrentUserHolder.getUserId();
List<String> regionIds = null;
Boolean isAdmin = enterpriseUserRoleDao.checkIsAdmin(userId);
if (!isAdmin) {
List<UserAuthMappingDO> userAuthMappings = userAuthMappingService.listUserAuthMappingByUserId(userId);
if (CollectionUtils.isEmpty(userAuthMappings)) {
return new PageInfo<>(Collections.emptyList());
}
regionIds = CollStreamUtil.toList(userAuthMappings, UserAuthMappingDO::getMappingId);
}
PageHelper.startPage(request.getPageNum(), request.getPageSize());
List<StoreDO> storeList = storeDao.getStoreByRegionIds(regionIds, request.getKeyword());
List<String> storeIds = CollStreamUtil.toList(storeList, StoreDO::getStoreId);
Map<String, BigDecimal> scoreMap = storeDao.getScoreByStoreIds(storeIds);
PageInfo<StoreListVO> page = BeanUtil.toPage(new PageInfo<>(storeList), StoreListVO.class);
page.getList().forEach(v -> {
v.setScore(scoreMap.getOrDefault(v.getStoreId(), new BigDecimal(12)));
});
return page;
}
@Override

View File

@@ -9,6 +9,7 @@ import com.cool.store.vo.tp.mini.MiniTpPenaltyApplyVO;
import com.cool.store.vo.tp.mini.MiniTpRewardApplyVO;
import com.cool.store.vo.tp.mini.MiniTpRuleListVO;
import com.github.pagehelper.PageInfo;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@@ -162,9 +163,37 @@ public interface TpApplyService {
*/
Boolean completePayment(Long applyId);
/**
* 撤销复议申请
* @param applyId 复议申请id
* @return 是否成功
*/
Boolean withdrawAppeal(Long applyId);
/**
* 积分变动
* @param formDO 申请单DO
*/
void scoreChange(TpApplyFormDO formDO);
/**
* 惩处申请单Excel导入异步执行立即返回
*
* @param file Excel 文件
*/
Boolean penaltyImport(MultipartFile file);
/**
* 门店积分
* @param storeId 门店id
* @return 积分
*/
TpStoreScoreVO getStoreScore(String storeId);
/**
* 批量审批
* @param request 申请单批量审批Request
* @return 申请单批量审批结果VO列表
*/
List<TpBatchAuditVO> batchAudit(TpBatchAuditRequest request);
}

View File

@@ -1,28 +1,38 @@
package com.cool.store.service.tp.impl;
import cn.hutool.core.collection.CollStreamUtil;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.CommonConstants;
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.tp.*;
import com.cool.store.dto.ImportOaOldShopDataErrorDTO;
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.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.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.oss.OssClientService;
import com.cool.store.request.tp.*;
import com.cool.store.response.AuditInfoResponse;
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.CoolDateUtils;
import com.cool.store.utils.TpHelper;
import com.cool.store.request.tp.TpPenaltyImportRowDTO;
import com.cool.store.utils.*;
import com.cool.store.utils.easyExcel.EasyExcelUtil;
import com.cool.store.utils.poi.DateUtils;
import com.cool.store.vo.tp.*;
import com.cool.store.vo.tp.mini.*;
import com.github.pagehelper.PageHelper;
@@ -30,13 +40,24 @@ 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.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.excel.EasyExcel;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import static com.cool.store.utils.poi.DateUtils.SPECIAL_DATE_START_1;
/**
* <p>
@@ -58,6 +79,14 @@ public class TpApplyServiceImpl implements TpApplyService {
private final DictService dictService;
private final TpScoreJournalDAO tpScoreJournalDAO;
private final EnterpriseUserDAO enterpriseUserDAO;
private final RedisUtilPool redisUtilPool;
private final OssClientService ossClientService;
private final ImportTaskMapper importTaskMapper;
@Resource(name = "generalThreadPool")
private ThreadPoolTaskExecutor executor;
private final EasyExcelUtil easyExcelUtil;
@Value("${mybatis.configuration.variables.enterpriseId}")
private String eid;
@Override
@Transactional
@@ -81,6 +110,7 @@ public class TpApplyServiceImpl implements TpApplyService {
formDO.setType(TpFormTypeEnum.REWARD.getType());
formDO.setPayStatus(TpPayStatusEnum.NO_NEED_PAY.getStatus());
}
formDO.setStatus(isDraft ? TpFormStatusEnum.DRAFT.getStatus() : TpFormStatusEnum.PENDING.getStatus());
fillRuleFields(formDO);
tpApplyFormDAO.insertOrUpdate(formDO);
// 第一次提交后添加审批记录
@@ -126,6 +156,7 @@ public class TpApplyServiceImpl implements TpApplyService {
throw new ServiceException(ErrorCodeEnum.TP_EXISTS_PENDING_APPLY);
}
fillRuleFields(formDO);
formDO.setStatus(isDraft ? TpFormStatusEnum.DRAFT.getStatus() : TpFormStatusEnum.PENDING.getStatus());
formDO.setApplyNo(Objects.isNull(request.getId()) ? TpHelper.generateApplyNo(formDO.getType()) : null);
tpApplyFormDAO.insertOrUpdate(formDO);
// 第一次提交后添加审批记录
@@ -171,7 +202,7 @@ public class TpApplyServiceImpl implements TpApplyService {
if (!TpFormStatusEnum.PENDING.getStatus().equals(formDO.getStatus())) {
throw new ServiceException(ErrorCodeEnum.TP_APPLY_AUDIT_COMPLETED);
}
if (tpApplyFormDAO.existPassRewardForm(formDO.getStoreId(), formDO.getRuleId())) {
if (CommonConstants.INDEX_ONE.equals(request.getAuditStatus()) && tpApplyFormDAO.existPassRewardForm(formDO.getStoreId(), formDO.getRuleId())) {
throw new ServiceException(ErrorCodeEnum.TP_MONTH_EXIST_APPLY);
}
auditCommon(request, formDO);
@@ -220,6 +251,7 @@ public class TpApplyServiceImpl implements TpApplyService {
formDO.setRuleId(penaltyFormDO.getRuleId());
formDO.setType(TpFormTypeEnum.APPEAL.getType());
formDO.setStoreId(penaltyFormDO.getStoreId());
formDO.setStatus(isDraft ? TpFormStatusEnum.DRAFT.getStatus() : TpFormStatusEnum.PENDING.getStatus());
fillRuleFields(formDO);
tpApplyFormDAO.insertOrUpdate(formDO);
// 第一次提交后添加审批记录
@@ -307,7 +339,9 @@ public class TpApplyServiceImpl implements TpApplyService {
@Override
public MiniTpRewardApplyVO getMiniRewardApplyDetail(Long applyId) {
TpApplyFormDO formDO = tpApplyFormDAO.getEffectiveById(applyId);
return BeanUtil.toBean(formDO, MiniTpRewardApplyVO.class);
MiniTpRewardApplyVO vo = BeanUtil.toBean(formDO, MiniTpRewardApplyVO.class);
dictService.fillDictField(vo);
return vo;
}
@Override
@@ -315,7 +349,7 @@ public class TpApplyServiceImpl implements TpApplyService {
TpApplyFormDO formDO = tpApplyFormDAO.getEffectiveById(applyId);
if (Objects.nonNull(formDO)) {
MiniTpPenaltyApplyVO vo = BeanUtil.toBean(formDO, MiniTpPenaltyApplyVO.class);
TpApplyFormDO appealForm = tpApplyFormDAO.getAppealByPenaltyId(formDO.getPenaltyId());
TpApplyFormDO appealForm = tpApplyFormDAO.getAppealByPenaltyId(formDO.getId());
vo.setAppeal(BeanUtil.toBean(appealForm, MiniTpAppealVO.class));
dictService.fillDictField(vo);
return vo;
@@ -366,6 +400,19 @@ public class TpApplyServiceImpl implements TpApplyService {
return true;
}
@Override
public Boolean withdrawAppeal(Long applyId) {
TpApplyFormDO formDO = tpApplyFormDAO.getById(applyId);
if (Objects.isNull(formDO) || !TpFormTypeEnum.APPEAL.getType().equals(formDO.getType())) {
throw new ServiceException(ErrorCodeEnum.TP_NOT_EXIST_APPLY_FORM);
}
if (!TpFormStatusEnum.PENDING.getStatus().equals(formDO.getStatus()) && !TpFormStatusEnum.DRAFT.getStatus().equals(formDO.getStatus())) {
throw new ServiceException(ErrorCodeEnum.TP_APPLY_AUDIT_COMPLETED);
}
tpApplyFormDAO.deleteByIds(Collections.singletonList(applyId));
return true;
}
/**
* 审批通用方法
*/
@@ -374,6 +421,7 @@ public class TpApplyServiceImpl implements TpApplyService {
// 修改申请单审批数据
formDO.setStatus(CommonConstants.INDEX_ONE.equals(request.getAuditStatus()) ? TpFormStatusEnum.PASS.getStatus() : TpFormStatusEnum.REJECT.getStatus());
formDO.setApproveTime(now);
formDO.setApproveUserId(CurrentUserHolder.getUserId());
tpApplyFormDAO.updateSelective(formDO);
LoginUserInfo user = CurrentUserHolder.getUser();
// 处理审批记录
@@ -420,6 +468,13 @@ public class TpApplyServiceImpl implements TpApplyService {
}
// 修改门店积分
if (Objects.nonNull(occurAfterScore)) {
// 限制积分在0-12之间
if (occurAfterScore.compareTo(BigDecimal.valueOf(12)) > 0) {
occurAfterScore = BigDecimal.valueOf(12);
}
if (occurAfterScore.compareTo(BigDecimal.ZERO) < 0) {
occurAfterScore = BigDecimal.ZERO;
}
storeDao.updateStoreScore(formDO.getStoreId(), occurAfterScore);
StoreDO storeDO = storeDao.getEffectiveByStoreId(formDO.getStoreId());
if (Objects.isNull(storeDO)) {
@@ -431,6 +486,124 @@ public class TpApplyServiceImpl implements TpApplyService {
}
}
@Override
public TpStoreScoreVO getStoreScore(String storeId) {
StoreDO storeDO = storeDao.getEffectiveByStoreId(storeId);
BigDecimal score = storeDao.getStoreScore(storeId);
return new TpStoreScoreVO(storeDO.getStoreName(), storeDO.getAvatar(), score);
}
@Override
@Transactional
public List<TpBatchAuditVO> batchAudit(TpBatchAuditRequest request) {
List<TpBatchAuditVO> result = new ArrayList<>();
TpFormTypeEnum type = TpFormTypeEnum.getByType(request.getType());
if (Objects.isNull(type)) {
throw new ServiceException(ErrorCodeEnum.TP_NOT_EXIST_FORM_TYPE);
}
for (Long applyId : request.getApplyIds()) {
boolean f = false;
String failReason = null;
try {
switch (type) {
case REWARD:
f = rewardAudit(new TpApplyAuditRequest(applyId, request.getAuditStatus(), request.getRemark()));
break;
case PENALTY:
case WARNING:
f = penaltyAudit(new TpApplyAuditRequest(applyId, request.getAuditStatus(), request.getRemark()));
break;
case APPEAL:
f = appealAudit(new TpApplyAuditRequest(applyId, request.getAuditStatus(), request.getRemark()));
break;
}
if (!f) {
failReason = "未知错误,请联系管理员";
}
} catch (ServiceException e) {
failReason = e.getErrorMessage();
} catch (Exception e) {
failReason = "未知错误,请联系管理员";
log.error("申请单批量审批失败applyId:{}", applyId, e);
}
result.add(new TpBatchAuditVO(applyId, f ? 1 : 2, failReason));
}
List<Long> applyIds = CollStreamUtil.toList(result, TpBatchAuditVO::getApplyId);
List<TpApplyFormDO> forms = tpApplyFormDAO.getByIds(applyIds);
Map<Long, String> applyNoMap = CollStreamUtil.toMap(forms, TpApplyFormDO::getId, TpApplyFormDO::getApplyNo);
result.forEach(v -> v.setApplyNo(applyNoMap.get(v.getApplyId())));
return result;
}
/**
* 惩处申请单Excel导入异步执行立即返回
*/
@Override
public Boolean penaltyImport(MultipartFile file) {
final String lockKey = RedisConstant.TP_PENALTY_APPLY_IMPORT_LOCK;
boolean lock = redisUtilPool.setNxExpire(lockKey, UUIDUtils.get32UUID(), 30 * 60 * 1000);
if (!lock) {
throw new ServiceException(ErrorCodeEnum.TP_EXIST_PENDING_IMPORT_TASK);
}
ImportTaskDO importTaskDO = new ImportTaskDO();
importTaskDO.setFileName(file.getOriginalFilename());
importTaskDO.setFileType(FileTypeEnum.TP_PENALTY_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(() -> importPenalty(excelBytes, importTaskDO, user));
} catch (Exception e) {
log.error("导入失败");
}
return true;
}
private void importPenalty(byte[] excelBytes, ImportTaskDO importTaskDO, LoginUserInfo user) {
List<TpPenaltyImportErrorDTO> errorList = new ArrayList<>();
AtomicInteger successNum = new AtomicInteger();
AtomicInteger totalNum = new AtomicInteger();
try {
EasyExcel.read(new ByteArrayInputStream(excelBytes), TpPenaltyImportRowDTO.class,
new TpPenaltyImportListener(this, tpRuleDAO, storeDao, ossClientService, errorList, user, excelBytes, totalNum, successNum))
.sheet(0)
.headRowNumber(2)
.doRead();
} catch (Exception e) {
log.error("惩处申请单导入失败", e);
} finally {
try {
final String lockKey = RedisConstant.TP_PENALTY_APPLY_IMPORT_LOCK;
String value = redisUtilPool.getString(lockKey);
if (StringUtils.isNotBlank(value)) {
redisUtilPool.delKey(lockKey);
}
} catch (Exception ex) {
log.error("释放惩处申请导入锁异常", ex);
}
}
importTaskDO.setStatus(totalNum.get() == successNum.get() ? ImportTaskStatusEnum.SUCCESS.getCode() : ImportTaskStatusEnum.ERROR.getCode());
importTaskDO.setTotalNum(totalNum.get());
importTaskDO.setSuccessNum(successNum.get());
if (CollectionUtils.isNotEmpty(errorList)) {
try {
String url = easyExcelUtil.exportExcel(ImportOaOldShopDataErrorDTO.class, errorList, null,
FileTypeEnum.TP_PENALTY_ERROR_EXPORT.getDesc() + DateUtils.parseDateToStr(SPECIAL_DATE_START_1, new Date()),
FileTypeEnum.TP_PENALTY_ERROR_EXPORT.getDesc() + DateUtils.parseDateToStr(SPECIAL_DATE_START_1, new Date()));
importTaskDO.setFileUrl(url);
} catch (Exception e) {
log.info("导出失败列表失败 errorList:{}", JSONObject.toJSONString(errorList));
}
}
importTaskMapper.update(eid, importTaskDO);
}
/**
* 填充规则相关字段
*/

View File

@@ -0,0 +1,208 @@
package com.cool.store.service.tp.impl;
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.context.LoginUserInfo;
import com.cool.store.dao.StoreDao;
import com.cool.store.dao.tp.TpRuleDAO;
import com.cool.store.dto.tp.TpPenaltyImportErrorDTO;
import com.cool.store.entity.StoreDO;
import com.cool.store.entity.tp.TpRuleDO;
import com.cool.store.exception.ServiceException;
import com.cool.store.oss.OssClientService;
import com.cool.store.request.tp.TpApplyRequest;
import com.cool.store.request.tp.TpPenaltyImportRowDTO;
import com.cool.store.service.tp.TpApplyService;
import com.cool.store.utils.CoolDateUtils;
import com.cool.store.utils.UUIDUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.xssf.usermodel.*;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* 扣分申请单导入监听器
*/
@RequiredArgsConstructor
@Slf4j
public class TpPenaltyImportListener implements ReadListener<TpPenaltyImportRowDTO> {
/**
* 证明图片起始列索引从0开始G列=6
*/
private static final int IMAGE_COL_START_INDEX = 6;
/**
* 证明图片结束列索引L列=11
*/
private static final int IMAGE_COL_END_INDEX = 11;
/**
* 每行最多图片数量
*/
private static final int MAX_IMAGE_PER_ROW = 6;
private final TpApplyService tpApplyService;
private final TpRuleDAO tpRuleDAO;
private final StoreDao storeDao;
private final OssClientService ossClientService;
private final List<TpPenaltyImportErrorDTO> errorList;
private final LoginUserInfo user;
private final byte[] excelBytes;
private final AtomicInteger totalNum;
private final AtomicInteger successNum;
private final Map<Integer, List<String>> pictureMap = new HashMap<>();
private volatile boolean pictureParsed = false;
@Override
public void onException(Exception e, AnalysisContext analysisContext) {
log.error("导入失败", e);
}
@Override
public void invokeHead(Map<Integer, CellData> map, AnalysisContext analysisContext) {
// head会回调多次图片解析只做一次
if (pictureParsed) {
return;
}
try {
XSSFWorkbook book = new XSSFWorkbook(new ByteArrayInputStream(excelBytes));
XSSFSheet sheet = book.getSheetAt(0);
if (Objects.isNull(sheet)) {
log.error("读取失败");
}
// 获取所有图片
XSSFDrawing drawingPatriarch = sheet.getDrawingPatriarch();
if (Objects.isNull(drawingPatriarch)) {
throw new RuntimeException("excel表格中没有图片请补充");
}
List<XSSFShape> shapes = drawingPatriarch.getShapes();
if (CollectionUtils.isEmpty(shapes)) {
log.info("表格中没有图片");
}
List<XSSFPicture> pictures = shapes.stream()
.filter(shape -> shape instanceof XSSFPicture)
.map(shape -> (XSSFPicture) shape)
.collect(Collectors.toList());
if (pictures.isEmpty()) {
return;
}
// 查找指定单元格中的图片
String fileNamePrefix = UUIDUtils.get32UUID();
for (XSSFPicture picture : pictures) {
ClientAnchor anchor = picture.getPreferredSize();
int row = anchor.getRow1();
int col = anchor.getCol1();
// 检查图片是否在指定单元格中
if (IMAGE_COL_START_INDEX <= col && col <= IMAGE_COL_END_INDEX) {
XSSFPictureData pictureData = picture.getPictureData();
byte[] data = pictureData.getData();
// 获取图片后缀
String fileName = fileNamePrefix + "-" + (row + 1) + "-" + (col + 1) + ".jpg";
try (InputStream in = new ByteArrayInputStream(data)) {
String url = ossClientService.putObjectWithoutPrefix(fileName, in, (long) data.length, "image/jpeg");
pictureMap.compute(row, (key, value) -> {
if (value == null) {
value = new ArrayList<>();
}
value.add(url);
return value;
});
} catch (Exception e) {
log.error("第{}行图片上传失败", row + 1, e);
}
}
}
pictureParsed = true;
} catch (Exception e) {
log.error("图片解析失败", e);
}
}
@Override
public void invoke(TpPenaltyImportRowDTO data, AnalysisContext context) {
totalNum.incrementAndGet();
int rowIndex = context.readRowHolder().getRowIndex();
// 基础必填校验
if (data == null) {
return;
}
if (data.getStoreNum() == null || data.getStoreNum().trim().isEmpty()) {
errorList.add(new TpPenaltyImportErrorDTO(data.getStoreNum(), data.getRuleNo(), "门店编码为空"));
return;
}
if (data.getRuleNo() == null || data.getRuleNo().trim().isEmpty()) {
errorList.add(new TpPenaltyImportErrorDTO(data.getStoreNum(), data.getRuleNo(), "行惩处规则编码为空"));
return;
}
// 根据门店编码查询门店
StoreDO store = storeDao.getByStoreNum(data.getStoreNum());
if (store == null) {
errorList.add(new TpPenaltyImportErrorDTO(data.getStoreNum(), data.getRuleNo(), "门店编码不存在"));
return;
}
// 根据规则编码查询规则
TpRuleDO rule = tpRuleDAO.getEnableByCode(data.getRuleNo());
if (rule == null) {
errorList.add(new TpPenaltyImportErrorDTO(data.getStoreNum(), data.getRuleNo(), "惩处规则编码不存在"));
return;
}
TpApplyRequest request = new TpApplyRequest();
request.setStoreId(store.getStoreId());
request.setRuleId(rule.getId());
request.setRemark(data.getRemark());
request.setIsDraft(0);
request.setSource(0);
request.setApplyUserId(user.getUserId());
request.setApplyUserName(user.getName());
List<String> proofUrls = pictureMap.getOrDefault(rowIndex, Collections.emptyList());
request.setProofUrls(String.join(",", proofUrls.subList(0, Math.min(proofUrls.size(), MAX_IMAGE_PER_ROW))));
request.setScore(data.getScore());
request.setAmount(data.getAmount());
if (Objects.nonNull(data.getAppealDeadline())) {
request.setAppealEndDate(CoolDateUtils.localDate2Date(LocalDate.now().plusDays(data.getAppealDeadline())));
}
try {
tpApplyService.penaltyApplySubmit(request);
successNum.incrementAndGet();
} catch (ServiceException e) {
errorList.add(new TpPenaltyImportErrorDTO(data.getStoreNum(), data.getRuleNo(), e.getErrorMessage()));
} catch (Exception e) {
log.error("申请单创建失败", e);
errorList.add(new TpPenaltyImportErrorDTO(data.getStoreNum(), data.getRuleNo(), "数据异常"));
}
}
@Override
public void extra(CellExtra cellExtra, AnalysisContext analysisContext) {
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// ignore
}
@Override
public boolean hasNext(AnalysisContext analysisContext) {
return true;
}
}

View File

@@ -2,14 +2,17 @@ package com.cool.store.controller.webb;
import com.cool.store.common.PageBasicInfo;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.request.store.StoreListRequest;
import com.cool.store.request.UserStoreRequest;
import com.cool.store.response.MiniShopsResponse;
import com.cool.store.response.ResponseResult;
import com.cool.store.service.StoreService;
import com.cool.store.vo.store.StoreListVO;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
@@ -32,4 +35,11 @@ public class PCStoreController {
public ResponseResult<PageInfo<MiniShopsResponse>> getCurrentUserStoreList(@RequestBody UserStoreRequest request) {
return ResponseResult.success(storeService.getStoreListByMobile(CurrentUserHolder.getUser().getMobile(), request.getPageNum(), request.getPageSize(), request.getKeyword(), null));
}
@ApiOperation("当前用户管辖下的门店列表")
@PostMapping("/storeList")
public ResponseResult<PageInfo<StoreListVO>> getStoreList(@RequestBody @Validated StoreListRequest request) {
return ResponseResult.success(storeService.getAuthStoreList(request));
}
}

View File

@@ -3,10 +3,7 @@ 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.TpAppealApplyRequest;
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.request.tp.*;
import com.cool.store.response.AuditInfoResponse;
import com.cool.store.response.ResponseResult;
import com.cool.store.service.tp.TpApplyService;
@@ -18,6 +15,7 @@ import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.NotNull;
import java.util.List;
@@ -86,7 +84,7 @@ public class TpApplyController {
@ApiOperation("惩处申请单分页查询")
@PostMapping("/penaltyPage")
public ResponseResult<PageInfo<TpPenaltyApplyListVO> > penaltyPage(@RequestBody TpApplyQueryRequest request) {
public ResponseResult<PageInfo<TpPenaltyApplyListVO>> penaltyPage(@RequestBody TpApplyQueryRequest request) {
request.setIsPenalty(true);
return ResponseResult.success(tpApplyService.penaltyPage(request));
}
@@ -146,4 +144,16 @@ public class TpApplyController {
public ResponseResult<Boolean> completePayment(@NotNull(message = "申请单id不能为空") Long applyId) {
return ResponseResult.success(tpApplyService.completePayment(applyId));
}
@ApiOperation("惩处申请单Excel导入")
@PostMapping("/penaltyImport")
public ResponseResult<Boolean> penaltyImport(MultipartFile file) {
return ResponseResult.success(tpApplyService.penaltyImport(file));
}
@ApiOperation("批量审批")
@PostMapping("/batchAudit")
public ResponseResult<List<TpBatchAuditVO>> batchAudit(@RequestBody @Validated TpBatchAuditRequest request) {
return ResponseResult.success(tpApplyService.batchAudit(request));
}
}

View File

@@ -4,6 +4,7 @@ import com.cool.store.common.InsertGroup;
import com.cool.store.common.UpdateGroup;
import com.cool.store.request.tp.TpPenaltyRuleUpdateRequest;
import com.cool.store.request.tp.TpRewardRuleUpdateRequest;
import com.cool.store.request.tp.TpRuleEnableRequest;
import com.cool.store.request.tp.TpRuleQueryRequest;
import com.cool.store.response.ResponseResult;
import com.cool.store.service.tp.TpRuleService;
@@ -96,13 +97,7 @@ public class TpRuleController {
@ApiOperation("启用规则")
@PostMapping("/enable")
public ResponseResult<Boolean> enableRuleByIds(@RequestBody List<Long> ruleIds) {
return ResponseResult.success(tpRuleService.enableRuleByIds(ruleIds, 1));
}
@ApiOperation("禁用规则")
@PostMapping("/disable")
public ResponseResult<Boolean> disableRuleByIds(@RequestBody List<Long> ruleIds) {
return ResponseResult.success(tpRuleService.enableRuleByIds(ruleIds, 0));
public ResponseResult<Boolean> enableRuleByIds(@RequestBody @Validated TpRuleEnableRequest request) {
return ResponseResult.success(tpRuleService.enableRuleByIds(request.getRuleIds(), request.getStatus()));
}
}

View File

@@ -2,14 +2,12 @@ package com.cool.store.controller.webc;
import com.cool.store.context.PartnerUserHolder;
import com.cool.store.enums.tp.TpFormTypeEnum;
import com.cool.store.request.tp.TpAppealApplyRequest;
import com.cool.store.request.tp.TpApplyQueryRequest;
import com.cool.store.request.tp.TpApplyRequest;
import com.cool.store.request.tp.TpRuleQueryRequest;
import com.cool.store.request.tp.*;
import com.cool.store.response.AuditInfoResponse;
import com.cool.store.response.ResponseResult;
import com.cool.store.service.tp.TpApplyService;
import com.cool.store.vo.PartnerUserInfoVO;
import com.cool.store.vo.tp.TpStoreScoreVO;
import com.cool.store.vo.tp.mini.MiniTpApplyListVO;
import com.cool.store.vo.tp.mini.MiniTpPenaltyApplyVO;
import com.cool.store.vo.tp.mini.MiniTpRewardApplyVO;
@@ -17,12 +15,15 @@ import com.cool.store.vo.tp.mini.MiniTpRuleListVO;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
/**
@@ -37,6 +38,7 @@ import java.util.List;
@RestController
@RequestMapping("/mini/tp/apply")
@RequiredArgsConstructor
@Validated
public class MiniTpApplyController {
private final TpApplyService tpApplyService;
@@ -97,19 +99,28 @@ public class MiniTpApplyController {
}
@ApiOperation("规则分页查询")
@GetMapping("/rulePage")
@ApiImplicitParam(name = "type", value = "规则类型0惩处 1加分", required = true, dataType = "Integer", paramType = "query")
public ResponseResult<PageInfo<MiniTpRuleListVO>> rewardRulePage(@NotNull(message = "规则类型不能为空") Integer type) {
TpRuleQueryRequest request = new TpRuleQueryRequest();
request.setType(type);
@PostMapping("/rulePage")
public ResponseResult<PageInfo<MiniTpRuleListVO>> rewardRulePage(@RequestBody TpRuleQueryRequest request) {
request.setStatus(1);
return ResponseResult.success(tpApplyService.getMiniRulePage(request));
}
@ApiOperation("认罚缴款")
@PostMapping("/acceptPenalty")
@ApiImplicitParam(name = "applyId", value = "惩处申请单id", required = true, dataType = "Long", paramType = "query")
public ResponseResult<Boolean> acceptPenalty(@NotNull(message = "惩处申请单id不能为空") Long applyId) {
return ResponseResult.success(tpApplyService.acceptPenalty(applyId));
public ResponseResult<Boolean> acceptPenalty(@RequestBody @Validated TpApplyIdRequest request) {
return ResponseResult.success(tpApplyService.acceptPenalty(request.getApplyId()));
}
@ApiOperation("撤销复议申请")
@PostMapping("/withdrawAppeal")
public ResponseResult<Boolean> withdrawAppeal(@RequestBody @Validated TpApplyIdRequest request) {
return ResponseResult.success(tpApplyService.withdrawAppeal(request.getApplyId()));
}
@ApiOperation("门店积分")
@GetMapping("/storeScore")
@ApiImplicitParam(name = "storeId", value = "门店id", required = true, dataType = "String", paramType = "query")
public ResponseResult<TpStoreScoreVO> storeScore(@NotBlank(message = "门店id不能为空") String storeId) {
return ResponseResult.success(tpApplyService.getStoreScore(storeId));
}
}

View File

@@ -46,14 +46,14 @@ rocketmq.orderTopic=zx_order_message
oss.excelFile.dir=lineExcel/
oss.accessKeyId=LTAI5tGBwmXwZkMuHK4MudMJ
oss.accessKeySecret=bnZoUMRQ9834STgz5E291YrqlBu6yn
oss.bucket=store-ossfile
oss.bucket=store-ossfile-zx
oss.file.dir=eid/${mybatis.configuration.variables.enterpriseId}/
oss.endpoint=oss-cn-hangzhou.aliyuncs.com
oss.host=https://oss-cool.coolstore.cn/
#cdn地址
cdn.url=https://oss-cool.coolstore.cn
cdn.url=https://ossfilezx.coolstore.cn/
#TRTC
trtc.sdkAppId=1600026212
@@ -150,4 +150,18 @@ wallet.url=https://api.dev.wenmatech.com:443
wallet.api.yzt.key=360155690205317
cool.api.rsa.private.key=MIIEpQIBAAKCAQEA0erPAWesjkp9J4htmfCyqKS9npmT9dW3KqWTfb4c7x/QBUtKuokWOO0XikHd4bGUa9kl+twSv/5A3kYz1B9eg6wRuDJoads+G5U7rVQjzdoUtLaf3lNXkuSehl4uHUPQfNa6vcmvzraXPxJjEpYzj9WZh7uJqq2oSgw42H1qdbFCXSaE5BwsOb+2vZXjzh4RO10Sy3Qb1UqGsoZoxVzrtDeEctCjrecFyQr96L2UtYa4NTxSTfu4rgObrwIOMvqqnLsXEzK/rd6kIHYjkZYQCOa48AedWp2YKQ7Ldclj+VMLnXvl42J9exVkbs++8k3P5sI9fdZX4Ey2RBjnSoAo/QIDAQABAoIBACbBGi8I+CE77M+13wAu4RkD8xL7CQc3ic2ojGqIRPi7r5CuphD6mpzvXqtyfhd7DKr9h8bAxwBlnQ28ObjVgsI96/aM7dxvMs/uVPpqwIJyWuTDG5A05EPVC9REQnC6Mp09mnPL7rZz3Mfy6dIGY2YQWfwmWiPl1B45k+wZ+WPZPI0JVnvRzM881kf4aAhEAt08i9VoihylwVAjWIPmLuhf6ZcqI5q8iUsjfO22wZJsudVTCA/dsJdNxv+1RDKeYnSLJL79cZQcodqEhFqTy6vnn2dMsaHH7dpphU27barxUjeL482SR7kFfMqEXn5sltRn/3ep+3sf4Ph2vMtoZeECgYEA6gXzEtT9ZOeAMp4BRGmfNZ0TQLprPPVSwudz/uUBE4j/vyhfXkh9p7hqwyoxN+Z8b65yINvx8yP6hge6ek/MyAwBCZyfIRxZAPZu1eEGoYKl391ubFt2EIVqrN2DtAvzHMr5B/E2VHBq6AJm/rERFX5oKsg6zHS9tPLhgGnWVd0CgYEA5aFWOrtiqZJlp1MHQ4OeWBJatBSynkORdxCW7ic0CKbkYus0NSz1SsvskpbnfEXNB53x98qJxRhSopg/DC4m7XqxjSf9lY3HH4Y/9907olj33yGAnLWC88GivVndt577u/XhYRCk33vOQ3GoibEdjnpMOkWmOfwYG/FsRWWQvaECgYEA1N2siEisZIgel+wZAv2AD+hchtgKi1wqd5bIb+Yl4HsRBfPXK4+MnG6mzfcm5c4FCiEHNtRZc+waCKgm+vJzNtOUbgXEyP1cCAAgOPOCcI7CCqsDshRPhB+XNL4Y+kCUVnBZrNu/q3bGB1uIC8tL2t0sKx4OPcNCe8EhVQjwKRECgYEA4uothdhKRPtwDIsVsHfN74Yjr7SMVay7gIcaPrjqyGnzYnS+oJWOx50AaFNK6Rko5JAF3jF9NxE0B4yfMPAic6Y88hpEkpcJ4HMPn2Y1WdbFCu/WYgVUJICCys6VNLCcXj85umtyIY38Y9VbEMW/SV49GZBeFQqy4FoP/fvBrkECgYEAnfjTDYwgdmJdsUqyNzAocwcJXG2rVtYc7Txrl0TltcwuJmgoSywdzyOP2R9+NZsfoxWDzG0/yr15ApMvUcnnTwHN/8bGQ9SLatFLKqS4EtdwDKKS1JvNbs7V1myQGpt7jbShZOI0e6Fs4xP8ujxsLeGgiq9mZrS9UdRj5XKDoVM=
cool.api.rsa.public.key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0erPAWesjkp9J4htmfCyqKS9npmT9dW3KqWTfb4c7x/QBUtKuokWOO0XikHd4bGUa9kl+twSv/5A3kYz1B9eg6wRuDJoads+G5U7rVQjzdoUtLaf3lNXkuSehl4uHUPQfNa6vcmvzraXPxJjEpYzj9WZh7uJqq2oSgw42H1qdbFCXSaE5BwsOb+2vZXjzh4RO10Sy3Qb1UqGsoZoxVzrtDeEctCjrecFyQr96L2UtYa4NTxSTfu4rgObrwIOMvqqnLsXEzK/rd6kIHYjkZYQCOa48AedWp2YKQ7Ldclj+VMLnXvl42J9exVkbs++8k3P5sI9fdZX4Ey2RBjnSoAo/QIDAQAB
wallet.api.rsa.public.key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvU5WUX5MaZhS4MRfZ5OeqmSxTgjNi64SEwTiDYS++DRHRFTEguk1g5AbiW3l9eEdATeVk0WX+T6ZIIa2do3bQOKhlMtRwWMWQIucjGa7ySOCuicvnCD2HAQ2EThfqQdSpAW5UpcyodrhcyUkuevBA4fQQ06k9lB4FjqWtao2+aYFIPFPu8Wu28KI/9QIMLI02Q1YY3duJ67QW4EM4I2oS0t3sWJeZtIJPRHFWW1EaLJz2FdbJJq+z6D2p++9pmkHsvdnktUUO+nPL3PCLtxGYxEwr/AqTYR/1yXfkVWe3nHXc+qvRt967X1hDHC+gEPJItr7kUk3pQTGBv9kNu75DwIDAQAB
wallet.api.rsa.public.key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvU5WUX5MaZhS4MRfZ5OeqmSxTgjNi64SEwTiDYS++DRHRFTEguk1g5AbiW3l9eEdATeVk0WX+T6ZIIa2do3bQOKhlMtRwWMWQIucjGa7ySOCuicvnCD2HAQ2EThfqQdSpAW5UpcyodrhcyUkuevBA4fQQ06k9lB4FjqWtao2+aYFIPFPu8Wu28KI/9QIMLI02Q1YY3duJ67QW4EM4I2oS0t3sWJeZtIJPRHFWW1EaLJz2FdbJJq+z6D2p++9pmkHsvdnktUUO+nPL3PCLtxGYxEwr/AqTYR/1yXfkVWe3nHXc+qvRt967X1hDHC+gEPJItr7kUk3pQTGBv9kNu75DwIDAQAB
huoMa.token.url = https://www.huoMayunping.com/api/SAASLogin/merchant
huoMa.id.url = https://www.huomayunping.com/api/reportCenter/executeSql
huoMa.store.device.detail.url = https://www.huomayunping.com/api/terminal/search
huoMa.get.point.terminal.url = https://www.huoMayunping.com/api/terminal/getPointTerminalInfos
huoMa.get.tag.url = https://www.huomayunping.com/api/tag/search
huoMa.get.program.url = https://www.huomayunping.com/api/program/search
huoMa.get.publish.url = https://www.huomayunping.com/api/channelPublish/target/v2/quick-publish
huoMa.direct.stores.account = 18375320931
huoMa.direct.stores.password = Huoma@123456.
huoMa.franchise.stores.account = 13345565081
huoMa.franchise.stores.password = Huoma@123456.
huoMa.restaurant.stores.account = 15167817007
huoMa.restaurant.stores.password = Huoma@123456.