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:
@@ -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 over,url:{}", url);
|
||||
return url;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充规则相关字段
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user