Commit 39ec82aa authored by zhaobiyan's avatar zhaobiyan

兑换信息导入

parents b7d23338 32b80572
......@@ -32,4 +32,5 @@ public interface DictDataFrameworkService {
*/
List<DictDataRespDTO> listDictDatasFromCache(String type);
DictDataRespDTO parseDictDataFromCacheWithMultiLang(String type, String multiLangLabel);
}
......@@ -25,4 +25,8 @@ public class DictFrameworkUtils {
return service.parseDictDataFromCache(type, label);
}
public static DictDataRespDTO parseDictDataFromCacheWithMultiLang(String type, String multiLangLabel) {
return service.parseDictDataFromCacheWithMultiLang(type, multiLangLabel);
}
}
......@@ -42,6 +42,21 @@ public class I18nMessage {
}
}
/**
* 获取一条语言配置信息
*
* @param message 配置信息属性名,eg: api.response.code.user.signUp
* @return
*/
public static String getMessage(String message, Object... arg) {
Locale locale = LocaleContextHolder.getLocale();
try {
return accessor.getMessage(message, arg, locale);
} catch (Exception e) {
return message;
}
}
/**
* 获取一条语言配置信息
* TODO 此方法暂时只支持中英文国际化,如需更多,待优化
......
......@@ -6,6 +6,7 @@ import java.math.BigDecimal;
@Data
public class CurrencyRespDTO {
private Integer id;
/**
* 中文名称
*/
......
package cn.iocoder.yudao.module.ecw.api.express;
import cn.iocoder.yudao.module.ecw.api.express.dto.ExpressRespDTO;
import java.util.List;
public interface ExpressApi {
List<ExpressRespDTO> getAllExpress();
}
package cn.iocoder.yudao.module.ecw.api.express.dto;
import lombok.Data;
@Data
public class ExpressRespDTO {
private Long id;
/**
* 快递公司名称
*/
private String companyName;
}
......@@ -4,6 +4,7 @@ import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.ecw.api.express.dto.ExpressRespDTO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import cn.iocoder.yudao.module.ecw.controller.admin.express.vo.*;
......@@ -31,4 +32,5 @@ public interface ExpressConvert {
List<ExpressExcelVO> convertList02(List<ExpressDO> list);
List<ExpressRespDTO> convert2DTO(List<ExpressDO> list);
}
package cn.iocoder.yudao.module.ecw.service.api;
import cn.iocoder.yudao.module.ecw.api.express.ExpressApi;
import cn.iocoder.yudao.module.ecw.api.express.dto.ExpressRespDTO;
import cn.iocoder.yudao.module.ecw.convert.express.ExpressConvert;
import cn.iocoder.yudao.module.ecw.dal.dataobject.express.ExpressDO;
import cn.iocoder.yudao.module.ecw.service.express.ExpressService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
@Component
public class ExpressApiImpl implements ExpressApi {
@Resource
private ExpressService expressService;
@Override
public List<ExpressRespDTO> getAllExpress() {
List<ExpressDO> list = expressService.list();
return ExpressConvert.INSTANCE.convert2DTO(list);
}
}
......@@ -67,4 +67,5 @@ public interface ExpressService {
*/
List<ExpressDO> getExpressList(ExpressExportReqVO exportReqVO);
List<ExpressDO> list();
}
package cn.iocoder.yudao.module.ecw.service.express;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
......@@ -79,4 +81,11 @@ public class ExpressServiceImpl implements ExpressService {
return expressMapper.selectList(exportReqVO);
}
@Override
public List<ExpressDO> list() {
LambdaQueryWrapper<ExpressDO> wrapper = Wrappers.lambdaQuery();
wrapper.eq(ExpressDO::getDeleted, 0);
return expressMapper.selectList(wrapper);
}
}
......@@ -48,7 +48,8 @@ public interface ErrorCodeConstants {
ErrorCode SCORE_RULE_NOT_EXISTS = new ErrorCode(1004008004, "score.rule.not.exists");
ErrorCode SCORE_RULE_DELETE_ERROR = new ErrorCode(1004008005, "score.rule.delete.error");
ErrorCode SCORE_RULE_UPDATE_ERROR = new ErrorCode(1004008005, "score.rule.update.error");
ErrorCode SCORE_RULE_UPDATE_ERROR = new ErrorCode(1004008006, "score.rule.update.error");
ErrorCode SCORE_RULE_FIELD_ERROR = new ErrorCode(1004008007, "score.rule.field.error");
}
package cn.iocoder.yudao.module.member.enums;
public enum RelationSymbolEnum {
GT(1, "大于"),
EQ(2, "等于"),
LT(3, "小于");
private final int value;
private final String name;
RelationSymbolEnum(int value, String name) {
this.value = value;
this.name = name;
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
}
\ No newline at end of file
package cn.iocoder.yudao.module.member.enums;
public enum TransportType {
OCEAN_LCL(1, "海运拼柜"),
SPECIAL_LINE_AIR_FREIGHT(3, "专线空运");
private final int value;
private final String name;
TransportType(int value, String name) {
this.value = value;
this.name = name;
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
}
......@@ -44,5 +44,10 @@
<version>${revision}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-depository-core</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</project>
......@@ -5,6 +5,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.util.ExcelUtils;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.depository.service.warehouse.WarehouseService;
import cn.iocoder.yudao.module.depository.vo.warehouse.WarehouseTreeRegionVO;
import cn.iocoder.yudao.module.member.convert.scoreRule.ScoreRuleConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.scoreRule.ScoreRuleDO;
import cn.iocoder.yudao.module.member.service.scoreRule.ScoreRuleService;
......@@ -12,6 +14,7 @@ import cn.iocoder.yudao.module.member.vo.scoreRule.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.ListUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
......@@ -36,6 +39,8 @@ public class ScoreRuleController {
@Resource
private ScoreRuleService scoreRuleService;
@Resource
private WarehouseService warehouseService;
@PostMapping("/create")
@ApiOperation("创建积分规则")
......@@ -54,19 +59,17 @@ public class ScoreRuleController {
@PostMapping("/delete")
@ApiOperation("删除积分规则")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('member:score-rule:delete')")
public CommonResult<Boolean> deleteScoreRule(@NotNull @RequestBody Long id) {
scoreRuleService.deleteScoreRule(id);
public CommonResult<Boolean> deleteScoreRule(@Valid @RequestBody IdReqVo idReqVo) {
scoreRuleService.deleteScoreRule(idReqVo.getId());
return success(true);
}
@PostMapping("/get")
@ApiOperation("获得积分规则详情")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('member:score-rule:query')")
public CommonResult<ScoreRuleBackDetailVO> getScoreRule(@NotNull @RequestBody Long id) {
ScoreRuleBackDetailVO scoreRuleBackDetailVO = scoreRuleService.getScoreRule(id);
public CommonResult<ScoreRuleBackDetailVO> getScoreRule(@Valid @RequestBody IdReqVo idReqVo) {
ScoreRuleBackDetailVO scoreRuleBackDetailVO = scoreRuleService.getScoreRule(idReqVo.getId());
return success(scoreRuleBackDetailVO);
}
......@@ -74,7 +77,7 @@ public class ScoreRuleController {
@ApiOperation("获得积分规则列表")
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('member:score-rule:query')")
public CommonResult<List<ScoreRuleBackVO>> getScoreRuleList(@NotNull @RequestBody Collection<Long> ids) {
public CommonResult<List<ScoreRuleBackVO>> getScoreRuleList(@NotNull @RequestParam Collection<Long> ids) {
List<ScoreRuleBackVO> list = scoreRuleService.getScoreRuleList(ids);
return success(list);
}
......@@ -90,24 +93,34 @@ public class ScoreRuleController {
@ApiOperation("启用关闭")
@PreAuthorize("@ss.hasPermission('member:score-rule:update')")
public CommonResult<Boolean> updateStatus(@Valid @RequestBody ScoreRuleStatusReqVO scoreRuleStatusReqVO) {
Boolean res = scoreRuleService.updateStatus(scoreRuleStatusReqVO);
return success(res);
scoreRuleService.updateStatus(scoreRuleStatusReqVO);
return success(true);
}
@PostMapping("/copy")
@ApiOperation("复制规则")
@PreAuthorize("@ss.hasPermission('member:score-rule:create')")
public CommonResult<Long> copyScoreRule(@NotNull @RequestBody Long id) {
Long newId = scoreRuleService.copyScoreRule(id);
return success(id);
public CommonResult<Long> copyScoreRule(@Valid @RequestBody IdReqVo idReqVo) {
return success(scoreRuleService.copyScoreRule(idReqVo.getId()));
}
@PostMapping("/delay")
@ApiOperation("延期规则")
@PreAuthorize("@ss.hasPermission('member:score-rule:update')")
public CommonResult<Boolean> delayScoreRule(@Valid @RequestBody ScoreDelayReqVO scoreDelayReqVO) {
Boolean res = scoreRuleService.delayScoreRule(scoreDelayReqVO);
return success(res);
scoreRuleService.delayScoreRule(scoreDelayReqVO);
return success(true);
}
@GetMapping("/getWarehouseTreeRegionList")
@ApiOperation("获得目的国、目的城市、目的仓列表")
public CommonResult<List<WarehouseTreeRegionVO>> WarehouseTreeRegionList() {
List<WarehouseTreeRegionVO> listIn = warehouseService.getWarehouseTreeRegionList(1);
List<WarehouseTreeRegionVO> listOut = warehouseService.getWarehouseTreeRegionList(2);
List<WarehouseTreeRegionVO> list = ListUtils.sum(listIn, listOut);
return success(list);
}
@GetMapping("/export-excel")
@ApiOperation("导出积分规则Excel")
@PreAuthorize("@ss.hasPermission('member:score-rule:export')")
......
......@@ -71,7 +71,7 @@ public class ScoreRuleDO extends BaseDO {
/**
* 积分有效期
*/
private Integer socrePeriod;
private Integer scorePeriod;
/**
* 排序值
*/
......
package cn.iocoder.yudao.module.member.dal.mysql.scoreRule;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQuery;
import cn.iocoder.yudao.framework.mybatis.core.mapper.AbstractMapper;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.member.dal.dataobject.scoreRule.ScoreRuleDO;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.module.member.enums.RelationSymbolEnum;
import cn.iocoder.yudao.module.member.vo.scoreRule.ScoreRuleQueryVO;
import org.apache.ibatis.annotations.Mapper;
/**
* 积分规则 DO Mapper
* 积分规则 Mapper
*
* @author 系统管理员
*/
@Mapper
......@@ -18,58 +22,51 @@ public interface ScoreRuleMapper extends AbstractMapper<ScoreRuleDO> {
@Override
default PageResult<ScoreRuleDO> selectPage(PageVO page, Object object) {
if (object instanceof ScoreRuleQueryVO) {
ScoreRuleQueryVO vo = (ScoreRuleQueryVO)object;
return selectPage(page, new LambdaQuery<ScoreRuleDO>()
.eqIfPresent(ScoreRuleDO::getType, vo.getType())
.eqIfPresent(ScoreRuleDO::getTitleZh, vo.getTitleZh())
.eqIfPresent(ScoreRuleDO::getTitleEn, vo.getTitleEn())
.eqIfPresent(ScoreRuleDO::getDescZh, vo.getDescZh())
.eqIfPresent(ScoreRuleDO::getDescEn, vo.getDescEn())
.eqIfPresent(ScoreRuleDO::getCoverImageZh, vo.getCoverImageZh())
.eqIfPresent(ScoreRuleDO::getCoverImageEn, vo.getCoverImageEn())
.eqIfPresent(ScoreRuleDO::getGetScoreOnce, vo.getGetScoreOnce())
.eqIfPresent(ScoreRuleDO::getMaxScoreTotal, vo.getMaxScoreTotal())
.betweenIfPresent(ScoreRuleDO::getStartTime, vo.getBeginStartTime(), vo.getEndStartTime())
.betweenIfPresent(ScoreRuleDO::getEndTime, vo.getBeginEndTime(), vo.getEndEndTime())
.eqIfPresent(ScoreRuleDO::getSocrePeriod, vo.getSocrePeriod())
.eqIfPresent(ScoreRuleDO::getOrderNum, vo.getOrderNum())
.eqIfPresent(ScoreRuleDO::getPushActivity, vo.getPushActivity())
.eqIfPresent(ScoreRuleDO::getShowPlatform, vo.getShowPlatform())
.eqIfPresent(ScoreRuleDO::getStatus, vo.getStatus())
.eqIfPresent(ScoreRuleDO::getExtra, vo.getExtra())
.betweenIfPresent(ScoreRuleDO::getCreateTime, vo.getBeginCreateTime(), vo.getEndCreateTime())
.orderByDesc(ScoreRuleDO::getId));
}
ScoreRuleQueryVO vo = (ScoreRuleQueryVO) object;
LambdaQueryWrapperX<ScoreRuleDO> queryWrapperX = new LambdaQuery<ScoreRuleDO>()
.eqIfPresent(ScoreRuleDO::getType, vo.getType())
.eqIfPresent(ScoreRuleDO::getStatus, vo.getStatus())
.betweenIfPresent(ScoreRuleDO::getCreateTime, vo.getBeginCreateTime(), vo.getEndCreateTime())
.orderByDesc(ScoreRuleDO::getId);
if (vo.getGetScoreOnceSymbol() != null && vo.getGetScoreOnce() != null) {
queryWrapperX.gt(vo.getGetScoreOnceSymbol() == RelationSymbolEnum.GT.getValue(), ScoreRuleDO::getGetScoreOnce, vo.getGetScoreOnce())
.eq(vo.getGetScoreOnceSymbol() == RelationSymbolEnum.EQ.getValue(), ScoreRuleDO::getGetScoreOnce, vo.getGetScoreOnce())
.lt(vo.getGetScoreOnceSymbol() == RelationSymbolEnum.LT.getValue(), ScoreRuleDO::getGetScoreOnce, vo.getGetScoreOnce());
}
if (vo.getMaxScoreTotalSymbol() != null && vo.getMaxScoreTotal() != null) {
queryWrapperX.gt(vo.getMaxScoreTotalSymbol() == RelationSymbolEnum.GT.getValue(), ScoreRuleDO::getMaxScoreTotal, vo.getMaxScoreTotal())
.eq(vo.getMaxScoreTotalSymbol() == RelationSymbolEnum.EQ.getValue(), ScoreRuleDO::getMaxScoreTotal, vo.getMaxScoreTotal())
.lt(vo.getMaxScoreTotalSymbol() == RelationSymbolEnum.LT.getValue(), ScoreRuleDO::getMaxScoreTotal, vo.getMaxScoreTotal());
}
queryWrapperX.and(vo.getTitle() != null, wrapper ->
wrapper.like(ScoreRuleDO::getTitleEn, vo.getTitle())
.or()
.like(ScoreRuleDO::getTitleZh, vo.getTitle())
);
queryWrapperX.and(vo.getDesc() != null, wrapper ->
wrapper.like(ScoreRuleDO::getDescZh, vo.getDesc())
.or()
.like(ScoreRuleDO::getDescEn, vo.getDesc())
);
return selectPage(page, queryWrapperX);
}
return null;
}
@Override
default List<ScoreRuleDO> selectList(Object object) {
if (object instanceof ScoreRuleQueryVO) {
ScoreRuleQueryVO vo = (ScoreRuleQueryVO)object;
ScoreRuleQueryVO vo = (ScoreRuleQueryVO) object;
return selectList(new LambdaQuery<ScoreRuleDO>()
.eqIfPresent(ScoreRuleDO::getType, vo.getType())
.eqIfPresent(ScoreRuleDO::getTitleZh, vo.getTitleZh())
.eqIfPresent(ScoreRuleDO::getTitleEn, vo.getTitleEn())
.eqIfPresent(ScoreRuleDO::getDescZh, vo.getDescZh())
.eqIfPresent(ScoreRuleDO::getDescEn, vo.getDescEn())
.eqIfPresent(ScoreRuleDO::getCoverImageZh, vo.getCoverImageZh())
.eqIfPresent(ScoreRuleDO::getCoverImageEn, vo.getCoverImageEn())
.eqIfPresent(ScoreRuleDO::getGetScoreOnce, vo.getGetScoreOnce())
.eqIfPresent(ScoreRuleDO::getMaxScoreTotal, vo.getMaxScoreTotal())
.betweenIfPresent(ScoreRuleDO::getStartTime, vo.getBeginStartTime(), vo.getEndStartTime())
.betweenIfPresent(ScoreRuleDO::getEndTime, vo.getBeginEndTime(), vo.getEndEndTime())
.eqIfPresent(ScoreRuleDO::getSocrePeriod, vo.getSocrePeriod())
.eqIfPresent(ScoreRuleDO::getOrderNum, vo.getOrderNum())
.eqIfPresent(ScoreRuleDO::getPushActivity, vo.getPushActivity())
.eqIfPresent(ScoreRuleDO::getShowPlatform, vo.getShowPlatform())
.eqIfPresent(ScoreRuleDO::getStatus, vo.getStatus())
.eqIfPresent(ScoreRuleDO::getExtra, vo.getExtra())
.betweenIfPresent(ScoreRuleDO::getCreateTime, vo.getBeginCreateTime(), vo.getEndCreateTime())
.eqIfPresent(ScoreRuleDO::getType, vo.getType())
.eqIfPresent(ScoreRuleDO::getGetScoreOnce, vo.getGetScoreOnce())
.eqIfPresent(ScoreRuleDO::getMaxScoreTotal, vo.getMaxScoreTotal())
.eqIfPresent(ScoreRuleDO::getStatus, vo.getStatus())
.betweenIfPresent(ScoreRuleDO::getCreateTime, vo.getBeginCreateTime(), vo.getEndCreateTime())
.orderByDesc(ScoreRuleDO::getId));
}
return null;
}
}
package cn.iocoder.yudao.module.member.job;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQuery;
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
import cn.iocoder.yudao.module.member.dal.dataobject.scoreRule.ScoreRuleDO;
import cn.iocoder.yudao.module.member.enums.ScoreRuleStatusEnum;
import cn.iocoder.yudao.module.member.service.scoreRule.ScoreRuleService;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
/**
* 会员积分过期定时任务
*/
@Component
@Slf4j
public class ScoreRuleExpireTask implements JobHandler {
/**
* 积分规则的过期时间为每日的0点整
* 任务每天0点整运行,扫描当天0点过期的积分进行状态修改
* @param param 参数
* @return
* @throws Exception
*/
@Resource
private ScoreRuleService scoreRuleService;
@Override
public String execute(String param) throws Exception {
log.info("score rule expire task running");
LambdaQuery<ScoreRuleDO> scoreRuleDOLambdaQuery = new LambdaQuery<>();
scoreRuleDOLambdaQuery.eq(ScoreRuleDO::getStatus, ScoreRuleStatusEnum.ENABLED.getValue());
scoreRuleDOLambdaQuery.le(ScoreRuleDO::getEndTime, DateUtils.getNextNDayStart(new Date(), 0));
List<ScoreRuleDO> todoList = scoreRuleService.selectList(scoreRuleDOLambdaQuery);
log.info("score rule expire task, to expire rule count :{}", todoList.size());
if (CollectionUtils.isEmpty(todoList)) {
return "success";
} else {
todoList.forEach(scoreRuleDO -> scoreRuleDO.setStatus(ScoreRuleStatusEnum.EXPIRED.getValue()));
scoreRuleService.updateBatch(todoList);
}
return "success";
}
}
......@@ -72,7 +72,7 @@ public interface ScoreRuleService extends IService<ScoreRuleDO> {
* @param scoreRuleStatusReqVO 积分规则状态
* @return
*/
Boolean updateStatus(ScoreRuleStatusReqVO scoreRuleStatusReqVO);
void updateStatus(ScoreRuleStatusReqVO scoreRuleStatusReqVO);
/**
* 积分规则复制
......@@ -86,5 +86,5 @@ public interface ScoreRuleService extends IService<ScoreRuleDO> {
* @param scoreDelayReqVO 积分规则延期
* @return
*/
Boolean delayScoreRule(ScoreDelayReqVO scoreDelayReqVO);
void delayScoreRule(ScoreDelayReqVO scoreDelayReqVO);
}
......@@ -6,17 +6,21 @@ import javax.annotation.Resource;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQuery;
import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService;
import cn.iocoder.yudao.module.member.convert.scoreRule.ScoreRuleConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.scoreRule.ScoreRuleDO;
import cn.iocoder.yudao.module.member.dal.mysql.scoreRule.ScoreRuleMapper;
import cn.iocoder.yudao.module.member.enums.ScoreRuleStatusEnum;
import cn.iocoder.yudao.module.member.enums.ScoreRuleTypeEnum;
import cn.iocoder.yudao.module.member.enums.TransportType;
import cn.iocoder.yudao.module.member.enums.YesOrNoTypeEnum;
import cn.iocoder.yudao.module.member.vo.scoreRule.*;
import cn.iocoder.yudao.module.member.vo.scoreRule.extra.ScoreRuleOrderVExtraVO;
import cn.iocoder.yudao.module.member.vo.scoreRule.extra.ScoreRuleRegisterExtraVO;
import cn.iocoder.yudao.module.member.vo.scoreRule.extra.ScoreRuleShareExtraVO;
import cn.iocoder.yudao.module.member.vo.scoreRule.extra.ScoreRulerRecommendExtraVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
......@@ -40,23 +44,59 @@ public class ScoreRuleServiceImpl extends AbstractService<ScoreRuleMapper, Score
@Override
public Long createScoreRule(ScoreRuleCreateReqVO createReqVO) {
ScoreRuleDO scoreRule = ScoreRuleConvert.INSTANCE.convert(createReqVO);
if (scoreRule.getStatus() != ScoreRuleStatusEnum.DISABLED.getValue() && scoreRule.getStatus() != ScoreRuleStatusEnum.ENABLED.getValue()){
throw exception(SCORE_RULE_FIELD_ERROR);
}
verifyCommon(scoreRule);
Integer scoreRuleType = scoreRule.getType();
setExtraDO(createReqVO, scoreRuleType, scoreRule);
verifyAndSetExtraDO(createReqVO, scoreRuleType, scoreRule);
scoreRuleMapper.insert(scoreRule);
// 返回
return scoreRule.getId();
}
private void verifyCommon(ScoreRuleDO scoreRule) {
//校验公共入参
if (scoreRule.getGetScoreOnce() <= 0) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
if (scoreRule.getMaxScoreTotal() <= 0) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
if (scoreRule.getStartTime().after((scoreRule.getEndTime())) || scoreRule.getEndTime().before(Date.from(Instant.now()))) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
if (scoreRule.getScorePeriod() <= 0) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
//如果是启用,校验同一个规则下,有效期内有没有重复的规则设置,分享不校验
if (scoreRule.getStatus() == ScoreRuleStatusEnum.ENABLED.getValue() && scoreRule.getType() != ScoreRuleTypeEnum.SHARE.getValue()) {
LambdaQuery<ScoreRuleDO> scoreRuleDOLambdaQuery = new LambdaQuery<>();
scoreRuleDOLambdaQuery.eq(ScoreRuleDO::getStatus, ScoreRuleStatusEnum.ENABLED.getValue())
.eq(ScoreRuleDO::getType, scoreRule.getType())
.eq(ScoreRuleDO::getStatus, ScoreRuleStatusEnum.ENABLED.getValue());
Long count = scoreRuleMapper.selectCount(scoreRuleDOLambdaQuery);
if (count > 0) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
}
}
@Override
public void updateScoreRule(ScoreRuleUpdateReqVO updateReqVO) {
// 校验存在
this.validateScoreRuleExists(updateReqVO.getId());
ScoreRuleDO scoreRuleDO = scoreRuleMapper.selectById(updateReqVO.getId());
if (scoreRuleDO == null) {
throw exception(SCORE_RULE_NOT_EXISTS);
}
if (scoreRuleDO.getStatus() != ScoreRuleStatusEnum.DISABLED.getValue()) {
throw exception(SCORE_RULE_UPDATE_ERROR);
}
ScoreRuleDO scoreRule = ScoreRuleConvert.INSTANCE.convert(updateReqVO);
setExtraDO(updateReqVO, updateReqVO.getType(), scoreRule);
verifyCommon(scoreRule);
verifyAndSetExtraDO(updateReqVO, updateReqVO.getType(), scoreRule);
// 更新
ScoreRuleDO updateObj = ScoreRuleConvert.INSTANCE.convert(updateReqVO);
scoreRuleMapper.updateById(updateObj);
scoreRuleMapper.updateById(scoreRule);
}
/**
......@@ -66,27 +106,80 @@ public class ScoreRuleServiceImpl extends AbstractService<ScoreRuleMapper, Score
* @param scoreRuleType 指标类型
* @param scoreRule 需要填充额外字段的DO
*/
private void setExtraDO(ScoreRuleBaseVO reqVO, Integer scoreRuleType, ScoreRuleDO scoreRule) {
private void verifyAndSetExtraDO(ScoreRuleBaseVO reqVO, Integer scoreRuleType, ScoreRuleDO scoreRule) {
if (scoreRuleType == ScoreRuleTypeEnum.ORDER_V.getValue()) {
scoreRule.setExtra(JSONUtil.toJsonStr(reqVO.getExtraOrderV()));
ScoreRuleOrderVExtraVO extraOrderV = reqVO.getExtraOrderV();
if (extraOrderV == null) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
if (extraOrderV.getFirstOrder() != YesOrNoTypeEnum.YES.ordinal() && extraOrderV.getFirstOrder() != YesOrNoTypeEnum.NO.ordinal()) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
if (extraOrderV.getTransportType() != TransportType.OCEAN_LCL.getValue() && extraOrderV.getFirstOrder() != TransportType.SPECIAL_LINE_AIR_FREIGHT.getValue()) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
if (StringUtils.isAnyBlank(extraOrderV.getTargetCountry(), extraOrderV.getTargetCity(), extraOrderV.getReceiveAddr(), extraOrderV.getOrderEntry())) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
verifyOrderVRule(extraOrderV.getOrderVRule());
scoreRule.setExtra(JSONUtil.toJsonStr(extraOrderV));
} else if (scoreRuleType == ScoreRuleTypeEnum.REGISTER.getValue()) {
if (reqVO.getExtraRegister() == null) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
if (StringUtils.isBlank(reqVO.getExtraRegister().getRegisterPlatform())) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
scoreRule.setExtra(JSONUtil.toJsonStr(reqVO.getExtraRegister()));
} else if (scoreRuleType == ScoreRuleTypeEnum.RECOMMEND.getValue()) {
scoreRule.setExtra(JSONUtil.toJsonStr(reqVO.getExtraRecommend()));
ScoreRulerRecommendExtraVO extraRecommend = reqVO.getExtraRecommend();
if (extraRecommend == null) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
if (extraRecommend.getShareStatus() != YesOrNoTypeEnum.YES.ordinal() && extraRecommend.getShareStatus() != YesOrNoTypeEnum.NO.ordinal()) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
if (StringUtils.isAnyBlank(extraRecommend.getShareContentEn(), extraRecommend.getShareContentZh())) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
scoreRule.setExtra(JSONUtil.toJsonStr(extraRecommend));
} else if (scoreRuleType == ScoreRuleTypeEnum.SHARE.getValue()) {
scoreRule.setExtra(JSONUtil.toJsonStr(reqVO.getExtraShare()));
ScoreRuleShareExtraVO extraShare = reqVO.getExtraShare();
if (extraShare == null) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
if (StringUtils.isAnyBlank(extraShare.getActivityDescZh(), extraShare.getActivityDescEn(), extraShare.getActivityUrl())) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
if (extraShare.getShareStatus() != YesOrNoTypeEnum.YES.ordinal() && extraShare.getShareStatus() != YesOrNoTypeEnum.NO.ordinal()) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
scoreRule.setExtra(JSONUtil.toJsonStr(extraShare));
} else {
throw exception(SCORE_RULE_NOT_EXISTS);
}
}
private void verifyOrderVRule(List<ScoreRuleOrderVExtraVO.OrderVRule> extraOrderVRule) {
if (extraOrderVRule == null || extraOrderVRule.isEmpty()) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
int low = 0;
for (ScoreRuleOrderVExtraVO.OrderVRule orderVRule : extraOrderVRule) {
if (orderVRule.getLow() < low || orderVRule.getHigh() <= orderVRule.getLow() || orderVRule.getScore() <= 0) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
low = orderVRule.getHigh();
}
}
@Override
public void deleteScoreRule(Long id) {
ScoreRuleDO scoreRuleDO = scoreRuleMapper.selectById(id);
if (scoreRuleDO == null) {
throw exception(SCORE_RULE_NOT_EXISTS);
}
if (scoreRuleDO.getStatus() == ScoreRuleStatusEnum.ENABLED.getValue()) {
if (scoreRuleDO.getStatus() != ScoreRuleStatusEnum.DISABLED.getValue()) {
throw exception(SCORE_RULE_DELETE_ERROR);
}
// 删除
......@@ -151,16 +244,33 @@ public class ScoreRuleServiceImpl extends AbstractService<ScoreRuleMapper, Score
}
@Override
public Boolean updateStatus(ScoreRuleStatusReqVO scoreRuleStatusReqVO) {
public void updateStatus(ScoreRuleStatusReqVO scoreRuleStatusReqVO) {
ScoreRuleDO scoreRuleDO = scoreRuleMapper.selectById(scoreRuleStatusReqVO.getId());
if (scoreRuleDO == null) {
throw exception(SCORE_RULE_NOT_EXISTS);
}
Integer oldStatus = scoreRuleDO.getStatus();
ScoreRuleDO upScoreRuleDO = new ScoreRuleDO();
upScoreRuleDO.setId(scoreRuleStatusReqVO.getId());
upScoreRuleDO.setStatus(scoreRuleStatusReqVO.getStatus());
int updated = scoreRuleMapper.updateById(upScoreRuleDO);
return updated > 0;
if (oldStatus == ScoreRuleStatusEnum.ENABLED.getValue() && scoreRuleStatusReqVO.getStatus() == ScoreRuleStatusEnum.CLOSED.getValue()) {
upScoreRuleDO.setStatus(scoreRuleStatusReqVO.getStatus());
} else if (oldStatus == ScoreRuleStatusEnum.DISABLED.getValue() && scoreRuleStatusReqVO.getStatus() == ScoreRuleStatusEnum.ENABLED.getValue()) {
//如果是启用,校验同一个规则下,有效期内有没有重复的规则设置,分享不校验
if (scoreRuleDO.getType() != ScoreRuleTypeEnum.SHARE.getValue()) {
LambdaQuery<ScoreRuleDO> scoreRuleDOLambdaQuery = new LambdaQuery<>();
scoreRuleDOLambdaQuery.eq(ScoreRuleDO::getStatus, ScoreRuleStatusEnum.ENABLED.getValue())
.eq(ScoreRuleDO::getType, scoreRuleDO.getType())
.eq(ScoreRuleDO::getStatus, ScoreRuleStatusEnum.ENABLED.getValue());
Long count = scoreRuleMapper.selectCount(scoreRuleDOLambdaQuery);
if (count > 0) {
throw exception(SCORE_RULE_FIELD_ERROR);
}
}
upScoreRuleDO.setStatus(scoreRuleStatusReqVO.getStatus());
} else {
throw exception(SCORE_RULE_UPDATE_ERROR);
}
scoreRuleMapper.updateById(upScoreRuleDO);
}
@Override
......@@ -173,12 +283,13 @@ public class ScoreRuleServiceImpl extends AbstractService<ScoreRuleMapper, Score
scoreRuleDO.setId(null);
scoreRuleDO.setCreateTime(null);
scoreRuleDO.setUpdateTime(null);
scoreRuleDO.setUpdater(null);
scoreRuleMapper.insert(scoreRuleDO);
return scoreRuleDO.getId();
}
@Override
public Boolean delayScoreRule(ScoreDelayReqVO delayReqVO) {
public void delayScoreRule(ScoreDelayReqVO delayReqVO) {
ScoreRuleDO scoreRuleDO = scoreRuleMapper.selectById(delayReqVO.getId());
if (scoreRuleDO == null) {
throw exception(SCORE_RULE_NOT_EXISTS);
......@@ -188,13 +299,12 @@ public class ScoreRuleServiceImpl extends AbstractService<ScoreRuleMapper, Score
}
Instant now = Instant.now();
//结束时间不能小于当前时间
if (!delayReqVO.getEndTime().toInstant().isAfter(now)) {
if (!delayReqVO.getEndTime().toInstant().isAfter(now) || !delayReqVO.getEndTime().toInstant().isAfter(scoreRuleDO.getStartTime().toInstant())) {
throw exception(SCORE_RULE_UPDATE_ERROR);
}
ScoreRuleDO upScoreRuleDO = new ScoreRuleDO();
upScoreRuleDO.setId(delayReqVO.getId());
upScoreRuleDO.setEndTime(delayReqVO.getEndTime());
int updated = scoreRuleMapper.updateById(upScoreRuleDO);
return updated > 0;
scoreRuleMapper.updateById(upScoreRuleDO);
}
}
package cn.iocoder.yudao.module.member.vo.scoreRule;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
@ApiModel("管理后台 - 积分规则id请求 VO")
public class IdReqVo {
@ApiModelProperty(value = "主键", required = true)
@NotNull(message = "主键不能为空")
private Long id;
}
......@@ -24,7 +24,7 @@ public class ScoreRuleBaseVO {
private Integer type;
@ApiModelProperty(value = "规则标题中文", required = true)
@NotNull(message = "规则标题中文不能为空")
@NotBlank(message = "规则标题中文不能为空")
private String titleZh;
@ApiModelProperty(value = "规则标题英文", required = true)
......
package cn.iocoder.yudao.module.member.vo.scoreRule;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
......@@ -15,64 +17,25 @@ public class ScoreRuleQueryVO {
@ApiModelProperty(value = "指标类型")
private Integer type;
@ApiModelProperty(value = "规则标题中文")
private String titleZh;
@ApiModelProperty(value = "规则标题英文")
private String titleEn;
@ApiModelProperty(value = "规则说明中文")
private String descZh;
@ApiModelProperty(value = "规则说明英文")
private String descEn;
@ApiModelProperty(value = "规则标题")
private String title;
@ApiModelProperty(value = "封面图中文")
private String coverImageZh;
@ApiModelProperty(value = "封面图英文")
private String coverImageEn;
@ApiModelProperty(value = "规则说明")
private String desc;
@ApiModelProperty(value = "单次获取积分数查询条件(1大于,2等于,3小于)")
private Integer getScoreOnceSymbol;
@ApiModelProperty(value = "单次获取积分数")
private Integer getScoreOnce;
@ApiModelProperty(value = "单次获取积分数查询条件(1大于,2等于,3小于)")
private Integer maxScoreTotalSymbol;
@ApiModelProperty(value = "累积最高积分")
private Integer maxScoreTotal;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始活动开始时间")
private Date beginStartTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束活动开始时间")
private Date endStartTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始活动结束时间")
private Date beginEndTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束活动结束时间")
private Date endEndTime;
@ApiModelProperty(value = "积分有效期")
private Integer socrePeriod;
@ApiModelProperty(value = "排序值")
private Integer orderNum;
@ApiModelProperty(value = "是否推送")
private Integer pushActivity;
@ApiModelProperty(value = "展示平台")
private String showPlatform;
@ApiModelProperty(value = "活动状态")
private Integer status;
@ApiModelProperty(value = "扩展字段")
private String extra;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始创建时间")
private Date beginCreateTime;
......@@ -80,5 +43,4 @@ public class ScoreRuleQueryVO {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束创建时间")
private Date endCreateTime;
}
......@@ -14,5 +14,5 @@ public class ScoreRuleShareExtraVO {
@ApiModelProperty(value = "活动链接", required = true)
private String activityUrl ;
@ApiModelProperty(value = "是否分享(0是,1否)默认是", required = true)
private String shareStatus ;
private Integer shareStatus ;
}
......@@ -27,6 +27,7 @@ public interface ErrorCodeConstants {
ErrorCode REWARD_REDEEM_STATUS_ERROR = new ErrorCode(1001011019, "reward.redeem.status.error");
ErrorCode REWARD_REDEEM_VERIFY_NO_PARAM = new ErrorCode(1001011020, "reward.redeem.verify.no.param");
ErrorCode REWARD_REDEEM_BATCH_VERIFY_ERROR = new ErrorCode(1001011021, "reward.redeem.batch.verify.error");
ErrorCode REWARD_REDEEM_VERIFY_BACK_STATUS = new ErrorCode(1001011021, "reward.redeem.verify.back.status");
ErrorCode REWARD_REDEEM_VERIFY_BACK_STATUS = new ErrorCode(1001011022, "reward.redeem.verify.back.status");
ErrorCode REDEEM_IMPORT_MAX_COUNT = new ErrorCode(1001011023, "redeem.import.max.count");
}
......@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.reward.controller.admin.redeem;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.util.ExcelUtils;
import cn.iocoder.yudao.module.reward.api.reward.RedeemRewardApi;
import cn.iocoder.yudao.module.reward.api.reward.dto.RedeemRewardReqVO;
import cn.iocoder.yudao.module.reward.api.reward.dto.RedeemRewardRespDTO;
......@@ -10,16 +11,21 @@ import cn.iocoder.yudao.module.reward.vo.reward.*;
import cn.iocoder.yudao.module.reward.vo.reward.RewardRedeemPageReqVO;
import cn.iocoder.yudao.module.reward.vo.reward.RewardRedeemPageRespVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
......@@ -78,6 +84,31 @@ public class RedeemRewardController {
return success(rewardRedeemService.export(reqVO));
}
@PostMapping("record/import/template")
@ApiOperation("导入模板下载")
public void importTemplate(HttpServletResponse response) throws IOException {
// 手动创建导出 demo
List<RedeemInfoImportExcelVO> list = Arrays.asList(
RedeemInfoImportExcelVO.builder().id(String.valueOf(11111)).redeemType("上门领取").courierCompany("顺丰空运").expenses(BigDecimal.valueOf(11.11))
.currency("人民币").expressDate("2024-01-01 11:22:33").expressNo("SDSD212212").remark("备注备注").expressSender("系统管理员")
.build(),
RedeemInfoImportExcelVO.builder().id(String.valueOf(11111)).redeemType("包邮到家").courierCompany("顺丰空运").expenses(BigDecimal.valueOf(11.11))
.currency("美元").expressDate("2024-01-01 11:22:33").expressNo("SDSD212212").remark("备注备注").expressSender("系统管理员")
.build());
// 输出
ExcelUtils.write(response, "兑换信息导入模板.xls", "兑换信息", RedeemInfoImportExcelVO.class, list);
}
@PostMapping(value = "record/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ApiOperation("兑换信息导入")
@ApiImplicitParams({
@ApiImplicitParam(name = "file", value = "Excel 文件", required = true, dataTypeClass = MultipartFile.class)
})
public CommonResult<RecordInfoImportRespVO> recordImport(@RequestParam("file") MultipartFile file) throws IOException {
List<RedeemInfoImportExcelVO> list = ExcelUtils.read(file, RedeemInfoImportExcelVO.class);
return success(rewardRedeemService.recordImport(list));
}
@PostMapping("/single")
@ApiOperation("兑换礼品")
......
......@@ -76,7 +76,7 @@ public class RewardRedeemDO extends BaseDO {
/**
* 快递公司
*/
private Integer courierCompany;
private Long courierCompany;
/**
* 快递单号
*/
......
package cn.iocoder.yudao.module.reward.dto;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* @author zhaobiyan
*/
@Data
public class RedeemRecordImportDTO {
private Long id;
private Integer redeemType;
private BigDecimal expenses;
private Integer currency;
private Integer courierCompany;
private String expressNo;
private Date expressDate;
private String expressSender;
private String remark;
}
......@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.reward.dto;
import lombok.Builder;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
......@@ -15,7 +16,11 @@ public class RewardRedeemVerifyDTO {
private Integer redeemType;
private Integer courierCompany;
private BigDecimal expense;
private Integer currency;
private Long courierCompany;
/**
* 收件人地址
*/
......
......@@ -31,4 +31,6 @@ public interface RewardRedeemService extends IService<RewardRedeemDO> {
List<RewardRedeemPageRespVO> exportList(RewardRedeemPageReqVO request);
Integer exportCount(RewardRedeemPageReqVO request);
RecordInfoImportRespVO recordImport(List<RedeemInfoImportExcelVO> dataList);
}
package cn.iocoder.yudao.module.reward.service.redeem;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.dict.core.dto.DictDataRespDTO;
import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
import cn.iocoder.yudao.framework.i18n.core.I18nMessage;
import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.ecw.api.currency.CurrencyApi;
import cn.iocoder.yudao.module.ecw.api.currency.dto.CurrencyRespDTO;
import cn.iocoder.yudao.module.ecw.api.express.ExpressApi;
import cn.iocoder.yudao.module.ecw.api.express.dto.ExpressRespDTO;
import cn.iocoder.yudao.module.reward.dal.dataobject.redeem.RewardRedeemDO;
import cn.iocoder.yudao.module.reward.dal.mysql.redeem.RewardRedeemMapper;
import cn.iocoder.yudao.module.reward.dto.RewardRedeemVerifyDTO;
import cn.iocoder.yudao.module.reward.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.reward.enums.RewardPickMethedEnum;
import cn.iocoder.yudao.module.reward.enums.RewardRedeemStatusEnum;
import cn.iocoder.yudao.module.reward.service.reward.RewardService;
import cn.iocoder.yudao.module.reward.vo.reward.*;
import cn.iocoder.yudao.module.system.api.file.FileMakeApi;
import cn.iocoder.yudao.module.system.api.file.dto.FileMakeReqDTO;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_PATTERN;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.download.DownloadTypeEnum.REWARD_REDEEM_RECORD;
......@@ -41,12 +46,21 @@ import static cn.iocoder.yudao.module.system.enums.download.DownloadTypeEnum.REW
@Service
@Slf4j
public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper, RewardRedeemDO> implements RewardRedeemService {
@Resource
private RewardRedeemMapper rewardRedeemMapper;
@Resource
private RewardService rewardService;
@Resource
private FileMakeApi fileMakeApi;
private static final Integer MAX_IMPORT_RECORD_COUNT = 500;
private final RewardRedeemMapper rewardRedeemMapper;
private final FileMakeApi fileMakeApi;
private final ExpressApi expressApi;
private final CurrencyApi currencyApi;
public RewardRedeemServiceImpl(RewardRedeemMapper rewardRedeemMapper, FileMakeApi fileMakeApi,
ExpressApi expressApi, CurrencyApi currencyApi) {
this.rewardRedeemMapper = rewardRedeemMapper;
this.fileMakeApi = fileMakeApi;
this.expressApi = expressApi;
this.currencyApi = currencyApi;
}
@Override
public PageResult<RewardRedeemPageRespVO> pageInfo(RewardRedeemPageReqVO reqVO) {
......@@ -92,7 +106,7 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
@Override
public Boolean verify(RewardRedeemVerifyReqVO request) {
if (!checkVerifyParam(request)){
if (!checkVerifyParam(request)) {
throw exception(ErrorCodeConstants.REWARD_REDEEM_VERIFY_NO_PARAM);
}
LambdaUpdateWrapper<RewardRedeemDO> wrapper = Wrappers.lambdaUpdate();
......@@ -178,33 +192,140 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
public List<RewardRedeemPageRespVO> exportList(RewardRedeemPageReqVO request) {
return rewardRedeemMapper.exportList(request);
}
@Override
public Integer exportCount(RewardRedeemPageReqVO request) {
return rewardRedeemMapper.pageCount(request);
}
@Override
public RecordInfoImportRespVO recordImport(List<RedeemInfoImportExcelVO> dataList) {
if (CollectionUtils.isEmpty(dataList)) {
return RecordInfoImportRespVO.builder().build();
}
if (dataList.size() > MAX_IMPORT_RECORD_COUNT) {
throw exception(ErrorCodeConstants.REDEEM_IMPORT_MAX_COUNT, MAX_IMPORT_RECORD_COUNT);
}
Collection<CurrencyRespDTO> allCurrency = currencyApi.getAllCurrency().values();
Map<String, CurrencyRespDTO> titleZhCurrencyMap = allCurrency.stream().collect(Collectors.toMap(CurrencyRespDTO::getTitleZh, Function.identity(), (c1, c2) -> c1));
Map<String, CurrencyRespDTO> titleEnCurrencyMap = allCurrency.stream().collect(Collectors.toMap(CurrencyRespDTO::getTitleEn, Function.identity(), (c1, c2) -> c1));
Map<String, ExpressRespDTO> nameExpressMap = expressApi.getAllExpress().stream().collect(Collectors.toMap(ExpressRespDTO::getCompanyName, Function.identity(), (c1, c2) -> c1));
Map<String, String> failedInfo = validate(dataList, titleZhCurrencyMap, titleEnCurrencyMap, nameExpressMap);
if (MapUtil.isNotEmpty(failedInfo)) {
return RecordInfoImportRespVO.builder().redeemIdFailedMap(failedInfo).build();
}
List<RewardRedeemDO> saveDataList = dataList.stream().map(data -> {
RewardRedeemDO rewardRedeemDO = new RewardRedeemDO();
rewardRedeemDO.setId(Long.parseLong(data.getId()));
DictDataRespDTO redeemTypeDict = DictFrameworkUtils.parseDictDataFromCacheWithMultiLang("way_of_receiving", data.getRedeemType());
rewardRedeemDO.setRedeemType(Integer.parseInt(redeemTypeDict.getValue()));
rewardRedeemDO.setExpenses(data.getExpenses());
CurrencyRespDTO currencyRespDTO = titleZhCurrencyMap.get(data.getCurrency());
if (currencyRespDTO == null) {
currencyRespDTO = titleEnCurrencyMap.get(data.getCurrency());
}
rewardRedeemDO.setCurrency(Optional.ofNullable(currencyRespDTO).map(CurrencyRespDTO::getId).orElse(null));
rewardRedeemDO.setCourierCompany(nameExpressMap.get(data.getCourierCompany()).getId());
rewardRedeemDO.setExpressNo(data.getExpressNo());
rewardRedeemDO.setExpressDate(DateUtil.parse(data.getExpressDate(), NORM_DATETIME_PATTERN));
rewardRedeemDO.setExpressSender(data.getExpressSender());
rewardRedeemDO.setRemark(data.getRemark());
return rewardRedeemDO;
}).collect(Collectors.toList());
this.updateBatchById(saveDataList);
return RecordInfoImportRespVO.builder().build();
}
private Map<String, String> validate(List<RedeemInfoImportExcelVO> dataList, Map<String, CurrencyRespDTO> titleZhCurrencyMap,
Map<String, CurrencyRespDTO> titleEnCurrencyMap,
Map<String, ExpressRespDTO> nameExpressMap) {
LambdaQueryWrapper<RewardRedeemDO> wrapper = Wrappers.lambdaQuery();
wrapper.in(RewardRedeemDO::getId, dataList.stream().map(RedeemInfoImportExcelVO::getId).collect(Collectors.toSet()));
Map<Long, RewardRedeemDO> idRewardRedeemDOMap = rewardRedeemMapper.selectList(wrapper).stream()
.collect(Collectors.toMap(RewardRedeemDO::getId, Function.identity(), (c1, c2) -> c1));
Map<String, String> failedInfoMap = new HashMap<>();
dataList.forEach(data -> {
long id ;
try {
id = Long.parseLong(data.getId());
}catch (Exception e) {
failedInfoMap.put(data.getId() == null ? "" : data.getId(), I18nMessage.getMessage("reward.redeem.not.exist"));
return;
}
try {
DateUtil.parse(data.getExpressDate(), NORM_DATETIME_PATTERN);
} catch (Exception e) {
failedInfoMap.put(data.getId() == null ? "" : data.getId(), I18nMessage.getMessage("date.format.error"));
return;
}
RewardRedeemDO rewardRedeemDO = idRewardRedeemDOMap.get(id);
if (rewardRedeemDO == null) {
failedInfoMap.put(data.getId() == null ? "" : data.getId(), I18nMessage.getMessage("reward.redeem.not.exist"));
return;
}
if (rewardRedeemDO.getStatus() != RewardRedeemStatusEnum.REDEEMING.getValue()) {
failedInfoMap.put(data.getId(), I18nMessage.getMessage("reward.redeem.status.error"));
return;
}
DictDataRespDTO redeemTypeDict = DictFrameworkUtils.parseDictDataFromCacheWithMultiLang("way_of_receiving", data.getRedeemType());
if (redeemTypeDict == null) {
failedInfoMap.put(data.getId(), I18nMessage.getMessage("dict.unknown.error", "way_of_receiving", data.getRedeemType()));
return;
}
ExpressRespDTO expressRespDTO = nameExpressMap.get(data.getCourierCompany());
if (expressRespDTO == null) {
failedInfoMap.put(data.getId(), I18nMessage.getMessage("express.not.exist"));
return;
}
CurrencyRespDTO currencyRespDTO = titleZhCurrencyMap.get(data.getCurrency());
if (currencyRespDTO == null) {
currencyRespDTO = titleEnCurrencyMap.get(data.getCurrency());
}
if (currencyRespDTO == null && StringUtils.isNotBlank(data.getCurrency())) {
failedInfoMap.put(data.getId(), I18nMessage.getMessage("currency.not.exist"));
return;
}
if (!canVerify(RewardRedeemVerifyDTO.builder()
.id(Long.parseLong(data.getId()))
.redeemType(Integer.parseInt(redeemTypeDict.getValue()))
.status(rewardRedeemDO.getStatus())
.expense(data.getExpenses())
.currency(Optional.ofNullable(currencyRespDTO).map(CurrencyRespDTO::getId).orElse(null))
.courierCompany(expressRespDTO.getId())
.expressSender(data.getExpressSender())
.expressDate(DateUtil.parse(data.getExpressDate(), NORM_DATETIME_PATTERN))
.expressNo(data.getExpressNo())
.recipientAddress(rewardRedeemDO.getRecipientAddress()).build())) {
failedInfoMap.put(String.valueOf(rewardRedeemDO.getId()), I18nMessage.getMessage("reward.redeem.verify.no.param"));
}
});
return failedInfoMap;
}
private List<Long> checkBatchVerifyParam(RewardRedeemBatchVerifyReqVO request) {
LambdaUpdateWrapper<RewardRedeemDO> wrapper = Wrappers.lambdaUpdate();
wrapper.in(RewardRedeemDO::getId, request.getIds());
Map<Long, RewardRedeemDO> idRewardRedeemMap = this.list(wrapper).stream()
.collect(Collectors.toMap(RewardRedeemDO::getId, Function.identity(), (c1, c2) -> c1));
List<Long> errorIds = idRewardRedeemMap.keySet().stream().filter(id -> {
RewardRedeemDO rewardRedeemDO = idRewardRedeemMap.get(id);
if (rewardRedeemDO == null) {
return true;
}
return !canVerify(RewardRedeemVerifyDTO.builder()
.id(rewardRedeemDO.getId())
.status(rewardRedeemDO.getStatus())
.redeemType(rewardRedeemDO.getRedeemType())
.courierCompany(rewardRedeemDO.getCourierCompany())
.expressDate(rewardRedeemDO.getExpressDate())
.recipientAddress(rewardRedeemDO.getRecipientAddress())
.expressNo(rewardRedeemDO.getExpressNo())
.expressSender(rewardRedeemDO.getExpressSender())
.build());
}).collect(Collectors.toList());
return errorIds;
return idRewardRedeemMap.keySet().stream().filter(id -> {
RewardRedeemDO rewardRedeemDO = idRewardRedeemMap.get(id);
if (rewardRedeemDO == null) {
return true;
}
return !canVerify(RewardRedeemVerifyDTO.builder()
.id(rewardRedeemDO.getId())
.status(rewardRedeemDO.getStatus())
.redeemType(rewardRedeemDO.getRedeemType())
.expense(rewardRedeemDO.getExpenses())
.currency(rewardRedeemDO.getCurrency())
.courierCompany(rewardRedeemDO.getCourierCompany())
.expressDate(rewardRedeemDO.getExpressDate())
.recipientAddress(rewardRedeemDO.getRecipientAddress())
.expressNo(rewardRedeemDO.getExpressNo())
.expressSender(rewardRedeemDO.getExpressSender())
.build());
}).collect(Collectors.toList());
}
private boolean checkVerifyParam(RewardRedeemVerifyReqVO request) {
......@@ -216,6 +337,8 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
.id(rewardRedeemDO.getId())
.status(rewardRedeemDO.getStatus())
.redeemType(rewardRedeemDO.getRedeemType())
.expense(rewardRedeemDO.getExpenses())
.currency(rewardRedeemDO.getCurrency())
.courierCompany(request.getCourierCompany())
.expressDate(request.getExpressDate())
.recipientAddress(request.getRecipientAddress())
......@@ -229,7 +352,12 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
return false;
}
if (rewardRedeemVerifyDTO.getRedeemType() != RewardPickMethedEnum.SELF_PICKUP.getValue()) {
//除上门领取状态外,其他方式需要验证 courierCompany, expressNo, expressDate, expressSender, recipientAddress 不能为空
if (rewardRedeemVerifyDTO.getExpense() == null) {
return false;
}
if (rewardRedeemVerifyDTO.getCurrency() == null) {
return false;
}
if (rewardRedeemVerifyDTO.getCourierCompany() == null) {
return false;
}
......
package cn.iocoder.yudao.module.reward.vo.reward;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import java.util.Map;
@Data
@Builder
public class RecordInfoImportRespVO {
@ApiModelProperty(value = "导入失败的信息集合", required = true, notes = "key 为兑换id,value 为失败原因")
private Map<String, String> redeemIdFailedMap;
public RecordInfoImportRespVO() {
}
public RecordInfoImportRespVO(Map<String, String> redeemIdFailedMap) {
this.redeemIdFailedMap = redeemIdFailedMap;
}
}
package cn.iocoder.yudao.module.reward.vo.reward;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = false)
public class RedeemInfoImportExcelVO {
@ExcelProperty("兑换记录ID/Redeem ID")
private String id;
@ExcelProperty("兑换方式/Redeem Method")
private String redeemType;
@ExcelProperty("费用/fee")
private BigDecimal expenses;
@ExcelProperty("币种/Currency")
private String currency;
@ExcelProperty("快递公司/Express")
private String courierCompany;
@ExcelProperty("快递单号/Express NO")
private String expressNo;
@ExcelProperty(value = "快递日期/Delivery Date")
private String expressDate;
@ExcelProperty("快递寄出人/Sender")
private String expressSender;
@ExcelProperty("备注/Remark")
private String remark;
}
......@@ -25,7 +25,7 @@ public class RewardRedeemVerifyReqVO {
private String recipientPhoneNum;
@ApiModelProperty(value = "快递公司")
private Integer courierCompany;
private Long courierCompany;
/**
* 收件人地址
*/
......
......@@ -26,6 +26,7 @@ public interface ChannelConvert {
ChannelRespVO convert(ChannelDO bean);
List<ChannelRespVO> convertList(List<ChannelDO> list);
List<ChannelSimpleRespVO> convertSimpleList(List<ChannelDO> list);
PageResult<ChannelRespVO> convertPage(PageResult<ChannelDO> page);
......
......@@ -86,4 +86,6 @@ public interface ChannelService extends IService<ChannelDO> {
* @return 渠道管理分页
*/
PageResult<ChannelRespVO> channelPage(ChannelPageReqVO pageVO);
List<ChannelDO> getChannelSimpleList();
}
......@@ -19,6 +19,7 @@ import cn.iocoder.yudao.module.sale.service.channel.ChannelService;
import cn.iocoder.yudao.module.sale.service.channelPackaging.ChannelPackagingService;
import cn.iocoder.yudao.module.sale.service.channelPriceStepClearance.ChannelPriceStepClearanceService;
import cn.iocoder.yudao.module.sale.vo.channel.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.lang3.StringUtils;
......@@ -233,4 +234,9 @@ public class ChannelServiceImpl extends AbstractService<ChannelMapper, ChannelDO
List<ChannelRespVO> channelList = pageResult.getList();
return pageResult;
}
@Override
public List<ChannelDO> getChannelSimpleList() {
return channelMapper.selectList(new LambdaQueryWrapper<ChannelDO>());
}
}
package cn.iocoder.yudao.module.sale.vo.channel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ApiModel("渠道精简信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ChannelSimpleRespVO {
@ApiModelProperty(value = "", required = true)
private Long channelId;
@ApiModelProperty(value = "中文标题")
private String nameZh;
@ApiModelProperty(value = "英文标题")
private String nameEn;
}
\ No newline at end of file
......@@ -110,6 +110,13 @@ public class ChannelController {
return success(ChannelConvert.INSTANCE.convertList(list));
}
@GetMapping("/list-all-simple")
@ApiOperation(value = "获得渠道精简信息列表", notes = "主要用于前端的下拉选项")
public CommonResult<List<ChannelSimpleRespVO>> getChannelSimpleList() {
List<ChannelDO> list = channelService.getChannelSimpleList();
return success(ChannelConvert.INSTANCE.convertSimpleList(list));
}
@GetMapping("/select")
@ApiOperation("获得可用渠道列表查询(参数可选择一个,最终以目的地国家来查询,不传代表查询所有)")
@ApiImplicitParams({
......
......@@ -70,6 +70,9 @@ public class DictDataServiceImpl implements DictDataService {
* key2:字典标签 label
*/
private ImmutableTable<String, String, DictDataDO> labelDictDataCache;
private ImmutableTable<String, String, DictDataDO> labelEnDictDataCache;
/**
* 字典数据缓存,第二个 key 使用 value
*
......@@ -93,13 +96,16 @@ public class DictDataServiceImpl implements DictDataService {
// 构建缓存
ImmutableTable.Builder<String, String, DictDataDO> labelDictDataBuilder = ImmutableTable.builder();
ImmutableTable.Builder<String, String, DictDataDO> labelEnDictDataBuilder = ImmutableTable.builder();
ImmutableTable.Builder<String, String, DictDataDO> valueDictDataBuilder = ImmutableTable.builder();
dataList.forEach(dictData -> {
labelDictDataBuilder.put(dictData.getDictType(), dictData.getLabel(), dictData);
valueDictDataBuilder.put(dictData.getDictType(), dictData.getValue(), dictData);
labelEnDictDataBuilder.put(dictData.getDictType(), dictData.getLabelEn(), dictData);
});
labelDictDataCache = labelDictDataBuilder.build();
valueDictDataCache = valueDictDataBuilder.build();
labelEnDictDataCache = labelEnDictDataBuilder.build();
maxUpdateTime = CollectionUtils.getMaxValue(dataList, DictDataDO::getUpdateTime);
log.info("[initLocalCache][缓存字典数据,数量为:{}]", dataList.size());
}
......@@ -174,6 +180,15 @@ public class DictDataServiceImpl implements DictDataService {
return DictDataConvert.INSTANCE.convertList03(labelDictDataCache.row(type).values());
}
@Override
public DictDataRespDTO parseDictDataFromCacheWithMultiLang(String type, String multiLangLabel) {
DictDataDO dictDataDO = labelDictDataCache.get(type, multiLangLabel);
if (dictDataDO == null) {
dictDataDO = labelEnDictDataCache.get(type, multiLangLabel);
}
return DictDataConvert.INSTANCE.convert02(dictDataDO);
}
@Override
public Long createDictData(DictDataCreateReqVO reqVO) {
// 校验正确性
......
......@@ -1013,6 +1013,11 @@ reward.time.not.allow=The reward time is not allow
get.lock.failed = The service is busy, please try again later
reward.redeem.not.exist = reward redeem record does not exist
reward.redeem.status.error = reward redeem record that is redeeming can edit or verify
reward.redeem.verify.no.param = In addition to collect at home, the delivery company/delivery number/delivery time/delivery sender/recipient address must be filled in
reward.redeem.verify.no.param = Fee/Currency/Express/Express NO/Delivery Date/Sender/Recipient Address must be filled in
reward.redeem.batch.verify.error = reward redeem record verify failed, please check record data : {}
reward.redeem.verify.back.status = record status must be redeemed
\ No newline at end of file
reward.redeem.verify.back.status = record status must be redeemed
redeem.import.max.count = allow maximum number of imports is {}
dict.unknown.error = Not in dict {0}: {1}
express.not.exist = express not exist
currency.not.exist = currency not exist
date.format.error = date format error, for example : 2024-01-01 12:11:11
\ No newline at end of file
......@@ -1017,6 +1017,11 @@ reward.time.not.allow=\u6D3B\u52A8\u65F6\u95F4\u4E0D\u5408\u6CD5
get.lock.failed = \u670D\u52A1\u7E41\u5FD9\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5
reward.redeem.not.exist = \u793C\u54C1\u5151\u6362\u8BB0\u5F55\u4E0D\u5B58\u5728
reward.redeem.status.error = \u53EA\u6709\u5151\u6362\u4E2D\u72B6\u6001\u7684\u8BB0\u5F55\u624D\u5141\u8BB8\u7F16\u8F91\u6216\u6838\u9500
reward.redeem.verify.no.param = \u9664\u4E0A\u95E8\u9886\u53D6\u5916\uFF0C\u5FEB\u9012\u516C\u53F8/\u5FEB\u9012\u5355\u53F7/\u5FEB\u9012\u65F6\u95F4/\u5FEB\u9012\u53D1\u9001\u4EBA/\u6536\u4EF6\u4EBA\u5730\u5740\uFF0C\u5FC5\u987B\u586B\u5199
reward.redeem.verify.no.param = \u8D27\u503C/\u5E01\u79CD/\u5FEB\u9012\u516C\u53F8/\u5FEB\u9012\u5355\u53F7/\u5FEB\u9012\u65F6\u95F4/\u5FEB\u9012\u53D1\u9001\u4EBA/\u6536\u4EF6\u4EBA\u5730\u5740\uFF0C\u5FC5\u987B\u586B\u5199
reward.redeem.batch.verify.error = \u793C\u54C1\u8BB0\u5F55\u6279\u91CF\u6838\u9500\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u6570\u636E\u662F\u5426\u6B63\u786E:{}
reward.redeem.verify.back.status = \u56DE\u9000\u8BB0\u5F55\u72B6\u6001\u5FC5\u987B\u4E3A\u5DF2\u5151\u6362
\ No newline at end of file
reward.redeem.verify.back.status = \u56DE\u9000\u8BB0\u5F55\u72B6\u6001\u5FC5\u987B\u4E3A\u5DF2\u5151\u6362
redeem.import.max.count = \u5141\u8BB8\u7684\u6700\u5927\u5BFC\u5165\u6761\u6570\u4E3A{}
dict.unknown.error = \u4E0D\u5728{0}\u5B57\u5178\u4E2D: {1}
express.not.exist = \u5FEB\u9012\u516C\u53F8\u4E0D\u5B58\u5728
currency.not.exist = \u5E01\u79CD\u4E0D\u5B58\u5728
date.format.error = \u65E5\u671F\u683C\u5F0F\u4E0D\u6B63\u786E, \u6B63\u786E\u683C\u5F0F\u53C2\u8003: 2024-01-01 12:11:11
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment