Merge remote-tracking branch 'origin/main'

main
zhangshengli 4 months ago
commit 27ec1f391b

@ -19,6 +19,7 @@ public class LoginUser {
public static final String INFO_KEY_NICKNAME = "nickname"; public static final String INFO_KEY_NICKNAME = "nickname";
public static final String INFO_KEY_DEPT_ID = "deptId"; public static final String INFO_KEY_DEPT_ID = "deptId";
public static final String INFO_KEY_MOBILE = "mobile";
/** /**
* *

@ -112,6 +112,17 @@ public class SecurityFrameworkUtils {
return loginUser != null ? MapUtil.getLong(loginUser.getInfo(), LoginUser.INFO_KEY_DEPT_ID) : null; return loginUser != null ? MapUtil.getLong(loginUser.getInfo(), LoginUser.INFO_KEY_DEPT_ID) : null;
} }
/**
*
*
* @return
*/
@Nullable
public static String getLoginUserMobile() {
LoginUser loginUser = getLoginUser();
return loginUser != null ? MapUtil.getStr(loginUser.getInfo(), LoginUser.INFO_KEY_MOBILE) : null;
}
/** /**
* *
* *

@ -124,5 +124,11 @@ public interface ErrorCodeConstants {
// ========== 装修页面 1-013-018-000 ========== // ========== 装修页面 1-013-018-000 ==========
ErrorCode DIY_PAGE_NOT_EXISTS = new ErrorCode(1_013_018_000, "装修页面不存在"); ErrorCode DIY_PAGE_NOT_EXISTS = new ErrorCode(1_013_018_000, "装修页面不存在");
ErrorCode DIY_PAGE_NAME_USED = new ErrorCode(1_013_018_001, "装修页面名称({})已经被使用"); ErrorCode DIY_PAGE_NAME_USED = new ErrorCode(1_013_018_001, "装修页面名称({})已经被使用");
ErrorCode PRIZE_DRAW_NOT_EXISTS = new ErrorCode(1_013_018_002, "抽奖活动不存在");
ErrorCode PRIZE_DRAW_NOT_START = new ErrorCode(1_013_018_003, "抽奖活动暂未开启");
ErrorCode PRIZE_DRAW_NOT_TIME = new ErrorCode(1_013_018_004, "抽奖活动未开始或已过期");
ErrorCode PRIZE_LOG_NOT_EXISTS = new ErrorCode(1_013_018_005, "抽奖记录不存在");
ErrorCode PRIZE_LOG_NOT_DRAWNUM = new ErrorCode(1_013_018_006, "抽奖次数已达上限");
ErrorCode PRIZE_LOG_NOT_LEVEL = new ErrorCode(1_013_018_007, "分销等级不在权限范围");
} }

@ -0,0 +1,121 @@
package cn.iocoder.yudao.module.promotion.controller.admin.prizedraw;
import cn.iocoder.yudao.module.member.api.level.MemberLevelApi;
import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.promotion.convert.prizedraw.PrizeDrawConvert;
import cn.iocoder.yudao.module.promotion.convert.prizelog.PrizeLogConvert;
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainHelpDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.ActivityPrizeDO;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo.*;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO;
import cn.iocoder.yudao.module.promotion.service.prizedraw.PrizeDrawService;
@Tag(name = "管理后台 - 抽奖活动")
@RestController
@RequestMapping("/promotion/prize-draw")
@Validated
public class PrizeDrawController {
@Resource
private PrizeDrawService prizeDrawService;
@Resource
private MemberLevelApi memberLevelApi;
@PostMapping("/create")
@Operation(summary = "创建抽奖活动")
@PreAuthorize("@ss.hasPermission('promotion:prize-draw:create')")
public CommonResult<Long> createPrizeDraw(@Valid @RequestBody PrizeDrawSaveReqVO createReqVO) {
return success(prizeDrawService.createPrizeDraw(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新抽奖活动")
@PreAuthorize("@ss.hasPermission('promotion:prize-draw:update')")
public CommonResult<Boolean> updatePrizeDraw(@Valid @RequestBody PrizeDrawSaveReqVO updateReqVO) {
prizeDrawService.updatePrizeDraw(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除抽奖活动")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('promotion:prize-draw:delete')")
public CommonResult<Boolean> deletePrizeDraw(@RequestParam("id") Long id) {
prizeDrawService.deletePrizeDraw(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得抽奖活动")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('promotion:prize-draw:query')")
public CommonResult<PrizeDrawRespVO> getPrizeDraw(@RequestParam("id") Long id) {
PrizeDrawDO prizeDraw = prizeDrawService.getPrizeDraw(id);
return success(BeanUtils.toBean(prizeDraw, PrizeDrawRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得抽奖活动分页")
@PreAuthorize("@ss.hasPermission('promotion:prize-draw:query')")
public CommonResult<PageResult<PrizeDrawRespVO>> getPrizeDrawPage(@Valid PrizeDrawPageReqVO pageReqVO) {
PageResult<PrizeDrawDO> pageResult = prizeDrawService.getPrizeDrawPage(pageReqVO);
// 处理用户级别返显
List<MemberLevelRespDTO> levels = memberLevelApi.getLevelList(
convertSet(pageResult.getList(), PrizeDrawDO::getMebLevel));
return success(PrizeDrawConvert.INSTANCE.convertPage(pageResult, levels));
}
@GetMapping("/export-excel")
@Operation(summary = "导出抽奖活动 Excel")
@PreAuthorize("@ss.hasPermission('promotion:prize-draw:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportPrizeDrawExcel(@Valid PrizeDrawPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<PrizeDrawDO> list = prizeDrawService.getPrizeDrawPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "抽奖活动.xls", "数据", PrizeDrawRespVO.class,
BeanUtils.toBean(list, PrizeDrawRespVO.class));
}
// ==================== 子表(抽奖活动奖品) ====================
@GetMapping("/activity-prize/list-by-activity-id")
@Operation(summary = "获得抽奖活动奖品列表")
@Parameter(name = "activityId", description = "关联抽奖活动id")
@PreAuthorize("@ss.hasPermission('promotion:prize-draw:query')")
public CommonResult<List<ActivityPrizeDO>> getActivityPrizeListByActivityId(@RequestParam("activityId") Long activityId) {
return success(prizeDrawService.getActivityPrizeListByActivityId(activityId));
}
}

@ -0,0 +1,49 @@
package cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 抽奖活动分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class PrizeDrawPageReqVO extends PageParam {
@Schema(description = "活动名称", example = "李四")
private String name;
@Schema(description = "活动规则")
private String activityRule;
@Schema(description = "活动状态0开启1关闭", example = "1")
private String status;
@Schema(description = "开始时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] startTime;
@Schema(description = "截至时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] endTime;
@Schema(description = "会员等级")
private Integer mebLevel;
/**
*
*/
@Schema(description = "单人次抽奖次数")
private Integer drawNum;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,61 @@
package cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 抽奖活动 Response VO")
@Data
@ExcelIgnoreUnannotated
public class PrizeDrawRespVO {
@Schema(description = "id主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1166")
@ExcelProperty("id主键")
private Long id;
@Schema(description = "活动名称", example = "李四")
@ExcelProperty("活动名称")
private String name;
@Schema(description = "活动规则")
@ExcelProperty("活动规则")
private String activityRule;
@Schema(description = "活动状态0开启1关闭", example = "1")
@ExcelProperty("活动状态0开启1关闭")
private String status;
@Schema(description = "开始时间")
@ExcelProperty("开始时间")
private LocalDateTime startTime;
@Schema(description = "截至时间")
@ExcelProperty("截至时间")
private LocalDateTime endTime;
@Schema(description = "会员等级")
@ExcelProperty("会员等级")
private Long mebLevel;
/**
*
*/
@Schema(description = "单人次抽奖次数")
@ExcelProperty("单人次抽奖次数")
private Integer drawNum;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
/**
*
*/
@Schema(description = "会员等级名称")
@ExcelProperty("会员等级名称")
private String levelName;
}

@ -0,0 +1,46 @@
package cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.ActivityPrizeDO;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 抽奖活动新增/修改 Request VO")
@Data
public class PrizeDrawSaveReqVO {
@Schema(description = "id主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1166")
private Long id;
@Schema(description = "活动名称", example = "李四")
private String name;
@Schema(description = "活动规则")
private String activityRule;
@Schema(description = "活动状态0开启1关闭", example = "1")
private String status;
@Schema(description = "开始时间")
private LocalDateTime startTime;
@Schema(description = "截至时间")
private LocalDateTime endTime;
@Schema(description = "会员等级")
private Integer mebLevel;
/**
*
*/
@Schema(description = "单人次抽奖次数")
private Integer drawNum;
@Schema(description = "抽奖活动奖品列表")
private List<ActivityPrizeDO> activityPrizes;
}

@ -0,0 +1,115 @@
package cn.iocoder.yudao.module.promotion.controller.admin.prizelog;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.promotion.convert.bargain.BargainHelpConvert;
import cn.iocoder.yudao.module.promotion.convert.prizelog.PrizeLogConvert;
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainHelpDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO;
import cn.iocoder.yudao.module.promotion.service.prizedraw.PrizeDrawService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.*;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO;
import cn.iocoder.yudao.module.promotion.service.prizelog.PrizeLogService;
@Tag(name = "管理后台 - 抽奖记录")
@RestController
@RequestMapping("/promotion/prize-log")
@Validated
public class PrizeLogController {
@Resource
private PrizeLogService prizeLogService;
@Resource
private MemberUserApi memberUserApi;
@Resource
private PrizeDrawService prizeDrawService;
@PostMapping("/create")
@Operation(summary = "创建抽奖记录")
@PreAuthorize("@ss.hasPermission('promotion:prize-log:create')")
public CommonResult<Long> createPrizeLog(@Valid @RequestBody PrizeLogSaveReqVO createReqVO) {
return success(prizeLogService.createPrizeLog(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新抽奖记录")
@PreAuthorize("@ss.hasPermission('promotion:prize-log:update')")
public CommonResult<Boolean> updatePrizeLog(@Valid @RequestBody PrizeLogSaveReqVO updateReqVO) {
prizeLogService.updatePrizeLog(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除抽奖记录")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('promotion:prize-log:delete')")
public CommonResult<Boolean> deletePrizeLog(@RequestParam("id") Long id) {
prizeLogService.deletePrizeLog(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得抽奖记录")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('promotion:prize-log:query')")
public CommonResult<PrizeLogRespVO> getPrizeLog(@RequestParam("id") Long id) {
PrizeLogDO prizeLog = prizeLogService.getPrizeLog(id);
return success(BeanUtils.toBean(prizeLog, PrizeLogRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得抽奖记录分页")
@PreAuthorize("@ss.hasPermission('promotion:prize-log:query')")
public CommonResult<PageResult<PrizeLogRespVO>> getPrizeLogPage(@Valid PrizeLogPageReqVO pageReqVO) {
PageResult<PrizeLogDO> pageResult = prizeLogService.getPrizeLogPage(pageReqVO);
// 拼接用户数据
Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(
convertSet(pageResult.getList(), PrizeLogDO::getMebId));
// 拼接活动数据
Map<Long, PrizeDrawDO> prizeMap = prizeDrawService.getPrizeDrawMap(
convertSet(pageResult.getList(), PrizeLogDO::getActivityId));
return success(PrizeLogConvert.INSTANCE.convertPage(pageResult, userMap,prizeMap));
}
@GetMapping("/export-excel")
@Operation(summary = "导出抽奖记录 Excel")
@PreAuthorize("@ss.hasPermission('promotion:prize-log:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportPrizeLogExcel(@Valid PrizeLogPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<PrizeLogDO> list = prizeLogService.getPrizeLogPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "抽奖记录.xls", "数据", PrizeLogRespVO.class,
BeanUtils.toBean(list, PrizeLogRespVO.class));
}
}

@ -0,0 +1,49 @@
package cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 抽奖记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class PrizeLogPageReqVO extends PageParam {
@Schema(description = "会员id", example = "26219")
private Long mebId;
@Schema(description = "关联抽奖活动id", example = "17850")
private Long activityId;
@Schema(description = "奖品id", example = "17850")
private Long prizeId;
@Schema(description = "奖品名称", example = "李四")
private String name;
@Schema(description = "奖品图片路径", example = "https://www.iocoder.cn")
private String imgUrl;
@Schema(description = "获奖人数上限")
private Integer winNum;
@Schema(description = "获奖概率")
private String prizeChance;
@Schema(description = "获奖金额")
private String prizePoolAmount;
@Schema(description = "兑奖状态0已兑奖1未兑奖", example = "2")
private String status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,67 @@
package cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 抽奖记录 Response VO")
@Data
@ExcelIgnoreUnannotated
public class PrizeLogRespVO {
@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "5655")
@ExcelProperty("主键id")
private Long id;
@Schema(description = "会员id", example = "26219")
@ExcelProperty("会员id")
private Long mebId;
@Schema(description = "关联抽奖活动id", example = "17850")
@ExcelProperty("关联抽奖活动id")
private Long activityId;
@Schema(description = "奖品id", example = "17850")
@ExcelProperty("奖品id")
private Long prizeId;
@Schema(description = "奖品名称", example = "李四")
@ExcelProperty("奖品名称")
private String name;
@Schema(description = "奖品图片路径", example = "https://www.iocoder.cn")
@ExcelProperty("奖品图片路径")
private String imgUrl;
@Schema(description = "获奖人数上限")
@ExcelProperty("获奖人数上限")
private Integer winNum;
@Schema(description = "获奖概率")
@ExcelProperty("获奖概率")
private String prizeChance;
@Schema(description = "获奖金额")
@ExcelProperty("获奖金额")
private String prizePoolAmount;
@Schema(description = "兑奖状态0已兑奖1未兑奖", example = "2")
@ExcelProperty("兑奖状态0已兑奖1未兑奖")
private String status;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
// ========== 用户相关 ==========
@Schema(description = "用户昵称", example = "老芋艿")
private String nickname;
@Schema(description = "活动名称", example = "老芋艿")
private String activityName;
}

@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 抽奖记录新增/修改 Request VO")
@Data
public class PrizeLogSaveReqVO {
@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "5655")
private Long id;
@Schema(description = "会员id", example = "26219")
private Long mebId;
@Schema(description = "关联抽奖活动id", example = "17850")
private Long activityId;
@Schema(description = "奖品id", example = "17850")
private Long prizeId;
@Schema(description = "奖品名称", example = "李四")
private String name;
@Schema(description = "奖品图片路径", example = "https://www.iocoder.cn")
private String imgUrl;
@Schema(description = "获奖人数上限")
private Integer winNum;
@Schema(description = "获奖概率")
private String prizeChance;
@Schema(description = "获奖金额")
private String prizePoolAmount;
@Schema(description = "兑奖状态0已兑奖1未兑奖", example = "2")
private String status;
}

@ -0,0 +1,180 @@
package cn.iocoder.yudao.module.promotion.controller.app.prizedraw;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.WeightRandom;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.api.level.MemberLevelApi;
import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.PrizeLogPageReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.PrizeLogRespVO;
import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.PrizeLogSaveReqVO;
import cn.iocoder.yudao.module.promotion.controller.app.prizedraw.vo.AppPrizeDrawRespVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.ActivityPrizeDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO;
import cn.iocoder.yudao.module.promotion.service.prizedraw.PrizeDrawService;
import cn.iocoder.yudao.module.promotion.service.prizelog.PrizeLogService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.USER_NOT_EXISTS;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
@Tag(name = "用户APP - 抽奖活动")
@RestController
@RequestMapping("/promotion/prize-draw")
@Validated
public class AppPrizeDrawController {
@Resource
private PrizeDrawService prizeDrawService;
@Resource
private PrizeLogService prizeLogService;
@Resource
private RedissonClient redissonClient;
@Resource
private MemberUserApi memberUserApi;
@Resource
private MemberLevelApi memberLevelApi;
@GetMapping("/getOne")
@Operation(summary = "用户APP--获得抽奖活动规则")
public CommonResult<AppPrizeDrawRespVO> getPrizeDraw() {
PrizeDrawDO prizeDraw = prizeDrawService.getOnePrizeDraw();
if (prizeDraw == null) {//抽奖活动不存在
throw exception(PRIZE_DRAW_NOT_EXISTS);
}
return success(BeanUtils.toBean(prizeDraw, AppPrizeDrawRespVO.class));
}
@GetMapping("/activity-prize/list-by-activity-id")
@Operation(summary = "用户APP--获得抽奖活动奖品列表")
@Parameter(name = "activityId", description = "关联抽奖活动id")
public CommonResult<List<ActivityPrizeDO>> getActivityPrizeListByActivityId(@RequestParam("activityId") Long activityId) {
return success(prizeDrawService.getActivityPrizeListByActivityId(activityId));
}
@GetMapping("/lottery")
@Operation(summary = "用户APP--抽奖")
@Parameter(name = "activityId", description = "关联抽奖活动id")
public CommonResult<ActivityPrizeDO> lottery(@RequestParam("activityId") Long activityId) {
//获取用户id
Long loginUserId = getLoginUserId();
//查询用户信息
MemberUserRespDTO user = memberUserApi.getUser(loginUserId);
//用户不存在
if(user == null){
throw exception(USER_NOT_EXISTS);
}
//获取活动信息
PrizeDrawDO prizeDraw = prizeDrawService.getPrizeDraw(activityId);
if (prizeDraw == null) {//抽奖活动不存在
throw exception(PRIZE_DRAW_NOT_EXISTS);
}
//判断活动状态
if(!ObjectUtil.equal(prizeDraw.getStatus(),"0")){
throw exception(PRIZE_DRAW_NOT_START);
}
//判断抽奖活动时间范围
if(!DateUtil.isIn(new Date(),DateUtils.of(prizeDraw.getStartTime()),DateUtils.of(prizeDraw.getEndTime()))){
throw exception(PRIZE_DRAW_NOT_TIME);
}
//判断抽奖活动会员等级
MemberLevelRespDTO memberLevel = memberLevelApi.getMemberLevel(user.getLevelId());
MemberLevelRespDTO activityLevel = memberLevelApi.getMemberLevel(Long.valueOf(prizeDraw.getMebLevel()));
if(memberLevel.getLevel()<activityLevel.getLevel()){
throw exception(PRIZE_LOG_NOT_LEVEL);
}
//判断参与次数
Long drawNum = prizeLogService.getPrizeLogByMebIdList(loginUserId, prizeDraw);
if(drawNum>=prizeDraw.getDrawNum()){
throw exception(PRIZE_LOG_NOT_DRAWNUM);
}
//抽奖
ActivityPrizeDO activityPrizeDO = recursionLottery(prizeDraw);
return success(activityPrizeDO);
}
private ActivityPrizeDO recursionLottery(PrizeDrawDO prizeDraw){
//获取奖品信息
List<ActivityPrizeDO> list = prizeDrawService.getActivityPrizeListByActivityId(prizeDraw.getId());
//获取随机数
int sortNum = (int) (Math.random() * ((8-list.size()) + 1));
// TODO: 2023/8/16 0016 后台限制
List<WeightRandom.WeightObj<String>> weightObjList = new ArrayList<WeightRandom.WeightObj<String>>();
list.forEach(s -> {
weightObjList.add(new WeightRandom.WeightObj<>(s.getId().toString(), Double.valueOf(s.getPrizeChance())));
});
WeightRandom<String> wr = RandomUtil.weightRandom(weightObjList);
String str = wr.next();
RLock lock = redissonClient.getLock(str);
try {
if (lock.tryLock(1000, 10000, TimeUnit.MILLISECONDS)) {
ActivityPrizeDO activityPrize = prizeDrawService.getActivityPrize(Long.valueOf(str));
//判断被抽中次数
Long prizeLogNum = prizeLogService.getPrizeLogList(prizeDraw, activityPrize.getId());
if (prizeLogNum >= activityPrize.getWinNum()) {
recursionLottery(prizeDraw);
}
//中奖
//添加抽奖记录
PrizeLogSaveReqVO createReqVO = new PrizeLogSaveReqVO();
createReqVO.setMebId(getLoginUserId());
createReqVO.setActivityId(prizeDraw.getId());
createReqVO.setPrizeId(activityPrize.getId());
createReqVO.setName(activityPrize.getName());
createReqVO.setImgUrl(activityPrize.getImgUrl());
createReqVO.setWinNum(activityPrize.getWinNum());
createReqVO.setPrizeChance(activityPrize.getPrizeChance());
createReqVO.setPrizePoolAmount(activityPrize.getPrizePoolAmount());
createReqVO.setStatus("1");
prizeLogService.createPrizeLog(createReqVO);
return activityPrize;
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
if (ObjectUtil.isNotEmpty(lock)){
lock.unlock();
}
}
return null;
}
@GetMapping("/getMyPrizeLogDO")
@Operation(summary = "获得我的抽奖记录")
public CommonResult<List<PrizeLogRespVO>> getPrizeLogPage(@RequestParam("activityId") Long activityId) {
//获取活动信息
PrizeDrawDO prizeDraw = prizeDrawService.getPrizeDraw(activityId);
List<PrizeLogDO> list = prizeLogService.getPrizeLogListByMebId(getLoginUserId(), prizeDraw);
return success(BeanUtils.toBean(list, PrizeLogRespVO.class));
}
}

@ -0,0 +1,52 @@
package cn.iocoder.yudao.module.promotion.controller.app.prizedraw.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "应用 App - 抽奖活动分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class AppPrizeDrawPageReqVO extends PageParam {
@Schema(description = "活动名称", example = "李四")
private String name;
@Schema(description = "活动规则")
private String activityRule;
@Schema(description = "活动状态0开启1关闭", example = "1")
private String status;
@Schema(description = "开始时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] startTime;
@Schema(description = "截至时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] endTime;
@Schema(description = "会员等级")
private Integer mebLevel;
/**
*
*/
@Schema(description = "单人次抽奖次数")
@ExcelProperty("单人次抽奖次数")
private Integer drawNum;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,54 @@
package cn.iocoder.yudao.module.promotion.controller.app.prizedraw.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "应用 App - 抽奖活动 Response VO")
@Data
@ExcelIgnoreUnannotated
public class AppPrizeDrawRespVO {
@Schema(description = "id主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1166")
@ExcelProperty("id主键")
private Long id;
@Schema(description = "活动名称", example = "李四")
@ExcelProperty("活动名称")
private String name;
@Schema(description = "活动规则")
@ExcelProperty("活动规则")
private String activityRule;
@Schema(description = "活动状态0开启1关闭", example = "1")
@ExcelProperty("活动状态0开启1关闭")
private String status;
@Schema(description = "开始时间")
@ExcelProperty("开始时间")
private LocalDateTime startTime;
@Schema(description = "截至时间")
@ExcelProperty("截至时间")
private LocalDateTime endTime;
@Schema(description = "会员等级")
@ExcelProperty("会员等级")
private Integer mebLevel;
/**
*
*/
@Schema(description = "单人次抽奖次数")
@ExcelProperty("单人次抽奖次数")
private Integer drawNum;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

@ -0,0 +1,44 @@
package cn.iocoder.yudao.module.promotion.controller.app.prizedraw.vo;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.ActivityPrizeDO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "应用 App - 抽奖活动新增/修改 Request VO")
@Data
public class AppPrizeDrawSaveReqVO {
@Schema(description = "id主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1166")
private Long id;
@Schema(description = "活动名称", example = "李四")
private String name;
@Schema(description = "活动规则")
private String activityRule;
@Schema(description = "活动状态0开启1关闭", example = "1")
private String status;
@Schema(description = "开始时间")
private LocalDateTime startTime;
@Schema(description = "截至时间")
private LocalDateTime endTime;
@Schema(description = "会员等级")
private Integer mebLevel;
/**
*
*/
@Schema(description = "单人次抽奖次数")
private Integer drawNum;
@Schema(description = "抽奖活动奖品列表")
private List<ActivityPrizeDO> activityPrizes;
}

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.promotion.convert.prizedraw;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo.PrizeDrawRespVO;
import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.PrizeLogRespVO;
import cn.iocoder.yudao.module.promotion.convert.prizelog.PrizeLogConvert;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
@Mapper
public interface PrizeDrawConvert {
PrizeDrawConvert INSTANCE = Mappers.getMapper(PrizeDrawConvert.class);
default PageResult<PrizeDrawRespVO> convertPage(PageResult<PrizeDrawDO> page,
List<MemberLevelRespDTO> levels) {
PageResult<PrizeDrawRespVO> pageResult = convertPage(page);
Map<Long, String> levelMap = convertMap(levels, MemberLevelRespDTO::getId, MemberLevelRespDTO::getName);
// 拼接数据
pageResult.getList().forEach(record ->{
MapUtils.findAndThen(levelMap, record.getMebLevel(),
level -> record.setLevelName(levelMap.get(record.getMebLevel())));
});
return pageResult;
}
PageResult<PrizeDrawRespVO> convertPage(PageResult<PrizeDrawDO> page);
}

@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.promotion.convert.prizelog;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.help.BargainHelpRespVO;
import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.PrizeLogRespVO;
import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.help.AppBargainHelpRespVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainHelpDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
/**
* Convert
*
* @author
*/
@Mapper
public interface PrizeLogConvert {
PrizeLogConvert INSTANCE = Mappers.getMapper(PrizeLogConvert.class);
default PageResult<PrizeLogRespVO> convertPage(PageResult<PrizeLogDO> page,
Map<Long, MemberUserRespDTO> userMap,
Map<Long, PrizeDrawDO> prizeMap) {
PageResult<PrizeLogRespVO> pageResult = convertPage(page);
// 拼接数据
pageResult.getList().forEach(record ->{
MapUtils.findAndThen(userMap, record.getMebId(),
user -> record.setNickname(user.getNickname()));
MapUtils.findAndThen(prizeMap, record.getActivityId(),
activity -> record.setActivityName(activity.getName()));
});
return pageResult;
}
PageResult<PrizeLogRespVO> convertPage(PageResult<PrizeLogDO> page);
}

@ -0,0 +1,55 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* DO
*
* @author
*/
@TableName("promotion_activity_prize")
@KeySequence("promotion_activity_prize_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ActivityPrizeDO extends BaseDO {
/**
* id
*/
@TableId
private Long id;
/**
* id
*/
private Long activityId;
/**
*
*/
private String name;
/**
*
*/
private String imgUrl;
/**
*
*/
private Integer winNum;
/**
*
*/
private String prizeChance;
/**
*
*/
private String prizePoolAmount;
}

@ -0,0 +1,61 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* DO
*
* @author
*/
@TableName("promotion_prize_draw")
@KeySequence("promotion_prize_draw_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PrizeDrawDO extends BaseDO {
/**
* id
*/
@TableId
private Long id;
/**
*
*/
private String name;
/**
*
*/
private String activityRule;
/**
* 01
*/
private String status;
/**
*
*/
private LocalDateTime startTime;
/**
*
*/
private LocalDateTime endTime;
/**
*
*/
private Long mebLevel;
/**
*
*/
private Integer drawNum;
}

@ -0,0 +1,67 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* DO
*
* @author
*/
@TableName("promotion_prize_log")
@KeySequence("promotion_prize_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PrizeLogDO extends BaseDO {
/**
* id
*/
@TableId
private Long id;
/**
* id
*/
private Long mebId;
/**
* id
*/
private Long activityId;
/**
* id
*/
private Long prizeId;
/**
*
*/
private String name;
/**
*
*/
private String imgUrl;
/**
*
*/
private Integer winNum;
/**
*
*/
private String prizeChance;
/**
*
*/
private String prizePoolAmount;
/**
* 01
*/
private String status;
}

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.promotion.dal.mysql.prizedraw;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.ActivityPrizeDO;
import org.apache.ibatis.annotations.Mapper;
/**
* Mapper
*
* @author
*/
@Mapper
public interface ActivityPrizeMapper extends BaseMapperX<ActivityPrizeDO> {
default List<ActivityPrizeDO> selectListByActivityId(Long activityId) {
return selectList(ActivityPrizeDO::getActivityId, activityId);
}
default int deleteByActivityId(Long activityId) {
return delete(ActivityPrizeDO::getActivityId, activityId);
}
}

@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.promotion.dal.mysql.prizedraw;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo.*;
/**
* Mapper
*
* @author
*/
@Mapper
public interface PrizeDrawMapper extends BaseMapperX<PrizeDrawDO> {
default PageResult<PrizeDrawDO> selectPage(PrizeDrawPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<PrizeDrawDO>()
.likeIfPresent(PrizeDrawDO::getName, reqVO.getName())
.eqIfPresent(PrizeDrawDO::getActivityRule, reqVO.getActivityRule())
.eqIfPresent(PrizeDrawDO::getStatus, reqVO.getStatus())
.betweenIfPresent(PrizeDrawDO::getStartTime, reqVO.getStartTime())
.betweenIfPresent(PrizeDrawDO::getEndTime, reqVO.getEndTime())
.eqIfPresent(PrizeDrawDO::getMebLevel, reqVO.getMebLevel())
.betweenIfPresent(PrizeDrawDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(PrizeDrawDO::getId));
}
}

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.promotion.dal.mysql.prizelog;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.*;
/**
* Mapper
*
* @author
*/
@Mapper
public interface PrizeLogMapper extends BaseMapperX<PrizeLogDO> {
default PageResult<PrizeLogDO> selectPage(PrizeLogPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<PrizeLogDO>()
.eqIfPresent(PrizeLogDO::getMebId, reqVO.getMebId())
.eqIfPresent(PrizeLogDO::getActivityId, reqVO.getActivityId())
.likeIfPresent(PrizeLogDO::getName, reqVO.getName())
.eqIfPresent(PrizeLogDO::getImgUrl, reqVO.getImgUrl())
.eqIfPresent(PrizeLogDO::getWinNum, reqVO.getWinNum())
.eqIfPresent(PrizeLogDO::getPrizeChance, reqVO.getPrizeChance())
.eqIfPresent(PrizeLogDO::getPrizePoolAmount, reqVO.getPrizePoolAmount())
.eqIfPresent(PrizeLogDO::getStatus, reqVO.getStatus())
.betweenIfPresent(PrizeLogDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(PrizeLogDO::getId));
}
}

@ -0,0 +1,104 @@
package cn.iocoder.yudao.module.promotion.service.prizedraw;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo.*;
import cn.iocoder.yudao.module.promotion.controller.app.prizedraw.vo.AppPrizeDrawRespVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.ActivityPrizeDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
/**
* Service
*
* @author
*/
public interface PrizeDrawService {
/**
*
*
* @param createReqVO
* @return
*/
Long createPrizeDraw(@Valid PrizeDrawSaveReqVO createReqVO);
/**
*
*
* @param updateReqVO
*/
void updatePrizeDraw(@Valid PrizeDrawSaveReqVO updateReqVO);
/**
*
*
* @param id
*/
void deletePrizeDraw(Long id);
/**
*
*
* @param id
* @return
*/
PrizeDrawDO getPrizeDraw(Long id);
/**
*
*
* @param pageReqVO
* @return
*/
PageResult<PrizeDrawDO> getPrizeDrawPage(PrizeDrawPageReqVO pageReqVO);
// ==================== 子表(抽奖活动奖品) ====================
/**
*
*
* @param activityId id
* @return
*/
List<ActivityPrizeDO> getActivityPrizeListByActivityId(Long activityId);
/**
*
*
* @param id id
* @return
*/
ActivityPrizeDO getActivityPrize(Long id);
/**
*
*
* @return
*/
PrizeDrawDO getOnePrizeDraw();
/**
* Map
*
* @param ids id
* @return Map
*/
default Map<Long, PrizeDrawDO> getPrizeDrawMap(Collection<Long> ids) {
List<PrizeDrawDO> list = getPrizeDrawDOList(ids);
return convertMap(list, PrizeDrawDO::getId);
}
/**
*
*
* @param ids
* @return
*/
List<PrizeDrawDO> getPrizeDrawDOList(Collection<Long> ids);
}

@ -0,0 +1,136 @@
package cn.iocoder.yudao.module.promotion.service.prizedraw;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.ActivityPrizeDO;
import cn.iocoder.yudao.module.promotion.dal.mysql.prizedraw.ActivityPrizeMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo.*;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.promotion.dal.mysql.prizedraw.PrizeDrawMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
/**
* Service
*
* @author
*/
@Service
@Validated
public class PrizeDrawServiceImpl implements PrizeDrawService {
@Resource
private PrizeDrawMapper prizeDrawMapper;
@Resource
private ActivityPrizeMapper activityPrizeMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createPrizeDraw(PrizeDrawSaveReqVO createReqVO) {
// 插入
PrizeDrawDO prizeDraw = BeanUtils.toBean(createReqVO, PrizeDrawDO.class);
prizeDrawMapper.insert(prizeDraw);
// 插入子表
createActivityPrizeList(prizeDraw.getId(), createReqVO.getActivityPrizes());
// 返回
return prizeDraw.getId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updatePrizeDraw(PrizeDrawSaveReqVO updateReqVO) {
// 校验存在
validatePrizeDrawExists(updateReqVO.getId());
// 更新
PrizeDrawDO updateObj = BeanUtils.toBean(updateReqVO, PrizeDrawDO.class);
prizeDrawMapper.updateById(updateObj);
// 更新子表
updateActivityPrizeList(updateReqVO.getId(), updateReqVO.getActivityPrizes());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deletePrizeDraw(Long id) {
// 校验存在
validatePrizeDrawExists(id);
// 删除
prizeDrawMapper.deleteById(id);
// 删除子表
deleteActivityPrizeByActivityId(id);
}
private void validatePrizeDrawExists(Long id) {
if (prizeDrawMapper.selectById(id) == null) {
throw exception(PRIZE_DRAW_NOT_EXISTS);
}
}
@Override
public PrizeDrawDO getPrizeDraw(Long id) {
return prizeDrawMapper.selectById(id);
}
@Override
public PageResult<PrizeDrawDO> getPrizeDrawPage(PrizeDrawPageReqVO pageReqVO) {
return prizeDrawMapper.selectPage(pageReqVO);
}
// ==================== 子表(抽奖活动奖品) ====================
@Override
public List<ActivityPrizeDO> getActivityPrizeListByActivityId(Long activityId) {
return activityPrizeMapper.selectListByActivityId(activityId);
}
private void createActivityPrizeList(Long activityId, List<ActivityPrizeDO> list) {
list.forEach(o -> o.setActivityId(activityId));
activityPrizeMapper.insertBatch(list);
}
private void updateActivityPrizeList(Long activityId, List<ActivityPrizeDO> list) {
deleteActivityPrizeByActivityId(activityId);
list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下1id 冲突2updateTime 不更新
createActivityPrizeList(activityId, list);
}
private void deleteActivityPrizeByActivityId(Long activityId) {
activityPrizeMapper.deleteByActivityId(activityId);
}
@Override
public PrizeDrawDO getOnePrizeDraw() {
return prizeDrawMapper.selectOne(new LambdaQueryWrapperX<PrizeDrawDO>()
.eq(PrizeDrawDO::getStatus, 0)
);
}
@Override
public List<PrizeDrawDO> getPrizeDrawDOList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return ListUtil.empty();
}
return prizeDrawMapper.selectBatchIds(ids);
}
@Override
public ActivityPrizeDO getActivityPrize(Long id) {
return activityPrizeMapper.selectById(id);
}
}

@ -0,0 +1,81 @@
package cn.iocoder.yudao.module.promotion.service.prizelog;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.*;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
/**
* Service
*
* @author
*/
public interface PrizeLogService {
/**
*
*
* @param createReqVO
* @return
*/
Long createPrizeLog(@Valid PrizeLogSaveReqVO createReqVO);
/**
*
*
* @param updateReqVO
*/
void updatePrizeLog(@Valid PrizeLogSaveReqVO updateReqVO);
/**
*
*
* @param id
*/
void deletePrizeLog(Long id);
/**
*
*
* @param id
* @return
*/
PrizeLogDO getPrizeLog(Long id);
/**
*
*
* @param pageReqVO
* @return
*/
PageResult<PrizeLogDO> getPrizeLogPage(PrizeLogPageReqVO pageReqVO);
/**
*
*
* @param mebId id
* @return
*/
Long getPrizeLogByMebIdList(Long mebId,PrizeDrawDO prizeDraw);
/**
*
*
* @param prizeDraw
* @return
*/
Long getPrizeLogList(PrizeDrawDO prizeDraw,Long prizeId);
/**
*
*
* @param prizeDraw
* @return
*/
List<PrizeLogDO> getPrizeLogListByMebId(Long mebId,PrizeDrawDO prizeDraw);
}

@ -0,0 +1,103 @@
package cn.iocoder.yudao.module.promotion.service.prizelog;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.*;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.promotion.dal.mysql.prizelog.PrizeLogMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
/**
* Service
*
* @author
*/
@Service
@Validated
public class PrizeLogServiceImpl implements PrizeLogService {
@Resource
private PrizeLogMapper prizeLogMapper;
@Override
public Long createPrizeLog(PrizeLogSaveReqVO createReqVO) {
// 插入
PrizeLogDO prizeLog = BeanUtils.toBean(createReqVO, PrizeLogDO.class);
prizeLogMapper.insert(prizeLog);
// 返回
return prizeLog.getId();
}
@Override
public void updatePrizeLog(PrizeLogSaveReqVO updateReqVO) {
// 校验存在
validatePrizeLogExists(updateReqVO.getId());
// 更新
PrizeLogDO updateObj = BeanUtils.toBean(updateReqVO, PrizeLogDO.class);
prizeLogMapper.updateById(updateObj);
}
@Override
public void deletePrizeLog(Long id) {
// 校验存在
validatePrizeLogExists(id);
// 删除
prizeLogMapper.deleteById(id);
}
private void validatePrizeLogExists(Long id) {
if (prizeLogMapper.selectById(id) == null) {
throw exception(PRIZE_LOG_NOT_EXISTS);
}
}
@Override
public PrizeLogDO getPrizeLog(Long id) {
return prizeLogMapper.selectById(id);
}
@Override
public PageResult<PrizeLogDO> getPrizeLogPage(PrizeLogPageReqVO pageReqVO) {
return prizeLogMapper.selectPage(pageReqVO);
}
@Override
public Long getPrizeLogByMebIdList(Long mebId,PrizeDrawDO prizeDraw) {
return prizeLogMapper.selectCount(new LambdaQueryWrapperX<PrizeLogDO>()
.eq(PrizeLogDO::getMebId, mebId)
.ge(PrizeLogDO::getCreateTime, prizeDraw.getStartTime())
.le(PrizeLogDO::getCreateTime, prizeDraw.getEndTime())
);
}
@Override
public Long getPrizeLogList(PrizeDrawDO prizeDraw,Long prizeId) {
return prizeLogMapper.selectCount(new LambdaQueryWrapperX<PrizeLogDO>()
.eq(PrizeLogDO::getPrizeId,prizeId)
.ge(PrizeLogDO::getCreateTime, prizeDraw.getStartTime())
.le(PrizeLogDO::getCreateTime, prizeDraw.getEndTime())
);
}
@Override
public List<PrizeLogDO> getPrizeLogListByMebId(Long mebId,PrizeDrawDO prizeDraw) {
return prizeLogMapper.selectList(new LambdaQueryWrapperX<PrizeLogDO>()
.eq(PrizeLogDO::getMebId, mebId)
.ge(PrizeLogDO::getCreateTime, prizeDraw.getStartTime())
.le(PrizeLogDO::getCreateTime, prizeDraw.getEndTime())
);
}
}

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.promotion.dal.mysql.prizedraw.PrizeDrawMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.promotion.dal.mysql.prizelog.PrizeLogMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>

@ -0,0 +1,154 @@
package cn.iocoder.yudao.module.promotion.service.prizedraw;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import javax.annotation.Resource;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo.*;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO;
import cn.iocoder.yudao.module.promotion.dal.mysql.prizedraw.PrizeDrawMapper;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import javax.annotation.Resource;
import org.springframework.context.annotation.Import;
import java.util.*;
import java.time.LocalDateTime;
import static cn.hutool.core.util.RandomUtil.*;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
/**
* {@link PrizeDrawServiceImpl}
*
* @author
*/
@Import(PrizeDrawServiceImpl.class)
public class PrizeDrawServiceImplTest extends BaseDbUnitTest {
@Resource
private PrizeDrawServiceImpl prizeDrawService;
@Resource
private PrizeDrawMapper prizeDrawMapper;
@Test
public void testCreatePrizeDraw_success() {
// 准备参数
PrizeDrawSaveReqVO createReqVO = randomPojo(PrizeDrawSaveReqVO.class).setId(null);
// 调用
Long prizeDrawId = prizeDrawService.createPrizeDraw(createReqVO);
// 断言
assertNotNull(prizeDrawId);
// 校验记录的属性是否正确
PrizeDrawDO prizeDraw = prizeDrawMapper.selectById(prizeDrawId);
assertPojoEquals(createReqVO, prizeDraw, "id");
}
@Test
public void testUpdatePrizeDraw_success() {
// mock 数据
PrizeDrawDO dbPrizeDraw = randomPojo(PrizeDrawDO.class);
prizeDrawMapper.insert(dbPrizeDraw);// @Sql: 先插入出一条存在的数据
// 准备参数
PrizeDrawSaveReqVO updateReqVO = randomPojo(PrizeDrawSaveReqVO.class, o -> {
o.setId(dbPrizeDraw.getId()); // 设置更新的 ID
});
// 调用
prizeDrawService.updatePrizeDraw(updateReqVO);
// 校验是否更新正确
PrizeDrawDO prizeDraw = prizeDrawMapper.selectById(updateReqVO.getId()); // 获取最新的
assertPojoEquals(updateReqVO, prizeDraw);
}
@Test
public void testUpdatePrizeDraw_notExists() {
// 准备参数
PrizeDrawSaveReqVO updateReqVO = randomPojo(PrizeDrawSaveReqVO.class);
// 调用, 并断言异常
assertServiceException(() -> prizeDrawService.updatePrizeDraw(updateReqVO), PRIZE_DRAW_NOT_EXISTS);
}
@Test
public void testDeletePrizeDraw_success() {
// mock 数据
PrizeDrawDO dbPrizeDraw = randomPojo(PrizeDrawDO.class);
prizeDrawMapper.insert(dbPrizeDraw);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbPrizeDraw.getId();
// 调用
prizeDrawService.deletePrizeDraw(id);
// 校验数据不存在了
assertNull(prizeDrawMapper.selectById(id));
}
@Test
public void testDeletePrizeDraw_notExists() {
// 准备参数
Long id = randomLongId();
// 调用, 并断言异常
assertServiceException(() -> prizeDrawService.deletePrizeDraw(id), PRIZE_DRAW_NOT_EXISTS);
}
@Test
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
public void testGetPrizeDrawPage() {
// mock 数据
PrizeDrawDO dbPrizeDraw = randomPojo(PrizeDrawDO.class, o -> { // 等会查询到
o.setName(null);
o.setActivityRule(null);
o.setStatus(null);
o.setStartTime(null);
o.setEndTime(null);
o.setMebLevel(null);
o.setCreateTime(null);
});
prizeDrawMapper.insert(dbPrizeDraw);
// 测试 name 不匹配
prizeDrawMapper.insert(cloneIgnoreId(dbPrizeDraw, o -> o.setName(null)));
// 测试 activityRule 不匹配
prizeDrawMapper.insert(cloneIgnoreId(dbPrizeDraw, o -> o.setActivityRule(null)));
// 测试 status 不匹配
prizeDrawMapper.insert(cloneIgnoreId(dbPrizeDraw, o -> o.setStatus(null)));
// 测试 startTime 不匹配
prizeDrawMapper.insert(cloneIgnoreId(dbPrizeDraw, o -> o.setStartTime(null)));
// 测试 endTime 不匹配
prizeDrawMapper.insert(cloneIgnoreId(dbPrizeDraw, o -> o.setEndTime(null)));
// 测试 mebLevel 不匹配
prizeDrawMapper.insert(cloneIgnoreId(dbPrizeDraw, o -> o.setMebLevel(null)));
// 测试 createTime 不匹配
prizeDrawMapper.insert(cloneIgnoreId(dbPrizeDraw, o -> o.setCreateTime(null)));
// 准备参数
PrizeDrawPageReqVO reqVO = new PrizeDrawPageReqVO();
reqVO.setName(null);
reqVO.setActivityRule(null);
reqVO.setStatus(null);
reqVO.setStartTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
reqVO.setEndTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
reqVO.setMebLevel(null);
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
// 调用
PageResult<PrizeDrawDO> pageResult = prizeDrawService.getPrizeDrawPage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbPrizeDraw, pageResult.getList().get(0));
}
}

@ -0,0 +1,162 @@
package cn.iocoder.yudao.module.promotion.service.prizelog;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import javax.annotation.Resource;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.*;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO;
import cn.iocoder.yudao.module.promotion.dal.mysql.prizelog.PrizeLogMapper;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import javax.annotation.Resource;
import org.springframework.context.annotation.Import;
import java.util.*;
import java.time.LocalDateTime;
import static cn.hutool.core.util.RandomUtil.*;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
/**
* {@link PrizeLogServiceImpl}
*
* @author
*/
@Import(PrizeLogServiceImpl.class)
public class PrizeLogServiceImplTest extends BaseDbUnitTest {
@Resource
private PrizeLogServiceImpl prizeLogService;
@Resource
private PrizeLogMapper prizeLogMapper;
@Test
public void testCreatePrizeLog_success() {
// 准备参数
PrizeLogSaveReqVO createReqVO = randomPojo(PrizeLogSaveReqVO.class).setId(null);
// 调用
Long prizeLogId = prizeLogService.createPrizeLog(createReqVO);
// 断言
assertNotNull(prizeLogId);
// 校验记录的属性是否正确
PrizeLogDO prizeLog = prizeLogMapper.selectById(prizeLogId);
assertPojoEquals(createReqVO, prizeLog, "id");
}
@Test
public void testUpdatePrizeLog_success() {
// mock 数据
PrizeLogDO dbPrizeLog = randomPojo(PrizeLogDO.class);
prizeLogMapper.insert(dbPrizeLog);// @Sql: 先插入出一条存在的数据
// 准备参数
PrizeLogSaveReqVO updateReqVO = randomPojo(PrizeLogSaveReqVO.class, o -> {
o.setId(dbPrizeLog.getId()); // 设置更新的 ID
});
// 调用
prizeLogService.updatePrizeLog(updateReqVO);
// 校验是否更新正确
PrizeLogDO prizeLog = prizeLogMapper.selectById(updateReqVO.getId()); // 获取最新的
assertPojoEquals(updateReqVO, prizeLog);
}
@Test
public void testUpdatePrizeLog_notExists() {
// 准备参数
PrizeLogSaveReqVO updateReqVO = randomPojo(PrizeLogSaveReqVO.class);
// 调用, 并断言异常
assertServiceException(() -> prizeLogService.updatePrizeLog(updateReqVO), PRIZE_LOG_NOT_EXISTS);
}
@Test
public void testDeletePrizeLog_success() {
// mock 数据
PrizeLogDO dbPrizeLog = randomPojo(PrizeLogDO.class);
prizeLogMapper.insert(dbPrizeLog);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbPrizeLog.getId();
// 调用
prizeLogService.deletePrizeLog(id);
// 校验数据不存在了
assertNull(prizeLogMapper.selectById(id));
}
@Test
public void testDeletePrizeLog_notExists() {
// 准备参数
Long id = randomLongId();
// 调用, 并断言异常
assertServiceException(() -> prizeLogService.deletePrizeLog(id), PRIZE_LOG_NOT_EXISTS);
}
@Test
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
public void testGetPrizeLogPage() {
// mock 数据
PrizeLogDO dbPrizeLog = randomPojo(PrizeLogDO.class, o -> { // 等会查询到
o.setMebId(null);
o.setActivityId(null);
o.setName(null);
o.setImgUrl(null);
o.setWinNum(null);
o.setPrizeChance(null);
o.setPrizePoolAmount(null);
o.setStatus(null);
o.setCreateTime(null);
});
prizeLogMapper.insert(dbPrizeLog);
// 测试 mebId 不匹配
prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setMebId(null)));
// 测试 activityId 不匹配
prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setActivityId(null)));
// 测试 name 不匹配
prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setName(null)));
// 测试 imgUrl 不匹配
prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setImgUrl(null)));
// 测试 winNum 不匹配
prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setWinNum(null)));
// 测试 prizeChance 不匹配
prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setPrizeChance(null)));
// 测试 prizePoolAmount 不匹配
prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setPrizePoolAmount(null)));
// 测试 status 不匹配
prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setStatus(null)));
// 测试 createTime 不匹配
prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setCreateTime(null)));
// 准备参数
PrizeLogPageReqVO reqVO = new PrizeLogPageReqVO();
reqVO.setMebId(null);
reqVO.setActivityId(null);
reqVO.setName(null);
reqVO.setImgUrl(null);
reqVO.setWinNum(null);
reqVO.setPrizeChance(null);
reqVO.setPrizePoolAmount(null);
reqVO.setStatus(null);
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
// 调用
PageResult<PrizeLogDO> pageResult = prizeLogService.getPrizeLogPage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbPrizeLog, pageResult.getList().get(0));
}
}

@ -10,3 +10,5 @@ DELETE FROM "promotion_article_category";
DELETE FROM "promotion_article"; DELETE FROM "promotion_article";
DELETE FROM "promotion_diy_template"; DELETE FROM "promotion_diy_template";
DELETE FROM "promotion_diy_page"; DELETE FROM "promotion_diy_page";
DELETE FROM "promotion_prize_draw";
DELETE FROM "promotion_prize_log";

@ -254,3 +254,38 @@ CREATE TABLE IF NOT EXISTS "promotion_diy_page"
"tenant_id" bigint NOT NULL, "tenant_id" bigint NOT NULL,
PRIMARY KEY ("id") PRIMARY KEY ("id")
) COMMENT '装修页面'; ) COMMENT '装修页面';
CREATE TABLE IF NOT EXISTS "promotion_prize_draw" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"name" varchar,
"activity_rule" varchar,
"status" varchar,
"start_time" varchar,
"end_time" varchar,
"meb_level" int,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint NOT NULL,
PRIMARY KEY ("id")
) COMMENT '抽奖活动';
CREATE TABLE IF NOT EXISTS "promotion_prize_log" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"meb_id" bigint,
"activity_id" bigint,
"name" varchar,
"img_url" varchar,
"win_num" int,
"prize_chance" varchar,
"prize_pool_amount" varchar,
"status" varchar,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint NOT NULL,
PRIMARY KEY ("id")
) COMMENT '抽奖记录表';

@ -0,0 +1,4 @@
package cn.iocoder.yudao.module.trade.api.order;
public interface TradeOrderItemApi {
}

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.admin.order;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.*; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.*;
@ -31,6 +32,7 @@ import java.util.Set;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.*;
@Tag(name = "管理后台 - 交易订单") @Tag(name = "管理后台 - 交易订单")
@RestController @RestController
@ -153,7 +155,10 @@ public class TradeOrderController {
@Parameter(name = "pickUpVerifyCode", description = "自提核销码") @Parameter(name = "pickUpVerifyCode", description = "自提核销码")
@PreAuthorize("@ss.hasPermission('trade:order:pick-up')") @PreAuthorize("@ss.hasPermission('trade:order:pick-up')")
public CommonResult<Boolean> pickUpOrderByVerifyCode(@RequestParam("pickUpVerifyCode") String pickUpVerifyCode) { public CommonResult<Boolean> pickUpOrderByVerifyCode(@RequestParam("pickUpVerifyCode") String pickUpVerifyCode) {
tradeOrderUpdateService.pickUpOrderByAdmin(pickUpVerifyCode); // 根据管理系统登录用户信息获取APP系统用户信息
String mobile = getLoginUserMobile();
MemberUserRespDTO userByMobile = memberUserApi.getUserByMobile(mobile);
tradeOrderUpdateService.pickUpOrderByAdmin(userByMobile.getId(),pickUpVerifyCode);
return success(true); return success(true);
} }

@ -2,7 +2,9 @@ package cn.iocoder.yudao.module.trade.controller.app.order;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; import cn.iocoder.yudao.module.trade.controller.app.order.vo.*;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
@ -17,6 +19,7 @@ import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleService;
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService; import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
@ -32,6 +35,7 @@ import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "用户 App - 交易订单") @Tag(name = "用户 App - 交易订单")
@ -54,6 +58,9 @@ public class AppTradeOrderController {
@Resource @Resource
private TradeOrderProperties tradeOrderProperties; private TradeOrderProperties tradeOrderProperties;
@Resource
private MemberUserApi memberUserApi;
@GetMapping("/settlement") @GetMapping("/settlement")
@Operation(summary = "获得订单结算信息") @Operation(summary = "获得订单结算信息")
@PreAuthenticated @PreAuthenticated
@ -65,6 +72,9 @@ public class AppTradeOrderController {
@Operation(summary = "创建订单") @Operation(summary = "创建订单")
@PreAuthenticated @PreAuthenticated
public CommonResult<AppTradeOrderCreateRespVO> createOrder(@Valid @RequestBody AppTradeOrderCreateReqVO createReqVO) { public CommonResult<AppTradeOrderCreateRespVO> createOrder(@Valid @RequestBody AppTradeOrderCreateReqVO createReqVO) {
LoginUser loginUser = getLoginUser();
createReqVO.setReceiverName(loginUser.getInfo().getOrDefault("nickname",""));
createReqVO.setReceiverMobile(loginUser.getInfo().getOrDefault("mobile",""));
TradeOrderDO order = tradeOrderUpdateService.createOrder(getLoginUserId(), createReqVO); TradeOrderDO order = tradeOrderUpdateService.createOrder(getLoginUserId(), createReqVO);
return success(new AppTradeOrderCreateRespVO().setId(order.getId()).setPayOrderId(order.getPayOrderId())); return success(new AppTradeOrderCreateRespVO().setId(order.getId()).setPayOrderId(order.getPayOrderId()));
} }
@ -74,6 +84,8 @@ public class AppTradeOrderController {
public CommonResult<Boolean> updateOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) { public CommonResult<Boolean> updateOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) {
tradeOrderUpdateService.updateOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()), tradeOrderUpdateService.updateOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()),
notifyReqDTO.getPayOrderId()); notifyReqDTO.getPayOrderId());
// memberUserApi.updateUserUpgradesLevel();
return success(true); return success(true);
} }
@ -116,6 +128,13 @@ public class AppTradeOrderController {
return success(TradeOrderConvert.INSTANCE.convertPage02(pageResult, orderItems)); return success(TradeOrderConvert.INSTANCE.convertPage02(pageResult, orderItems));
} }
@GetMapping("/getPickUpVerifyCode")
@Operation(summary = "根据订单id获取自提核销码")
public CommonResult<String> getPickUpVerifyCode(String id) {
String pickUpVerifyCode = tradeOrderQueryService.getPickUpVerifyCode(id);
return success(pickUpVerifyCode);
}
@GetMapping("/get-count") @GetMapping("/get-count")
@Operation(summary = "获得交易订单数量") @Operation(summary = "获得交易订单数量")
public CommonResult<Map<String, Long>> getOrderCount() { public CommonResult<Map<String, Long>> getOrderCount() {

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.trade.controller.app.order.vo; package cn.iocoder.yudao.module.trade.controller.app.order.vo;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
@ -45,6 +46,19 @@ public class AppTradeOrderPageItemRespVO {
@Schema(description = "配送方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @Schema(description = "配送方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer deliveryType; private Integer deliveryType;
/**
*
*
* {@link DeliveryPickUpStoreDO#getId()}
*/
@Schema(description = "核销单位id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long pickUpStoreId;
/**
*
*/
@Schema(description = "核销码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private String pickUpVerifyCode;
/** /**
* *
*/ */

@ -59,4 +59,8 @@ public class BrokerageUserDO extends BaseDO {
* *
*/ */
private Integer frozenPrice; private Integer frozenPrice;
/**
*
*/
private Integer level;
} }

@ -130,6 +130,7 @@ public class TradeOrderItemDO extends BaseDO {
*/ */
private Integer payPrice; private Integer payPrice;
// ========== 营销基本信息 ========== // ========== 营销基本信息 ==========
/** /**

@ -53,6 +53,20 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
update(null, lambdaUpdateWrapper); update(null, lambdaUpdateWrapper);
} }
/**
*
*
* @param id
* @param incrCount
*/
default void updateUserPriceByBindUserIdIncr(Long id, Integer incrCount) {
Assert.isTrue(incrCount > 0);
LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
.setSql(" brokerage_price = brokerage_price + " + incrCount)
.eq(BrokerageUserDO::getBindUserId, id);
update(null, lambdaUpdateWrapper);
}
/** /**
* *
* *
@ -69,6 +83,22 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
return update(null, lambdaUpdateWrapper); return update(null, lambdaUpdateWrapper);
} }
/**
*
*
*
* @param id
* @param incrCount
* @return
*/
default int updateUserPriceByBindUserIdDecr(Long id, Integer incrCount) {
Assert.isTrue(incrCount < 0);
LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
.setSql(" brokerage_price = brokerage_price + " + incrCount) // 负数,所以使用 + 号
.eq(BrokerageUserDO::getBindUserId, id);
return update(null, lambdaUpdateWrapper);
}
/** /**
* *
* *

@ -124,4 +124,7 @@ public interface TradeOrderMapper extends BaseMapperX<TradeOrderDO> {
); );
} }
default String getPickUpVerifyCode(String id){
return selectOne(TradeOrderDO::getId, id).getPickUpVerifyCode();
};
} }

@ -76,6 +76,16 @@ public interface BrokerageUserService {
*/ */
boolean updateUserPrice(Long id, Integer price); boolean updateUserPrice(Long id, Integer price);
/**
*
*
* @param id
* @param price
* @return
*/
boolean updateUserPriceByBindUserId(Long id, Integer price);
/** /**
* *
* *

@ -138,6 +138,16 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
return true; return true;
} }
@Override
public boolean updateUserPriceByBindUserId(Long id, Integer price) {
if (price > 0) {
brokerageUserMapper.updateUserPriceByBindUserIdIncr(id, price);
} else if (price < 0) {
return brokerageUserMapper.updateUserPriceByBindUserIdDecr(id, price) > 0;
}
return true;
}
@Override @Override
public void updateUserFrozenPrice(Long id, Integer frozenPrice) { public void updateUserFrozenPrice(Long id, Integer frozenPrice) {
if (frozenPrice > 0) { if (frozenPrice > 0) {

@ -155,4 +155,5 @@ public interface TradeOrderQueryService {
*/ */
List<TradeOrderItemDO> getOrderItemListByOrderId(Collection<Long> orderIds); List<TradeOrderItemDO> getOrderItemListByOrderId(Collection<Long> orderIds);
String getPickUpVerifyCode(String id);
} }

@ -248,6 +248,11 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService {
return tradeOrderItemMapper.selectListByOrderId(orderIds); return tradeOrderItemMapper.selectListByOrderId(orderIds);
} }
@Override
public String getPickUpVerifyCode(String id) {
return tradeOrderMapper.getPickUpVerifyCode(id);
}
/** /**
* AOP * AOP
* *

@ -126,8 +126,9 @@ public interface TradeOrderUpdateService {
* *
* *
* @param pickUpVerifyCode * @param pickUpVerifyCode
* @param id id
*/ */
void pickUpOrderByAdmin(String pickUpVerifyCode); void pickUpOrderByAdmin(Long id, String pickUpVerifyCode);
/** /**
* *

@ -40,6 +40,7 @@ import cn.iocoder.yudao.module.trade.enums.order.*;
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog; import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog;
import cn.iocoder.yudao.module.trade.framework.order.core.utils.TradeOrderLogUtils; import cn.iocoder.yudao.module.trade.framework.order.core.utils.TradeOrderLogUtils;
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService;
import cn.iocoder.yudao.module.trade.service.cart.CartService; import cn.iocoder.yudao.module.trade.service.cart.CartService;
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
import cn.iocoder.yudao.module.trade.service.message.TradeMessageService; import cn.iocoder.yudao.module.trade.service.message.TradeMessageService;
@ -107,6 +108,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
@Resource @Resource
private TradeOrderProperties tradeOrderProperties; private TradeOrderProperties tradeOrderProperties;
@Resource
private BrokerageUserService brokerageUserService;
// =================== Order =================== // =================== Order ===================
@Override @Override
@ -679,7 +684,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
@Override @Override
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.ADMIN_PICK_UP_RECEIVE) @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.ADMIN_PICK_UP_RECEIVE)
public void pickUpOrderByAdmin(String pickUpVerifyCode) { public void pickUpOrderByAdmin(Long id, String pickUpVerifyCode) {
boolean b = brokerageUserService.updateUserPriceByBindUserId(id, 30);
getSelf().pickUpOrder(tradeOrderMapper.selectOneByPickUpVerifyCode(pickUpVerifyCode)); getSelf().pickUpOrder(tradeOrderMapper.selectOneByPickUpVerifyCode(pickUpVerifyCode));
} }

@ -3,6 +3,9 @@ package cn.iocoder.yudao.module.member.api.level;
import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO; import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
import java.util.Collection;
import java.util.List;
/** /**
* API * API
* *
@ -38,4 +41,11 @@ public interface MemberLevelApi {
*/ */
void reduceExperience(Long userId, Integer experience, Integer bizType, String bizId); void reduceExperience(Long userId, Integer experience, Integer bizType, String bizId);
/**
*
*
* @param ids
* @return
*/
List<MemberLevelRespDTO> getLevelList(Collection<Long> ids);
} }

@ -57,4 +57,27 @@ public interface MemberUserApi {
* @return * @return
*/ */
MemberUserRespDTO getUserByMobile(String mobile); MemberUserRespDTO getUserByMobile(String mobile);
/**
*
*
* @param userId
* @return
*/
boolean updateUserLevelId(Long userId);
/**
* 1188
*
* @param userId
* @return
*/
void updateUserUpgradesLevel(Long userId);
/**
*
*
* @param orderId id
* @return
*/
void updateUserUpgradesLevelcallback(Long orderId);
} }

@ -54,5 +54,7 @@ public interface ErrorCodeConstants {
//========== 用户分组 1-004-012-000 ========== //========== 用户分组 1-004-012-000 ==========
ErrorCode GROUP_NOT_EXISTS = new ErrorCode(1_004_012_000, "用户分组不存在"); ErrorCode GROUP_NOT_EXISTS = new ErrorCode(1_004_012_000, "用户分组不存在");
ErrorCode GROUP_HAS_USER = new ErrorCode(1_004_012_001, "用户分组下存在用户,无法删除"); ErrorCode GROUP_HAS_USER = new ErrorCode(1_004_012_001, "用户分组下存在用户,无法删除");
ErrorCode DISTRIBUTION_CONFIG_NOT_EXISTS = new ErrorCode(1_004_012_002, "分销配置不存在");
ErrorCode DISTRIBUTION_LOG_NOT_EXISTS = new ErrorCode(1_004_012_003, "分销记录不存在");
ErrorCode DISTRIBUTION_STATISTICS_NOT_EXISTS = new ErrorCode(1_004_012_004, "分销统计不存在");
} }

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.member.api.level; package cn.iocoder.yudao.module.member.api.level;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO; import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
import cn.iocoder.yudao.module.member.convert.level.MemberLevelConvert; import cn.iocoder.yudao.module.member.convert.level.MemberLevelConvert;
import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
@ -9,6 +10,9 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.EXPERIENCE_BIZ_NOT_SUPPORT; import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.EXPERIENCE_BIZ_NOT_SUPPORT;
@ -43,4 +47,9 @@ public class MemberLevelApiImpl implements MemberLevelApi {
addExperience(userId, -experience, bizType, bizId); addExperience(userId, -experience, bizType, bizId);
} }
@Override
public List<MemberLevelRespDTO> getLevelList(Collection<Long> ids) {
return BeanUtils.toBean(memberLevelService.getLevelList(ids),MemberLevelRespDTO.class);
}
} }

@ -44,4 +44,20 @@ public class MemberUserApiImpl implements MemberUserApi {
return MemberUserConvert.INSTANCE.convert2(userService.getUserByMobile(mobile)); return MemberUserConvert.INSTANCE.convert2(userService.getUserByMobile(mobile));
} }
@Override
public boolean updateUserLevelId(Long userId) {
return userService.updateUserLevelId(userId);
}
@Override
public void updateUserUpgradesLevel(Long userId) {
userService.updateUserUpgradesLevel(userId);
}
@Override
public void updateUserUpgradesLevelcallback(Long orderId) {
userService.updateUserUpgradesLevelcallback(orderId);
}
} }

@ -0,0 +1,125 @@
package cn.iocoder.yudao.module.member.controller.admin.distributionconfig;
import cn.iocoder.yudao.module.member.api.level.MemberLevelApi;
import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
import cn.iocoder.yudao.module.member.convert.distributionconfig.DistributionConfigConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionMebConfigDO;
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import cn.iocoder.yudao.module.member.controller.admin.distributionconfig.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionConfigDO;
import cn.iocoder.yudao.module.member.service.distributionconfig.DistributionConfigService;
@Tag(name = "管理后台 - 分销配置")
@RestController
@RequestMapping("/member/distribution-config")
@Validated
public class DistributionConfigController {
@Resource
private DistributionConfigService distributionConfigService;
@Resource
private MemberLevelApi memberLevelApi;
@Resource
private ProductSpuApi spuApi;
@PostMapping("/create")
@Operation(summary = "创建分销配置")
@PreAuthorize("@ss.hasPermission('member:distribution-config:create')")
public CommonResult<Long> createDistributionConfig(@Valid @RequestBody DistributionConfigSaveReqVO createReqVO) {
return success(distributionConfigService.createDistributionConfig(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新分销配置")
@PreAuthorize("@ss.hasPermission('member:distribution-config:update')")
public CommonResult<Boolean> updateDistributionConfig(@Valid @RequestBody DistributionConfigSaveReqVO updateReqVO) {
distributionConfigService.updateDistributionConfig(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除分销配置")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('member:distribution-config:delete')")
public CommonResult<Boolean> deleteDistributionConfig(@RequestParam("id") Long id) {
distributionConfigService.deleteDistributionConfig(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得分销配置")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('member:distribution-config:query')")
public CommonResult<DistributionConfigRespVO> getDistributionConfig(@RequestParam("id") Long id) {
DistributionConfigDO distributionConfig = distributionConfigService.getDistributionConfig(id);
return success(BeanUtils.toBean(distributionConfig, DistributionConfigRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得分销配置分页")
@PreAuthorize("@ss.hasPermission('member:distribution-config:query')")
public CommonResult<PageResult<DistributionConfigRespVO>> getDistributionConfigPage(@Valid DistributionConfigPageReqVO pageReqVO) {
PageResult<DistributionConfigDO> pageResult = distributionConfigService.getDistributionConfigPage(pageReqVO);
// 处理用户级别返显
List<MemberLevelRespDTO> levels = memberLevelApi.getLevelList(
convertSet(pageResult.getList(), DistributionConfigDO::getLevelId));
// 拼接数据
List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(pageResult.getList(), DistributionConfigDO::getProductId));
return success(DistributionConfigConvert.INSTANCE.convertPage(pageResult, levels,spuList));
// return success(BeanUtils.toBean(pageResult, DistributionConfigRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出分销配置 Excel")
@PreAuthorize("@ss.hasPermission('member:distribution-config:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportDistributionConfigExcel(@Valid DistributionConfigPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<DistributionConfigDO> list = distributionConfigService.getDistributionConfigPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "分销配置.xls", "数据", DistributionConfigRespVO.class,
BeanUtils.toBean(list, DistributionConfigRespVO.class));
}
// ==================== 子表(分销配置关联会员等级) ====================
@GetMapping("/distribution-meb-config/list-by-config-id")
@Operation(summary = "获得分销配置关联会员等级列表")
@Parameter(name = "configId", description = "分销配置id")
@PreAuthorize("@ss.hasPermission('member:distribution-config:query')")
public CommonResult<List<DistributionMebConfigDO>> getDistributionMebConfigListByConfigId(@RequestParam("configId") Long configId) {
return success(distributionConfigService.getDistributionMebConfigListByConfigId(configId));
}
}

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.member.controller.admin.distributionconfig.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 分销配置分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DistributionConfigPageReqVO extends PageParam {
@Schema(description = "分销商品id", example = "18678")
private Long productId;
@Schema(description = "购买人提升会员等级", example = "18678")
private Long levelId;
@Schema(description = "启用状态", example = "2")
private String status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,43 @@
package cn.iocoder.yudao.module.member.controller.admin.distributionconfig.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 分销配置 Response VO")
@Data
@ExcelIgnoreUnannotated
public class DistributionConfigRespVO {
@Schema(description = "id主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "16387")
@ExcelProperty("id主键")
private Long id;
@Schema(description = "分销商品id", example = "18678")
@ExcelProperty("分销商品id")
private Long productId;
@Schema(description = "购买人提升会员等级", example = "18678")
@ExcelProperty("购买人提升会员等级")
private Long levelId;
@Schema(description = "启用状态", example = "2")
@ExcelProperty("启用状态")
private String status;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "购买人提升会员等级", example = "18678")
@ExcelProperty("购买人提升会员等级")
private String levelName;
@Schema(description = "商品名称", example = "18678")
@ExcelProperty("商品名称")
private String supName;
}

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.member.controller.admin.distributionconfig.vo;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionMebConfigDO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 分销配置新增/修改 Request VO")
@Data
public class DistributionConfigSaveReqVO {
@Schema(description = "id主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "16387")
private Long id;
@Schema(description = "分销商品id", example = "18678")
private Long productId;
@Schema(description = "购买人提升会员等级", example = "18678")
private Long levelId;
@Schema(description = "启用状态", example = "2")
private String status;
@Schema(description = "分销配置关联会员等级列表")
private List<DistributionMebConfigDO> distributionMebConfigs;
}

@ -0,0 +1,108 @@
package cn.iocoder.yudao.module.member.controller.admin.distributionlog;
import cn.iocoder.yudao.module.member.convert.distributionlog.DistributionLogConvert;
import cn.iocoder.yudao.module.member.convert.signin.MemberSignInRecordConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import cn.iocoder.yudao.module.member.controller.admin.distributionlog.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionlog.DistributionLogDO;
import cn.iocoder.yudao.module.member.service.distributionlog.DistributionLogService;
@Tag(name = "管理后台 - 分销记录")
@RestController
@RequestMapping("/member/distribution-log")
@Validated
public class DistributionLogController {
@Resource
private DistributionLogService distributionLogService;
@Resource
private MemberUserService memberUserService;
@PostMapping("/create")
@Operation(summary = "创建分销记录")
@PreAuthorize("@ss.hasPermission('member:distribution-log:create')")
public CommonResult<Long> createDistributionLog(@Valid @RequestBody DistributionLogSaveReqVO createReqVO) {
return success(distributionLogService.createDistributionLog(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新分销记录")
@PreAuthorize("@ss.hasPermission('member:distribution-log:update')")
public CommonResult<Boolean> updateDistributionLog(@Valid @RequestBody DistributionLogSaveReqVO updateReqVO) {
distributionLogService.updateDistributionLog(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除分销记录")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('member:distribution-log:delete')")
public CommonResult<Boolean> deleteDistributionLog(@RequestParam("id") Long id) {
distributionLogService.deleteDistributionLog(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得分销记录")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('member:distribution-log:query')")
public CommonResult<DistributionLogRespVO> getDistributionLog(@RequestParam("id") Long id) {
DistributionLogDO distributionLog = distributionLogService.getDistributionLog(id);
return success(BeanUtils.toBean(distributionLog, DistributionLogRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得分销记录分页")
@PreAuthorize("@ss.hasPermission('member:distribution-log:query')")
public CommonResult<PageResult<DistributionLogRespVO>> getDistributionLogPage(@Valid DistributionLogPageReqVO pageReqVO) {
pageReqVO.setGameStatus("0");
PageResult<DistributionLogDO> pageResult = distributionLogService.getDistributionLogPage(pageReqVO);
// 拼接结果返回
List<MemberUserDO> users = memberUserService.getUserList(
convertSet(pageResult.getList(), DistributionLogDO::getMebId));
return success(DistributionLogConvert.INSTANCE.convertPage(pageResult, users));
}
@GetMapping("/export-excel")
@Operation(summary = "导出分销记录 Excel")
@PreAuthorize("@ss.hasPermission('member:distribution-log:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportDistributionLogExcel(@Valid DistributionLogPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<DistributionLogDO> list = distributionLogService.getDistributionLogPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "分销记录.xls", "数据", DistributionLogRespVO.class,
BeanUtils.toBean(list, DistributionLogRespVO.class));
}
}

@ -0,0 +1,46 @@
package cn.iocoder.yudao.module.member.controller.admin.distributionlog.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 分销记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DistributionLogPageReqVO extends PageParam {
@Schema(description = "推荐人id", example = "5267")
private Long referrerId;
@Schema(description = "推荐人id(便于回溯)", example = "23906")
private Long oldReferrerId;
@Schema(description = "购买人id", example = "6637")
private Long mebId;
@Schema(description = "佣金")
private Integer brokerage;
@Schema(description = "分佣结算核销状态", example = "2")
private String status;
@Schema(description = "游戏状态", example = "2")
private String gameStatus;
@Schema(description = "游戏兑换状态", example = "1")
private String convertStatus;
@Schema(description = "推荐人会员等级id", example = "10242")
private Long levelId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,67 @@
package cn.iocoder.yudao.module.member.controller.admin.distributionlog.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 分销记录 Response VO")
@Data
@ExcelIgnoreUnannotated
public class DistributionLogRespVO {
@Schema(description = "id主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "4693")
@ExcelProperty("id主键")
private Long id;
@Schema(description = "推荐人id", example = "5267")
@ExcelProperty("推荐人id")
private Long referrerId;
@Schema(description = "推荐人id(便于回溯)", example = "23906")
@ExcelProperty("推荐人id(便于回溯)")
private Long oldReferrerId;
@Schema(description = "购买人id", example = "6637")
@ExcelProperty("购买人id")
private Long mebId;
@Schema(description = "佣金")
@ExcelProperty("佣金")
private Integer brokerage;
@Schema(description = "分佣结算核销状态", example = "2")
@ExcelProperty("分佣结算核销状态")
private String status;
@Schema(description = "游戏状态", example = "2")
@ExcelProperty("游戏状态")
private String gameStatus;
@Schema(description = "游戏兑换状态", example = "1")
@ExcelProperty("游戏兑换状态")
private String convertStatus;
@Schema(description = "推荐人会员等级id", example = "10242")
@ExcelProperty("推荐人会员等级id")
private Long levelId;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "用户昵称", example = "2")
@ExcelProperty("用户昵称")
private String nickname;
@Schema(description = "用户名称", example = "2")
@ExcelProperty("用户名称")
private String userName;
@Schema(description = "手机号", example = "2")
@ExcelProperty("手机号")
private String phone;
}

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.member.controller.admin.distributionlog.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 分销记录新增/修改 Request VO")
@Data
public class DistributionLogSaveReqVO {
@Schema(description = "id主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "4693")
private Long id;
@Schema(description = "推荐人id", example = "5267")
private Long referrerId;
@Schema(description = "推荐人id(便于回溯)", example = "23906")
private Long oldReferrerId;
@Schema(description = "购买人id", example = "6637")
private Long mebId;
@Schema(description = "佣金")
private Integer brokerage;
@Schema(description = "分佣结算核销状态", example = "2")
private String status;
@Schema(description = "游戏状态", example = "2")
private String gameStatus;
@Schema(description = "游戏兑换状态", example = "1")
private String convertStatus;
@Schema(description = "推荐人会员等级id", example = "10242")
private Long levelId;
}

@ -0,0 +1,124 @@
package cn.iocoder.yudao.module.member.controller.admin.distributionstatistics;
import cn.iocoder.yudao.module.member.api.level.MemberLevelApi;
import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
import cn.iocoder.yudao.module.member.convert.distributionlog.DistributionLogConvert;
import cn.iocoder.yudao.module.member.convert.distributionstatistics.DistributionStatisticsConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionConfigDO;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionlog.DistributionLogDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import cn.iocoder.yudao.module.member.controller.admin.distributionstatistics.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionstatistics.DistributionStatisticsDO;
import cn.iocoder.yudao.module.member.service.distributionstatistics.DistributionStatisticsService;
@Tag(name = "管理后台 - 分销统计")
@RestController
@RequestMapping("/member/distribution-statistics")
@Validated
public class DistributionStatisticsController {
@Resource
private DistributionStatisticsService distributionStatisticsService;
@Resource
private MemberUserService memberUserService;
@Resource
private MemberLevelApi memberLevelApi;
@PostMapping("/create")
@Operation(summary = "创建分销统计")
@PreAuthorize("@ss.hasPermission('member:distribution-statistics:create')")
public CommonResult<Long> createDistributionStatistics(@Valid @RequestBody DistributionStatisticsSaveReqVO createReqVO) {
return success(distributionStatisticsService.createDistributionStatistics(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新分销统计")
@PreAuthorize("@ss.hasPermission('member:distribution-statistics:update')")
public CommonResult<Boolean> updateDistributionStatistics(@Valid @RequestBody DistributionStatisticsSaveReqVO updateReqVO) {
distributionStatisticsService.updateDistributionStatistics(updateReqVO);
return success(true);
}
@PutMapping("/updateAlready")
@Operation(summary = "结算分销统计")
@PreAuthorize("@ss.hasPermission('member:distribution-statistics:update')")
public CommonResult<Boolean> updateAlready(@Valid @RequestBody DistributionStatisticsSaveReqVO updateReqVO) {
distributionStatisticsService.updateAlready(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除分销统计")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('member:distribution-statistics:delete')")
public CommonResult<Boolean> deleteDistributionStatistics(@RequestParam("id") Long id) {
distributionStatisticsService.deleteDistributionStatistics(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得分销统计")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('member:distribution-statistics:query')")
public CommonResult<DistributionStatisticsRespVO> getDistributionStatistics(@RequestParam("id") Long id) {
DistributionStatisticsDO distributionStatistics = distributionStatisticsService.getDistributionStatistics(id);
return success(BeanUtils.toBean(distributionStatistics, DistributionStatisticsRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得分销统计分页")
@PreAuthorize("@ss.hasPermission('member:distribution-statistics:query')")
public CommonResult<PageResult<DistributionStatisticsRespVO>> getDistributionStatisticsPage(@Valid DistributionStatisticsPageReqVO pageReqVO) {
PageResult<DistributionStatisticsRespVO> pageResult = distributionStatisticsService.getDistributionStatisticsPage1(pageReqVO);
// 拼接结果返回
// 处理用户级别返显
List<MemberLevelRespDTO> levels = memberLevelApi.getLevelList(
convertSet(pageResult.getList(), DistributionStatisticsRespVO::getLevelId));
List<MemberUserDO> users = memberUserService.getUserList(
convertSet(pageResult.getList(), DistributionStatisticsRespVO::getMebId));
return success(DistributionStatisticsConvert.INSTANCE.convertPage(pageResult, users,levels));
}
@GetMapping("/export-excel")
@Operation(summary = "导出分销统计 Excel")
@PreAuthorize("@ss.hasPermission('member:distribution-statistics:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportDistributionStatisticsExcel(@Valid DistributionStatisticsPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<DistributionStatisticsDO> list = distributionStatisticsService.getDistributionStatisticsPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "分销统计.xls", "数据", DistributionStatisticsRespVO.class,
BeanUtils.toBean(list, DistributionStatisticsRespVO.class));
}
}

@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.member.controller.admin.distributionstatistics.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 分销统计分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DistributionStatisticsPageReqVO extends PageParam {
@Schema(description = "会员等级id", example = "19012")
private Long levelId;
@Schema(description = "会员id", example = "10495")
private Long mebId;
@Schema(description = "推荐记录id", example = "5711")
private Long logId;
@Schema(description = "推荐人id", example = "2750")
private Long referrerId;
@Schema(description = "分佣结算核销状态", example = "1")
private String status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,70 @@
package cn.iocoder.yudao.module.member.controller.admin.distributionstatistics.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 分销统计 Response VO")
@Data
@ExcelIgnoreUnannotated
public class DistributionStatisticsRespVO {
@Schema(description = "id主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "25196")
@ExcelProperty("id主键")
private Long id;
@Schema(description = "会员等级id", example = "19012")
@ExcelProperty("会员等级id")
private Long levelId;
@Schema(description = "会员id", example = "10495")
@ExcelProperty("会员id")
private Long mebId;
@Schema(description = "推荐记录id", example = "5711")
@ExcelProperty("推荐记录id")
private Long logId;
@Schema(description = "推荐人id", example = "2750")
@ExcelProperty("推荐人id")
private Long referrerId;
@Schema(description = "分佣结算核销状态", example = "1")
@ExcelProperty("分佣结算核销状态")
private String status;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "用户昵称", example = "2")
@ExcelProperty("用户昵称")
private String nickname;
@Schema(description = "用户名称", example = "2")
@ExcelProperty("用户名称")
private String userName;
@Schema(description = "手机号", example = "2")
@ExcelProperty("手机号")
private String phone;
@Schema(description = "会员等级", example = "2")
@ExcelProperty("会员等级")
private String levelName;
@Schema(description = "已结算", example = "2")
@ExcelProperty("已结算")
private Integer haveAlready;
@Schema(description = "未结算", example = "2")
@ExcelProperty("未结算")
private Integer unAlready;
}

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.member.controller.admin.distributionstatistics.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 分销统计新增/修改 Request VO")
@Data
public class DistributionStatisticsSaveReqVO {
@Schema(description = "id主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "25196")
private Long id;
@Schema(description = "会员等级id", example = "19012")
private Long levelId;
@Schema(description = "会员id", example = "10495")
private Long mebId;
@Schema(description = "推荐记录id", example = "5711")
private Long logId;
@Schema(description = "推荐人id", example = "2750")
private Long referrerId;
@Schema(description = "分佣结算核销状态", example = "1")
private String status;
}

@ -0,0 +1,40 @@
package cn.iocoder.yudao.module.member.convert.distributionconfig;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
import cn.iocoder.yudao.module.member.controller.admin.distributionconfig.vo.DistributionConfigRespVO;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionConfigDO;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
@Mapper
public interface DistributionConfigConvert {
DistributionConfigConvert INSTANCE = Mappers.getMapper(DistributionConfigConvert.class);
default PageResult<DistributionConfigRespVO> convertPage(PageResult<DistributionConfigDO> page,
List<MemberLevelRespDTO> levels
, List<ProductSpuRespDTO> spuList) {
PageResult<DistributionConfigRespVO> pageResult = convertPage(page);
Map<Long, String> levelMap = convertMap(levels, MemberLevelRespDTO::getId, MemberLevelRespDTO::getName);
// 拼接关联属性
Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
// 拼接数据
pageResult.getList().forEach(record ->{
findAndThen(spuMap, record.getProductId(), spu -> {
record.setSupName(spu.getName());
});
MapUtils.findAndThen(levelMap, record.getLevelId(),
level -> record.setLevelName(levelMap.get(record.getLevelId())));
});
return pageResult;
}
PageResult<DistributionConfigRespVO> convertPage(PageResult<DistributionConfigDO> page);
}

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.member.convert.distributionlog;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
import cn.iocoder.yudao.module.member.controller.admin.distributionconfig.vo.DistributionConfigRespVO;
import cn.iocoder.yudao.module.member.controller.admin.distributionlog.vo.DistributionLogRespVO;
import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordRespVO;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionConfigDO;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionlog.DistributionLogDO;
import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
@Mapper
public interface DistributionLogConvert {
DistributionLogConvert INSTANCE = Mappers.getMapper(DistributionLogConvert.class);
default PageResult<DistributionLogRespVO> convertPage(PageResult<DistributionLogDO> pageResult, List<MemberUserDO> users) {
PageResult<DistributionLogRespVO> voPageResult = convertPage(pageResult);
// user 拼接
Map<Long, MemberUserDO> userMap = convertMap(users, MemberUserDO::getId);
voPageResult.getList().forEach(record -> MapUtils.findAndThen(userMap, record.getMebId(),
memberUserRespDTO -> record.setNickname(memberUserRespDTO.getNickname()).setUserName(memberUserRespDTO.getName()).setPhone(memberUserRespDTO.getMobile())));
return voPageResult;
}
PageResult<DistributionLogRespVO> convertPage(PageResult<DistributionLogDO> page);
}

@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.member.convert.distributionstatistics;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
import cn.iocoder.yudao.module.member.controller.admin.distributionconfig.vo.DistributionConfigRespVO;
import cn.iocoder.yudao.module.member.controller.admin.distributionlog.vo.DistributionLogRespVO;
import cn.iocoder.yudao.module.member.controller.admin.distributionstatistics.vo.DistributionStatisticsRespVO;
import cn.iocoder.yudao.module.member.convert.distributionlog.DistributionLogConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionConfigDO;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionlog.DistributionLogDO;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionstatistics.DistributionStatisticsDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
@Mapper
public interface DistributionStatisticsConvert {
DistributionStatisticsConvert INSTANCE = Mappers.getMapper(DistributionStatisticsConvert.class);
default PageResult<DistributionStatisticsRespVO> convertPage(PageResult<DistributionStatisticsRespVO> pageResult, List<MemberUserDO> users,List<MemberLevelRespDTO> levels) {
PageResult<DistributionStatisticsRespVO> voPageResult = convertPage(pageResult);
// user 拼接
Map<Long, MemberUserDO> userMap = convertMap(users, MemberUserDO::getId);
Map<Long, String> levelMap = convertMap(levels, MemberLevelRespDTO::getId, MemberLevelRespDTO::getName);
voPageResult.getList().forEach(record -> {
MapUtils.findAndThen(userMap, record.getMebId(),
memberUserRespDTO -> record.setNickname(memberUserRespDTO.getNickname()).setUserName(memberUserRespDTO.getName()).setPhone(memberUserRespDTO.getMobile()));
MapUtils.findAndThen(levelMap, record.getLevelId(),
level -> record.setLevelName(levelMap.get(record.getLevelId())));
});
return voPageResult;
}
PageResult<DistributionStatisticsRespVO> convertPage(PageResult<DistributionStatisticsRespVO> page);
}

@ -29,6 +29,7 @@ public interface MemberUserConvert {
@Mapping(source = "level", target = "level") @Mapping(source = "level", target = "level")
@Mapping(source = "bean.experience", target = "experience") @Mapping(source = "bean.experience", target = "experience")
@Mapping(source = "bean.id",target = "id")
AppMemberUserInfoRespVO convert(MemberUserDO bean, MemberLevelDO level); AppMemberUserInfoRespVO convert(MemberUserDO bean, MemberLevelDO level);
MemberUserRespDTO convert2(MemberUserDO bean); MemberUserRespDTO convert2(MemberUserDO bean);

@ -0,0 +1,43 @@
package cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* DO
*
* @author
*/
@TableName("member_distribution_config")
@KeySequence("member_distribution_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DistributionConfigDO extends BaseDO {
/**
* id
*/
@TableId
private Long id;
/**
* id
*/
private Long productId;
/**
*
*/
private String status;
/**
*
*/
private Long levelId;
}

@ -0,0 +1,43 @@
package cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* DO
*
* @author
*/
@TableName("member_distribution_meb_config")
@KeySequence("member_distribution_meb_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DistributionMebConfigDO extends BaseDO {
/**
* id
*/
@TableId
private Long id;
/**
* id
*/
private Long configId;
/**
*
*/
private Long levelId;
/**
*
*/
private Integer brokerage;
}

@ -0,0 +1,63 @@
package cn.iocoder.yudao.module.member.dal.dataobject.distributionlog;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* DO
*
* @author
*/
@TableName("member_distribution_log")
@KeySequence("member_distribution_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DistributionLogDO extends BaseDO {
/**
* id
*/
@TableId
private Long id;
/**
* id
*/
private Long referrerId;
/**
* id(便)
*/
private Long oldReferrerId;
/**
* id
*/
private Long mebId;
/**
*
*/
private Integer brokerage;
/**
*
*/
private String status;
/**
*
*/
private String gameStatus;
/**
*
*/
private String convertStatus;
/**
* id
*/
private Long levelId;
}

@ -0,0 +1,51 @@
package cn.iocoder.yudao.module.member.dal.dataobject.distributionstatistics;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* DO
*
* @author
*/
@TableName("member_distribution_statistics")
@KeySequence("member_distribution_statistics_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DistributionStatisticsDO extends BaseDO {
/**
* id
*/
@TableId
private Long id;
/**
* id
*/
private Long levelId;
/**
* id
*/
private Long mebId;
/**
* id
*/
private Long logId;
/**
* id
*/
private Long referrerId;
/**
*
*/
private String status;
}

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.member.dal.mysql.distributionconfig;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionConfigDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.member.controller.admin.distributionconfig.vo.*;
/**
* Mapper
*
* @author
*/
@Mapper
public interface DistributionConfigMapper extends BaseMapperX<DistributionConfigDO> {
default PageResult<DistributionConfigDO> selectPage(DistributionConfigPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<DistributionConfigDO>()
.eqIfPresent(DistributionConfigDO::getProductId, reqVO.getProductId())
.eqIfPresent(DistributionConfigDO::getStatus, reqVO.getStatus())
.betweenIfPresent(DistributionConfigDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(DistributionConfigDO::getId));
}
}

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.member.dal.mysql.distributionconfig;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionMebConfigDO;
import org.apache.ibatis.annotations.Mapper;
/**
* Mapper
*
* @author
*/
@Mapper
public interface DistributionMebConfigMapper extends BaseMapperX<DistributionMebConfigDO> {
default List<DistributionMebConfigDO> selectListByConfigId(Long configId) {
return selectList(DistributionMebConfigDO::getConfigId, configId);
}
default int deleteByConfigId(Long configId) {
return delete(DistributionMebConfigDO::getConfigId, configId);
}
}

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.member.dal.mysql.distributionlog;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionlog.DistributionLogDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.member.controller.admin.distributionlog.vo.*;
/**
* Mapper
*
* @author
*/
@Mapper
public interface DistributionLogMapper extends BaseMapperX<DistributionLogDO> {
default PageResult<DistributionLogDO> selectPage(DistributionLogPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<DistributionLogDO>()
.eqIfPresent(DistributionLogDO::getReferrerId, reqVO.getReferrerId())
.eqIfPresent(DistributionLogDO::getOldReferrerId, reqVO.getOldReferrerId())
.eqIfPresent(DistributionLogDO::getMebId, reqVO.getMebId())
.eqIfPresent(DistributionLogDO::getBrokerage, reqVO.getBrokerage())
.eqIfPresent(DistributionLogDO::getStatus, reqVO.getStatus())
.eqIfPresent(DistributionLogDO::getGameStatus, reqVO.getGameStatus())
.eqIfPresent(DistributionLogDO::getConvertStatus, reqVO.getConvertStatus())
.eqIfPresent(DistributionLogDO::getLevelId, reqVO.getLevelId())
.betweenIfPresent(DistributionLogDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(DistributionLogDO::getId));
}
}

@ -0,0 +1,55 @@
package cn.iocoder.yudao.module.member.dal.mysql.distributionstatistics;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionstatistics.DistributionStatisticsDO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.member.controller.admin.distributionstatistics.vo.*;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/**
* Mapper
*
* @author
*/
@Mapper
public interface DistributionStatisticsMapper extends BaseMapperX<DistributionStatisticsDO> {
default PageResult<DistributionStatisticsDO> selectPage(DistributionStatisticsPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<DistributionStatisticsDO>()
.eqIfPresent(DistributionStatisticsDO::getLevelId, reqVO.getLevelId())
.eqIfPresent(DistributionStatisticsDO::getMebId, reqVO.getMebId())
.eqIfPresent(DistributionStatisticsDO::getLogId, reqVO.getLogId())
.eqIfPresent(DistributionStatisticsDO::getReferrerId, reqVO.getReferrerId())
.eqIfPresent(DistributionStatisticsDO::getStatus, reqVO.getStatus())
.betweenIfPresent(DistributionStatisticsDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(DistributionStatisticsDO::getId));
}
@Select({"<script>",
"SELECT\n" +
"\ts.meb_id,\n" +
"\ts.level_id,\n" +
"\tsum( CASE WHEN s.STATUS = 0 THEN 1 ELSE 0 END ) AS 'have_already',\n" +
"\tsum( CASE WHEN s.STATUS = 1 THEN 1 ELSE 0 END ) AS 'un_already' \n" +
"FROM\n" +
"\tmember_distribution_statistics s",
"where s.deleted = FALSE ",
"<if test='status !=null and status!=\"\" '>" ,
" and s.status = #{status}" ,
"</if> ",
"GROUP BY\n" +
"\ts.meb_id,\n" +
"\ts.level_id",
"order BY\n" +
"\ts.meb_id,\n" +
"\ts.level_id",
"</script>"})
IPage<DistributionStatisticsRespVO> selectPage1(IPage<?> page, @Param("status") String status);
}

@ -0,0 +1,66 @@
package cn.iocoder.yudao.module.member.service.distributionconfig;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.member.controller.admin.distributionconfig.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionConfigDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionMebConfigDO;
/**
* Service
*
* @author
*/
public interface DistributionConfigService {
/**
*
*
* @param createReqVO
* @return
*/
Long createDistributionConfig(@Valid DistributionConfigSaveReqVO createReqVO);
/**
*
*
* @param updateReqVO
*/
void updateDistributionConfig(@Valid DistributionConfigSaveReqVO updateReqVO);
/**
*
*
* @param id
*/
void deleteDistributionConfig(Long id);
/**
*
*
* @param id
* @return
*/
DistributionConfigDO getDistributionConfig(Long id);
/**
*
*
* @param pageReqVO
* @return
*/
PageResult<DistributionConfigDO> getDistributionConfigPage(DistributionConfigPageReqVO pageReqVO);
// ==================== 子表(分销配置关联会员等级) ====================
/**
*
*
* @param configId id
* @return
*/
List<DistributionMebConfigDO> getDistributionMebConfigListByConfigId(Long configId);
}

@ -0,0 +1,112 @@
package cn.iocoder.yudao.module.member.service.distributionconfig;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionMebConfigDO;
import cn.iocoder.yudao.module.member.dal.mysql.distributionconfig.DistributionMebConfigMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.iocoder.yudao.module.member.controller.admin.distributionconfig.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionConfigDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.dal.mysql.distributionconfig.DistributionConfigMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
/**
* Service
*
* @author
*/
@Service
@Validated
public class DistributionConfigServiceImpl implements DistributionConfigService {
@Resource
private DistributionConfigMapper distributionConfigMapper;
@Resource
private DistributionMebConfigMapper distributionMebConfigMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createDistributionConfig(DistributionConfigSaveReqVO createReqVO) {
// 插入
DistributionConfigDO distributionConfig = BeanUtils.toBean(createReqVO, DistributionConfigDO.class);
distributionConfigMapper.insert(distributionConfig);
// 插入子表
createDistributionMebConfigList(distributionConfig.getId(), createReqVO.getDistributionMebConfigs());
// 返回
return distributionConfig.getId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateDistributionConfig(DistributionConfigSaveReqVO updateReqVO) {
// 校验存在
validateDistributionConfigExists(updateReqVO.getId());
// 更新
DistributionConfigDO updateObj = BeanUtils.toBean(updateReqVO, DistributionConfigDO.class);
distributionConfigMapper.updateById(updateObj);
// 更新子表
updateDistributionMebConfigList(updateReqVO.getId(), updateReqVO.getDistributionMebConfigs());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteDistributionConfig(Long id) {
// 校验存在
validateDistributionConfigExists(id);
// 删除
distributionConfigMapper.deleteById(id);
// 删除子表
deleteDistributionMebConfigByConfigId(id);
}
private void validateDistributionConfigExists(Long id) {
if (distributionConfigMapper.selectById(id) == null) {
throw exception(DISTRIBUTION_CONFIG_NOT_EXISTS);
}
}
@Override
public DistributionConfigDO getDistributionConfig(Long id) {
return distributionConfigMapper.selectById(id);
}
@Override
public PageResult<DistributionConfigDO> getDistributionConfigPage(DistributionConfigPageReqVO pageReqVO) {
return distributionConfigMapper.selectPage(pageReqVO);
}
// ==================== 子表(分销配置关联会员等级) ====================
@Override
public List<DistributionMebConfigDO> getDistributionMebConfigListByConfigId(Long configId) {
return distributionMebConfigMapper.selectListByConfigId(configId);
}
private void createDistributionMebConfigList(Long configId, List<DistributionMebConfigDO> list) {
list.forEach(o -> o.setConfigId(configId));
distributionMebConfigMapper.insertBatch(list);
}
private void updateDistributionMebConfigList(Long configId, List<DistributionMebConfigDO> list) {
deleteDistributionMebConfigByConfigId(configId);
list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下1id 冲突2updateTime 不更新
createDistributionMebConfigList(configId, list);
}
private void deleteDistributionMebConfigByConfigId(Long configId) {
distributionMebConfigMapper.deleteByConfigId(configId);
}
}

@ -0,0 +1,55 @@
package cn.iocoder.yudao.module.member.service.distributionlog;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.member.controller.admin.distributionlog.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionlog.DistributionLogDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
/**
* Service
*
* @author
*/
public interface DistributionLogService {
/**
*
*
* @param createReqVO
* @return
*/
Long createDistributionLog(@Valid DistributionLogSaveReqVO createReqVO);
/**
*
*
* @param updateReqVO
*/
void updateDistributionLog(@Valid DistributionLogSaveReqVO updateReqVO);
/**
*
*
* @param id
*/
void deleteDistributionLog(Long id);
/**
*
*
* @param id
* @return
*/
DistributionLogDO getDistributionLog(Long id);
/**
*
*
* @param pageReqVO
* @return
*/
PageResult<DistributionLogDO> getDistributionLogPage(DistributionLogPageReqVO pageReqVO);
}

@ -0,0 +1,74 @@
package cn.iocoder.yudao.module.member.service.distributionlog;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.iocoder.yudao.module.member.controller.admin.distributionlog.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionlog.DistributionLogDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.dal.mysql.distributionlog.DistributionLogMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
/**
* Service
*
* @author
*/
@Service
@Validated
public class DistributionLogServiceImpl implements DistributionLogService {
@Resource
private DistributionLogMapper distributionLogMapper;
@Override
public Long createDistributionLog(DistributionLogSaveReqVO createReqVO) {
// 插入
DistributionLogDO distributionLog = BeanUtils.toBean(createReqVO, DistributionLogDO.class);
distributionLogMapper.insert(distributionLog);
// 返回
return distributionLog.getId();
}
@Override
public void updateDistributionLog(DistributionLogSaveReqVO updateReqVO) {
// 校验存在
validateDistributionLogExists(updateReqVO.getId());
// 更新
DistributionLogDO updateObj = BeanUtils.toBean(updateReqVO, DistributionLogDO.class);
distributionLogMapper.updateById(updateObj);
}
@Override
public void deleteDistributionLog(Long id) {
// 校验存在
validateDistributionLogExists(id);
// 删除
distributionLogMapper.deleteById(id);
}
private void validateDistributionLogExists(Long id) {
if (distributionLogMapper.selectById(id) == null) {
throw exception(DISTRIBUTION_LOG_NOT_EXISTS);
}
}
@Override
public DistributionLogDO getDistributionLog(Long id) {
return distributionLogMapper.selectById(id);
}
@Override
public PageResult<DistributionLogDO> getDistributionLogPage(DistributionLogPageReqVO pageReqVO) {
return distributionLogMapper.selectPage(pageReqVO);
}
}

@ -0,0 +1,68 @@
package cn.iocoder.yudao.module.member.service.distributionstatistics;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.member.controller.admin.distributionstatistics.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionstatistics.DistributionStatisticsDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
/**
* Service
*
* @author
*/
public interface DistributionStatisticsService {
/**
*
*
* @param createReqVO
* @return
*/
Long createDistributionStatistics(@Valid DistributionStatisticsSaveReqVO createReqVO);
/**
*
*
* @param updateReqVO
*/
void updateDistributionStatistics(@Valid DistributionStatisticsSaveReqVO updateReqVO);
/**
*
*
* @param updateReqVO
*/
void updateAlready(@Valid DistributionStatisticsSaveReqVO updateReqVO);
/**
*
*
* @param id
*/
void deleteDistributionStatistics(Long id);
/**
*
*
* @param id
* @return
*/
DistributionStatisticsDO getDistributionStatistics(Long id);
/**
*
*
* @param pageReqVO
* @return
*/
PageResult<DistributionStatisticsDO> getDistributionStatisticsPage(DistributionStatisticsPageReqVO pageReqVO);
/**
*
*
* @param pageReqVO
* @return
*/
PageResult<DistributionStatisticsRespVO> getDistributionStatisticsPage1(DistributionStatisticsPageReqVO pageReqVO);
}

@ -0,0 +1,96 @@
package cn.iocoder.yudao.module.member.service.distributionstatistics;
import cn.hutool.core.util.ArrayUtil;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.iocoder.yudao.module.member.controller.admin.distributionstatistics.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionstatistics.DistributionStatisticsDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.dal.mysql.distributionstatistics.DistributionStatisticsMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
/**
* Service
*
* @author
*/
@Service
@Validated
public class DistributionStatisticsServiceImpl implements DistributionStatisticsService {
@Resource
private DistributionStatisticsMapper distributionStatisticsMapper;
@Override
public Long createDistributionStatistics(DistributionStatisticsSaveReqVO createReqVO) {
// 插入
DistributionStatisticsDO distributionStatistics = BeanUtils.toBean(createReqVO, DistributionStatisticsDO.class);
distributionStatisticsMapper.insert(distributionStatistics);
// 返回
return distributionStatistics.getId();
}
@Override
public void updateDistributionStatistics(DistributionStatisticsSaveReqVO updateReqVO) {
// 校验存在
validateDistributionStatisticsExists(updateReqVO.getId());
// 更新
DistributionStatisticsDO updateObj = BeanUtils.toBean(updateReqVO, DistributionStatisticsDO.class);
distributionStatisticsMapper.updateById(updateObj);
}
@Override
public void updateAlready(DistributionStatisticsSaveReqVO updateReqVO) {
// 结算
distributionStatisticsMapper.update(new UpdateWrapper<DistributionStatisticsDO>().lambda().set(DistributionStatisticsDO::getStatus,0).eq(DistributionStatisticsDO::getMebId,updateReqVO.getMebId()).eq(DistributionStatisticsDO::getLevelId,updateReqVO.getLevelId()));
}
@Override
public void deleteDistributionStatistics(Long id) {
// 校验存在
validateDistributionStatisticsExists(id);
// 删除
distributionStatisticsMapper.deleteById(id);
}
private void validateDistributionStatisticsExists(Long id) {
if (distributionStatisticsMapper.selectById(id) == null) {
throw exception(DISTRIBUTION_STATISTICS_NOT_EXISTS);
}
}
@Override
public DistributionStatisticsDO getDistributionStatistics(Long id) {
return distributionStatisticsMapper.selectById(id);
}
@Override
public PageResult<DistributionStatisticsDO> getDistributionStatisticsPage(DistributionStatisticsPageReqVO pageReqVO) {
return distributionStatisticsMapper.selectPage(pageReqVO);
}
@Override
public PageResult<DistributionStatisticsRespVO> getDistributionStatisticsPage1(DistributionStatisticsPageReqVO pageReqVO) {
IPage<DistributionStatisticsRespVO> pageResult = distributionStatisticsMapper.selectPage1(
MyBatisUtils.buildPage(pageReqVO),
pageReqVO.getStatus());
return new PageResult<>(pageResult.getRecords(), pageResult.getTotal());
// return distributionStatisticsMapper.selectPage1(pageReqVO);
}
}

@ -186,5 +186,28 @@ public interface MemberUserService {
* @return * @return
*/ */
boolean updateUserPoint(Long userId, Integer point); boolean updateUserPoint(Long userId, Integer point);
/**
*
*
* @param userId
* @return
*/
boolean updateUserLevelId(Long userId);
/**
* 1188
*
* @param userId
* @return
*/
void updateUserUpgradesLevel(Long userId);
/**
*
*
* @param userId
* @param orderId id
* @param productId id
* @return
*/
void updateUserUpgradesLevelcallback(Long orderId);
} }

@ -8,12 +8,24 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO; import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO; import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
import cn.iocoder.yudao.module.member.controller.app.user.vo.*; import cn.iocoder.yudao.module.member.controller.app.user.vo.*;
import cn.iocoder.yudao.module.member.convert.auth.AuthConvert; import cn.iocoder.yudao.module.member.convert.auth.AuthConvert;
import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert; import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionConfigDO;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionMebConfigDO;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionlog.DistributionLogDO;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionstatistics.DistributionStatisticsDO;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.dal.mysql.distributionconfig.DistributionConfigMapper;
import cn.iocoder.yudao.module.member.dal.mysql.distributionconfig.DistributionMebConfigMapper;
import cn.iocoder.yudao.module.member.dal.mysql.distributionlog.DistributionLogMapper;
import cn.iocoder.yudao.module.member.dal.mysql.distributionstatistics.DistributionStatisticsMapper;
import cn.iocoder.yudao.module.member.dal.mysql.level.MemberLevelMapper;
import cn.iocoder.yudao.module.member.dal.mysql.level.MemberLevelRecordMapper;
import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
import cn.iocoder.yudao.module.member.mq.producer.user.MemberUserProducer; import cn.iocoder.yudao.module.member.mq.producer.user.MemberUserProducer;
import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
@ -21,8 +33,17 @@ import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
import cn.iocoder.yudao.module.system.api.social.SocialClientApi; import cn.iocoder.yudao.module.system.api.social.SocialClientApi;
import cn.iocoder.yudao.module.system.api.social.dto.SocialWxPhoneNumberInfoRespDTO; import cn.iocoder.yudao.module.system.api.social.dto.SocialWxPhoneNumberInfoRespDTO;
import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi;
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageRecordMapper;
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageUserMapper;
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -33,6 +54,7 @@ import javax.annotation.Resource;
import javax.validation.Valid; import javax.validation.Valid;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Collection; import java.util.Collection;
import java.util.Date;
import java.util.List; import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -64,6 +86,33 @@ public class MemberUserServiceImpl implements MemberUserService {
@Resource @Resource
private MemberUserProducer memberUserProducer; private MemberUserProducer memberUserProducer;
@Resource
private MemberLevelRecordMapper levelLogMapper;
@Resource
private MemberLevelMapper memberLevelMapper;
@Resource
private BrokerageUserMapper brokerageUserMapper;
@Resource
private TradeOrderItemMapper tradeOrderItemMapper;
@Resource
@Lazy
private TradeOrderApi tradeOrderApi;
@Resource
private DistributionConfigMapper distributionConfigMapper;
@Resource
private BrokerageRecordMapper brokerageRecordMapper;
@Resource
private DistributionMebConfigMapper distributionMebConfigMapper;
@Resource
private DistributionLogMapper distributionLogMapper;
@Resource
private DistributionStatisticsMapper distributionStatisticsMapper;
@Override @Override
public MemberUserDO getUserByMobile(String mobile) { public MemberUserDO getUserByMobile(String mobile) {
return memberUserMapper.selectByMobile(mobile); return memberUserMapper.selectByMobile(mobile);
@ -314,4 +363,233 @@ public class MemberUserServiceImpl implements MemberUserService {
return true; return true;
} }
@Override
public boolean updateUserLevelId(Long userId) {
//查询帮扶人等级id
MemberLevelDO memberLevelDO = memberLevelMapper.selectOne(new LambdaQueryWrapperX<MemberLevelDO>()
.eq(MemberLevelDO::getStatus, 0)
.eq(MemberLevelDO::getDeleted, 0)
.eq(MemberLevelDO::getLevel, 1)
.orderByAsc(MemberLevelDO::getLevel));
int i = memberUserMapper.updateById(new MemberUserDO()
.setId(userId)
.setLevelId(memberLevelDO.getId())
);
brokerageUserMapper.updateById(new BrokerageUserDO()
.setId(userId)
.setLevel(1)
);
if(i>0){
return true;
}
return false;
}
@Override
public void updateUserUpgradesLevel(Long userId) {
}
@Override
public void updateUserUpgradesLevelcallback(Long orderId) {
//查询订单信息
Long productId = null;
List<TradeOrderItemDO> tradeOrderItemDOS = tradeOrderItemMapper.selectListByOrderId(orderId);
if(ObjectUtil.isNotEmpty(tradeOrderItemDOS)){
productId = tradeOrderItemDOS.get(0).getSpuId();
}
TradeOrderRespDTO order = tradeOrderApi.getOrder(orderId);
Long userId = order.getUserId();
//判断订单是否已支付
//根据商品id查询配置规则
List<DistributionConfigDO> distributionConfigDOS = distributionConfigMapper.selectList(new LambdaQueryWrapperX<DistributionConfigDO>()
.eq(DistributionConfigDO::getProductId, productId)
.eq(DistributionConfigDO::getDeleted, 0)
.eq(DistributionConfigDO::getStatus, 0)
.orderByDesc(DistributionConfigDO::getCreateTime));
if(ObjectUtil.isNotEmpty(distributionConfigDOS)){
DistributionConfigDO distributionConfigDO = distributionConfigDOS.get(0);
//查询会员当前等级
MemberUserDO user = memberUserMapper.selectById(userId);
MemberLevelDO memberLevelDO = memberLevelMapper.selectById(user.getLevelId());
//查询推广员配置信息
MemberLevelDO configLevelDO = memberLevelMapper.selectById(distributionConfigDO.getLevelId());
if(ObjectUtil.isEmpty(memberLevelDO)){
//修改购买人会员等级
int i = memberUserMapper.updateById(new MemberUserDO()
.setId(userId)
.setLevelId(distributionConfigDO.getLevelId())
);
brokerageUserMapper.updateById(new BrokerageUserDO()
.setId(userId)
.setLevel(configLevelDO.getLevel())
);
}else{
if(memberLevelDO.getLevel()<configLevelDO.getLevel()){
//修改购买人会员等级
int i = memberUserMapper.updateById(new MemberUserDO()
.setId(userId)
.setLevelId(distributionConfigDO.getLevelId())
);
brokerageUserMapper.updateById(new BrokerageUserDO()
.setId(userId)
.setLevel(configLevelDO.getLevel())
);
}
}
//查询配置中添加的等级奖励
List<DistributionMebConfigDO> distributionMebConfigDOS = distributionMebConfigMapper.selectList(new LambdaQueryWrapperX<DistributionMebConfigDO>()
.eq(DistributionMebConfigDO::getConfigId, distributionConfigDO.getId())
.eq(DistributionMebConfigDO::getDeleted, 0)
.orderByAsc(DistributionMebConfigDO::getLevelId));
//添加5占一
if(ObjectUtil.isNotEmpty(distributionMebConfigDOS)){
//添加5占一游戏
DistributionLogDO distributionLogDO = new DistributionLogDO();
distributionLogDO.setMebId(userId);
distributionLogDO.setStatus("1");
// distributionLogDO.setBrokerage();
distributionLogDO.setGameStatus("1");
distributionLogDO.setConvertStatus("1");
distributionLogMapper.insert(distributionLogDO);
//查询5占一总数
List<DistributionLogDO> distributionLogDOS = distributionLogMapper.selectList(new LambdaQueryWrapperX<DistributionLogDO>()
.orderByAsc(DistributionLogDO::getCreateTime));
int i1 = distributionLogDOS.size() % 5;
if(i1 == 0){
// DistributionLogDO vo = distributionLogDOS.get((distributionLogDOS.size()/5)-1);
// vo.setGameStatus("0");
// distributionLogMapper.updateById(vo);
List<DistributionLogDO> distributionLogDOS1 = distributionLogDOS.subList(0, (distributionLogDOS.size() / 5));
for (DistributionLogDO dt:distributionLogDOS1) {
dt.setGameStatus("0");
}
distributionLogMapper.updateBatch(distributionLogDOS1);
// distributionLogMapper.up
}
}
//发放直销奖励
//查询推广员
BrokerageUserDO brokerageUserDO = brokerageUserMapper.selectById(userId);
if(ObjectUtil.isNotEmpty(brokerageUserDO)){
if(ObjectUtil.isNotEmpty(brokerageUserDO.getBindUserId())){
//查询推广员会员信息
MemberUserDO memberUserDO = memberUserMapper.selectById(brokerageUserDO.getBindUserId());
if(ObjectUtil.isNotEmpty(memberUserDO)){
if(ObjectUtil.isNotEmpty(distributionMebConfigDOS)){
for (DistributionMebConfigDO eg :distributionMebConfigDOS) {
if(eg.getLevelId() == memberUserDO.getLevelId()){
//添加佣金记录
BrokerageRecordDO brokerageRecordDO = new BrokerageRecordDO();
brokerageRecordDO.setUserId(memberUserDO.getId());
brokerageRecordDO.setBizType(1);
brokerageRecordDO.setTitle("分销直推佣金");
brokerageRecordDO.setPrice(eg.getBrokerage()*100);
//查询当前总佣金
Integer totalPrice = 0;
List<BrokerageRecordDO> brokerageRecordDOS = brokerageRecordMapper.selectList(new LambdaQueryWrapperX<BrokerageRecordDO>()
.eq(BrokerageRecordDO::getUserId, memberUserDO.getId())
.eq(BrokerageRecordDO::getDeleted, 0)
.orderByDesc(BrokerageRecordDO::getCreateTime));
if(ObjectUtil.isNotEmpty(brokerageRecordDOS)){
totalPrice = brokerageRecordDOS.get(0).getTotalPrice();
}
brokerageRecordDO.setTotalPrice(totalPrice+eg.getBrokerage()*100);//当前总佣金
brokerageRecordDO.setStatus(1);
brokerageRecordDO.setSourceUserLevel(configLevelDO.getLevel());
brokerageRecordDO.setSourceUserId(userId);
brokerageRecordMapper.insert(brokerageRecordDO);
break;
}
}
}
recursionMemberLevel(brokerageUserDO.getId(),orderId);
}
}
}
}
}
private void recursionMemberLevel(Long userId,Long orderId){
//查询会员信息
MemberUserDO memberUserDO = memberUserMapper.selectById(userId);
DistributionStatisticsDO distributionStatisticsDO = new DistributionStatisticsDO();
distributionStatisticsDO.setLevelId(memberUserDO.getLevelId());
distributionStatisticsDO.setMebId(memberUserDO.getId());
distributionStatisticsDO.setLogId(orderId);
distributionStatisticsDO.setStatus("1");
distributionStatisticsMapper.insert(distributionStatisticsDO);
//查询会员当前等级
MemberLevelDO memberLevelDO = memberLevelMapper.selectById(memberUserDO.getLevelId());
if(ObjectUtil.isNotEmpty(memberLevelDO)){
//查询上一级会员等级
MemberLevelDO upLevelDO = memberLevelMapper.selectOne(new LambdaQueryWrapperX<MemberLevelDO>()
.eq(MemberLevelDO::getStatus, 0)
.eq(MemberLevelDO::getDeleted, 0)
.eq(MemberLevelDO::getLevel, (memberLevelDO.getLevel()+1))
.orderByAsc(MemberLevelDO::getLevel));
if(ObjectUtil.isNotEmpty(upLevelDO)){
if(ObjectUtil.equal(memberLevelDO.getLevel(),1)){//帮扶人不升级
//添加推荐统计
}
if(ObjectUtil.equal(memberLevelDO.getLevel(),2)){//帮扶员升级帮扶驿站
//查询会员邀请记录下级会员
List<BrokerageUserDO> brokerageUserDOS = brokerageUserMapper.selectList(new LambdaQueryWrapperX<BrokerageUserDO>()
.eq(BrokerageUserDO::getBindUserId, userId)
.ge(BrokerageUserDO::getLevel, memberLevelDO.getLevel())
.eq(BrokerageUserDO::getDeleted, 0)
);
if(ObjectUtil.isNotEmpty(brokerageUserDOS)){
if(brokerageUserDOS.size()>=3){
//升级会员
memberUserMapper.updateById(new MemberUserDO()
.setId(userId)
.setLevelId(upLevelDO.getId())
);
brokerageUserMapper.updateById(new BrokerageUserDO()
.setId(userId)
.setLevel(upLevelDO.getLevel())
);
}
}
//判断上级会员是否升级
BrokerageUserDO brokerageUserDO = brokerageUserMapper.selectById(userId);
recursionMemberLevel(brokerageUserDO.getBindUserId(),orderId);
}
if(ObjectUtil.equal(memberLevelDO.getLevel(),3)){//帮扶驿站升级帮扶中心
//查询会员邀请记录下级会员
List<BrokerageUserDO> brokerageUserDOS = brokerageUserMapper.selectList(new LambdaQueryWrapperX<BrokerageUserDO>()
.eq(BrokerageUserDO::getBindUserId, userId)
.ge(BrokerageUserDO::getLevel, memberLevelDO.getLevel())
.eq(BrokerageUserDO::getDeleted, 0)
);
//查询会员邀请记录下级会员
List<BrokerageUserDO> brokerageUserDOS1 = brokerageUserMapper.selectList(new LambdaQueryWrapperX<BrokerageUserDO>()
.eq(BrokerageUserDO::getBindUserId, userId)
.ge(BrokerageUserDO::getLevel, 2)
.eq(BrokerageUserDO::getDeleted, 0)
);
if(ObjectUtil.isNotEmpty(brokerageUserDOS)){
if(brokerageUserDOS.size()>=10 || brokerageUserDOS1.size()>=300){
//升级会员
memberUserMapper.updateById(new MemberUserDO()
.setId(userId)
.setLevelId(upLevelDO.getId())
);
brokerageUserMapper.updateById(new BrokerageUserDO()
.setId(userId)
.setLevel(upLevelDO.getLevel())
);
}
}
//判断上级会员是否升级
BrokerageUserDO brokerageUserDO = brokerageUserMapper.selectById(userId);
recursionMemberLevel(brokerageUserDO.getBindUserId(),orderId);
}
if(ObjectUtil.equal(memberLevelDO.getLevel(),4)){//帮扶中心不做升级
}
}
}
}
} }

@ -0,0 +1,138 @@
package cn.iocoder.yudao.module.member.service.distributionconfig;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import javax.annotation.Resource;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.member.controller.admin.distributionconfig.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionconfig.DistributionConfigDO;
import cn.iocoder.yudao.module.member.dal.mysql.distributionconfig.DistributionConfigMapper;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import javax.annotation.Resource;
import org.springframework.context.annotation.Import;
import java.util.*;
import java.time.LocalDateTime;
import static cn.hutool.core.util.RandomUtil.*;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
/**
* {@link DistributionConfigServiceImpl}
*
* @author
*/
@Import(DistributionConfigServiceImpl.class)
public class DistributionConfigServiceImplTest extends BaseDbUnitTest {
@Resource
private DistributionConfigServiceImpl distributionConfigService;
@Resource
private DistributionConfigMapper distributionConfigMapper;
@Test
public void testCreateDistributionConfig_success() {
// 准备参数
DistributionConfigSaveReqVO createReqVO = randomPojo(DistributionConfigSaveReqVO.class).setId(null);
// 调用
Long distributionConfigId = distributionConfigService.createDistributionConfig(createReqVO);
// 断言
assertNotNull(distributionConfigId);
// 校验记录的属性是否正确
DistributionConfigDO distributionConfig = distributionConfigMapper.selectById(distributionConfigId);
assertPojoEquals(createReqVO, distributionConfig, "id");
}
@Test
public void testUpdateDistributionConfig_success() {
// mock 数据
DistributionConfigDO dbDistributionConfig = randomPojo(DistributionConfigDO.class);
distributionConfigMapper.insert(dbDistributionConfig);// @Sql: 先插入出一条存在的数据
// 准备参数
DistributionConfigSaveReqVO updateReqVO = randomPojo(DistributionConfigSaveReqVO.class, o -> {
o.setId(dbDistributionConfig.getId()); // 设置更新的 ID
});
// 调用
distributionConfigService.updateDistributionConfig(updateReqVO);
// 校验是否更新正确
DistributionConfigDO distributionConfig = distributionConfigMapper.selectById(updateReqVO.getId()); // 获取最新的
assertPojoEquals(updateReqVO, distributionConfig);
}
@Test
public void testUpdateDistributionConfig_notExists() {
// 准备参数
DistributionConfigSaveReqVO updateReqVO = randomPojo(DistributionConfigSaveReqVO.class);
// 调用, 并断言异常
assertServiceException(() -> distributionConfigService.updateDistributionConfig(updateReqVO), DISTRIBUTION_CONFIG_NOT_EXISTS);
}
@Test
public void testDeleteDistributionConfig_success() {
// mock 数据
DistributionConfigDO dbDistributionConfig = randomPojo(DistributionConfigDO.class);
distributionConfigMapper.insert(dbDistributionConfig);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbDistributionConfig.getId();
// 调用
distributionConfigService.deleteDistributionConfig(id);
// 校验数据不存在了
assertNull(distributionConfigMapper.selectById(id));
}
@Test
public void testDeleteDistributionConfig_notExists() {
// 准备参数
Long id = randomLongId();
// 调用, 并断言异常
assertServiceException(() -> distributionConfigService.deleteDistributionConfig(id), DISTRIBUTION_CONFIG_NOT_EXISTS);
}
@Test
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
public void testGetDistributionConfigPage() {
// mock 数据
DistributionConfigDO dbDistributionConfig = randomPojo(DistributionConfigDO.class, o -> { // 等会查询到
o.setProductId(null);
o.setStatus(null);
o.setCreateTime(null);
});
distributionConfigMapper.insert(dbDistributionConfig);
// 测试 productId 不匹配
distributionConfigMapper.insert(cloneIgnoreId(dbDistributionConfig, o -> o.setProductId(null)));
// 测试 status 不匹配
distributionConfigMapper.insert(cloneIgnoreId(dbDistributionConfig, o -> o.setStatus(null)));
// 测试 createTime 不匹配
distributionConfigMapper.insert(cloneIgnoreId(dbDistributionConfig, o -> o.setCreateTime(null)));
// 准备参数
DistributionConfigPageReqVO reqVO = new DistributionConfigPageReqVO();
reqVO.setProductId(null);
reqVO.setStatus(null);
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
// 调用
PageResult<DistributionConfigDO> pageResult = distributionConfigService.getDistributionConfigPage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbDistributionConfig, pageResult.getList().get(0));
}
}

@ -0,0 +1,162 @@
package cn.iocoder.yudao.module.member.service.distributionlog;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import javax.annotation.Resource;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.member.controller.admin.distributionlog.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionlog.DistributionLogDO;
import cn.iocoder.yudao.module.member.dal.mysql.distributionlog.DistributionLogMapper;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import javax.annotation.Resource;
import org.springframework.context.annotation.Import;
import java.util.*;
import java.time.LocalDateTime;
import static cn.hutool.core.util.RandomUtil.*;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
/**
* {@link DistributionLogServiceImpl}
*
* @author
*/
@Import(DistributionLogServiceImpl.class)
public class DistributionLogServiceImplTest extends BaseDbUnitTest {
@Resource
private DistributionLogServiceImpl distributionLogService;
@Resource
private DistributionLogMapper distributionLogMapper;
@Test
public void testCreateDistributionLog_success() {
// 准备参数
DistributionLogSaveReqVO createReqVO = randomPojo(DistributionLogSaveReqVO.class).setId(null);
// 调用
Long distributionLogId = distributionLogService.createDistributionLog(createReqVO);
// 断言
assertNotNull(distributionLogId);
// 校验记录的属性是否正确
DistributionLogDO distributionLog = distributionLogMapper.selectById(distributionLogId);
assertPojoEquals(createReqVO, distributionLog, "id");
}
@Test
public void testUpdateDistributionLog_success() {
// mock 数据
DistributionLogDO dbDistributionLog = randomPojo(DistributionLogDO.class);
distributionLogMapper.insert(dbDistributionLog);// @Sql: 先插入出一条存在的数据
// 准备参数
DistributionLogSaveReqVO updateReqVO = randomPojo(DistributionLogSaveReqVO.class, o -> {
o.setId(dbDistributionLog.getId()); // 设置更新的 ID
});
// 调用
distributionLogService.updateDistributionLog(updateReqVO);
// 校验是否更新正确
DistributionLogDO distributionLog = distributionLogMapper.selectById(updateReqVO.getId()); // 获取最新的
assertPojoEquals(updateReqVO, distributionLog);
}
@Test
public void testUpdateDistributionLog_notExists() {
// 准备参数
DistributionLogSaveReqVO updateReqVO = randomPojo(DistributionLogSaveReqVO.class);
// 调用, 并断言异常
assertServiceException(() -> distributionLogService.updateDistributionLog(updateReqVO), DISTRIBUTION_LOG_NOT_EXISTS);
}
@Test
public void testDeleteDistributionLog_success() {
// mock 数据
DistributionLogDO dbDistributionLog = randomPojo(DistributionLogDO.class);
distributionLogMapper.insert(dbDistributionLog);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbDistributionLog.getId();
// 调用
distributionLogService.deleteDistributionLog(id);
// 校验数据不存在了
assertNull(distributionLogMapper.selectById(id));
}
@Test
public void testDeleteDistributionLog_notExists() {
// 准备参数
Long id = randomLongId();
// 调用, 并断言异常
assertServiceException(() -> distributionLogService.deleteDistributionLog(id), DISTRIBUTION_LOG_NOT_EXISTS);
}
@Test
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
public void testGetDistributionLogPage() {
// mock 数据
DistributionLogDO dbDistributionLog = randomPojo(DistributionLogDO.class, o -> { // 等会查询到
o.setReferrerId(null);
o.setOldReferrerId(null);
o.setMebId(null);
o.setBrokerage(null);
o.setStatus(null);
o.setGameStatus(null);
o.setConvertStatus(null);
o.setLevelId(null);
o.setCreateTime(null);
});
distributionLogMapper.insert(dbDistributionLog);
// 测试 referrerId 不匹配
distributionLogMapper.insert(cloneIgnoreId(dbDistributionLog, o -> o.setReferrerId(null)));
// 测试 oldReferrerId 不匹配
distributionLogMapper.insert(cloneIgnoreId(dbDistributionLog, o -> o.setOldReferrerId(null)));
// 测试 mebId 不匹配
distributionLogMapper.insert(cloneIgnoreId(dbDistributionLog, o -> o.setMebId(null)));
// 测试 brokerage 不匹配
distributionLogMapper.insert(cloneIgnoreId(dbDistributionLog, o -> o.setBrokerage(null)));
// 测试 status 不匹配
distributionLogMapper.insert(cloneIgnoreId(dbDistributionLog, o -> o.setStatus(null)));
// 测试 gameStatus 不匹配
distributionLogMapper.insert(cloneIgnoreId(dbDistributionLog, o -> o.setGameStatus(null)));
// 测试 convertStatus 不匹配
distributionLogMapper.insert(cloneIgnoreId(dbDistributionLog, o -> o.setConvertStatus(null)));
// 测试 levelId 不匹配
distributionLogMapper.insert(cloneIgnoreId(dbDistributionLog, o -> o.setLevelId(null)));
// 测试 createTime 不匹配
distributionLogMapper.insert(cloneIgnoreId(dbDistributionLog, o -> o.setCreateTime(null)));
// 准备参数
DistributionLogPageReqVO reqVO = new DistributionLogPageReqVO();
reqVO.setReferrerId(null);
reqVO.setOldReferrerId(null);
reqVO.setMebId(null);
reqVO.setBrokerage(null);
reqVO.setStatus(null);
reqVO.setGameStatus(null);
reqVO.setConvertStatus(null);
reqVO.setLevelId(null);
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
// 调用
PageResult<DistributionLogDO> pageResult = distributionLogService.getDistributionLogPage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbDistributionLog, pageResult.getList().get(0));
}
}

@ -0,0 +1,150 @@
package cn.iocoder.yudao.module.member.service.distributionstatistics;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import javax.annotation.Resource;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.member.controller.admin.distributionstatistics.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.distributionstatistics.DistributionStatisticsDO;
import cn.iocoder.yudao.module.member.dal.mysql.distributionstatistics.DistributionStatisticsMapper;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import javax.annotation.Resource;
import org.springframework.context.annotation.Import;
import java.util.*;
import java.time.LocalDateTime;
import static cn.hutool.core.util.RandomUtil.*;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
/**
* {@link DistributionStatisticsServiceImpl}
*
* @author
*/
@Import(DistributionStatisticsServiceImpl.class)
public class DistributionStatisticsServiceImplTest extends BaseDbUnitTest {
@Resource
private DistributionStatisticsServiceImpl distributionStatisticsService;
@Resource
private DistributionStatisticsMapper distributionStatisticsMapper;
@Test
public void testCreateDistributionStatistics_success() {
// 准备参数
DistributionStatisticsSaveReqVO createReqVO = randomPojo(DistributionStatisticsSaveReqVO.class).setId(null);
// 调用
Long distributionStatisticsId = distributionStatisticsService.createDistributionStatistics(createReqVO);
// 断言
assertNotNull(distributionStatisticsId);
// 校验记录的属性是否正确
DistributionStatisticsDO distributionStatistics = distributionStatisticsMapper.selectById(distributionStatisticsId);
assertPojoEquals(createReqVO, distributionStatistics, "id");
}
@Test
public void testUpdateDistributionStatistics_success() {
// mock 数据
DistributionStatisticsDO dbDistributionStatistics = randomPojo(DistributionStatisticsDO.class);
distributionStatisticsMapper.insert(dbDistributionStatistics);// @Sql: 先插入出一条存在的数据
// 准备参数
DistributionStatisticsSaveReqVO updateReqVO = randomPojo(DistributionStatisticsSaveReqVO.class, o -> {
o.setId(dbDistributionStatistics.getId()); // 设置更新的 ID
});
// 调用
distributionStatisticsService.updateDistributionStatistics(updateReqVO);
// 校验是否更新正确
DistributionStatisticsDO distributionStatistics = distributionStatisticsMapper.selectById(updateReqVO.getId()); // 获取最新的
assertPojoEquals(updateReqVO, distributionStatistics);
}
@Test
public void testUpdateDistributionStatistics_notExists() {
// 准备参数
DistributionStatisticsSaveReqVO updateReqVO = randomPojo(DistributionStatisticsSaveReqVO.class);
// 调用, 并断言异常
assertServiceException(() -> distributionStatisticsService.updateDistributionStatistics(updateReqVO), DISTRIBUTION_STATISTICS_NOT_EXISTS);
}
@Test
public void testDeleteDistributionStatistics_success() {
// mock 数据
DistributionStatisticsDO dbDistributionStatistics = randomPojo(DistributionStatisticsDO.class);
distributionStatisticsMapper.insert(dbDistributionStatistics);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbDistributionStatistics.getId();
// 调用
distributionStatisticsService.deleteDistributionStatistics(id);
// 校验数据不存在了
assertNull(distributionStatisticsMapper.selectById(id));
}
@Test
public void testDeleteDistributionStatistics_notExists() {
// 准备参数
Long id = randomLongId();
// 调用, 并断言异常
assertServiceException(() -> distributionStatisticsService.deleteDistributionStatistics(id), DISTRIBUTION_STATISTICS_NOT_EXISTS);
}
@Test
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
public void testGetDistributionStatisticsPage() {
// mock 数据
DistributionStatisticsDO dbDistributionStatistics = randomPojo(DistributionStatisticsDO.class, o -> { // 等会查询到
o.setLevelId(null);
o.setMebId(null);
o.setLogId(null);
o.setReferrerId(null);
o.setStatus(null);
o.setCreateTime(null);
});
distributionStatisticsMapper.insert(dbDistributionStatistics);
// 测试 levelId 不匹配
distributionStatisticsMapper.insert(cloneIgnoreId(dbDistributionStatistics, o -> o.setLevelId(null)));
// 测试 mebId 不匹配
distributionStatisticsMapper.insert(cloneIgnoreId(dbDistributionStatistics, o -> o.setMebId(null)));
// 测试 logId 不匹配
distributionStatisticsMapper.insert(cloneIgnoreId(dbDistributionStatistics, o -> o.setLogId(null)));
// 测试 referrerId 不匹配
distributionStatisticsMapper.insert(cloneIgnoreId(dbDistributionStatistics, o -> o.setReferrerId(null)));
// 测试 status 不匹配
distributionStatisticsMapper.insert(cloneIgnoreId(dbDistributionStatistics, o -> o.setStatus(null)));
// 测试 createTime 不匹配
distributionStatisticsMapper.insert(cloneIgnoreId(dbDistributionStatistics, o -> o.setCreateTime(null)));
// 准备参数
DistributionStatisticsPageReqVO reqVO = new DistributionStatisticsPageReqVO();
reqVO.setLevelId(null);
reqVO.setMebId(null);
reqVO.setLogId(null);
reqVO.setReferrerId(null);
reqVO.setStatus(null);
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
// 调用
PageResult<DistributionStatisticsDO> pageResult = distributionStatisticsService.getDistributionStatisticsPage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbDistributionStatistics, pageResult.getList().get(0));
}
}

@ -33,6 +33,7 @@ public class PayDemoOrderController {
@Resource @Resource
private PayDemoOrderService payDemoOrderService; private PayDemoOrderService payDemoOrderService;
@PostMapping("/create") @PostMapping("/create")
@Operation(summary = "创建示例订单") @Operation(summary = "创建示例订单")
public CommonResult<Long> createDemoOrder(@Valid @RequestBody PayDemoOrderCreateReqVO createReqVO) { public CommonResult<Long> createDemoOrder(@Valid @RequestBody PayDemoOrderCreateReqVO createReqVO) {
@ -52,6 +53,8 @@ public class PayDemoOrderController {
public CommonResult<Boolean> updateDemoOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) { public CommonResult<Boolean> updateDemoOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) {
payDemoOrderService.updateDemoOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()), payDemoOrderService.updateDemoOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()),
notifyReqDTO.getPayOrderId()); notifyReqDTO.getPayOrderId());
return success(true); return success(true);
} }

@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.pay.core.client.PayClient; import cn.iocoder.yudao.framework.pay.core.client.PayClient;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskDetailRespVO; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskDetailRespVO;
import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskPageReqVO; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskPageReqVO;
import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskRespVO; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskRespVO;

@ -58,5 +58,8 @@ public interface PayOrderMapper extends BaseMapperX<PayOrderDO> {
.eq(PayOrderDO::getStatus, status) .eq(PayOrderDO::getStatus, status)
.lt(PayOrderDO::getExpireTime, expireTime)); .lt(PayOrderDO::getExpireTime, expireTime));
} }
default PayOrderDO selectPayOrderDOById(Long id) {
return selectById(id);
}
} }

@ -12,6 +12,7 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO; import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO;
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO; import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO;
@ -75,6 +76,9 @@ public class PayOrderServiceImpl implements PayOrderService {
@Resource @Resource
private PayNotifyService notifyService; private PayNotifyService notifyService;
@Resource
private MemberUserApi memberUserApi;
@Override @Override
public PayOrderDO getOrder(Long id) { public PayOrderDO getOrder(Long id) {
return orderMapper.selectById(id); return orderMapper.selectById(id);
@ -268,6 +272,9 @@ public class PayOrderServiceImpl implements PayOrderService {
// 情况一:支付成功的回调 // 情况一:支付成功的回调
if (PayOrderStatusRespEnum.isSuccess(notify.getStatus())) { if (PayOrderStatusRespEnum.isSuccess(notify.getStatus())) {
notifyOrderSuccess(channel, notify); notifyOrderSuccess(channel, notify);
PayOrderExtensionDO orderExtension = updateOrderSuccess(notify);
PayOrderDO payOrderDO = orderMapper.selectPayOrderDOById(orderExtension.getOrderId());
memberUserApi.updateUserUpgradesLevelcallback(Long.valueOf(payOrderDO.getMerchantOrderId()));
return; return;
} }
// 情况二:支付失败的回调 // 情况二:支付失败的回调

@ -178,7 +178,8 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
if (userType.equals(UserTypeEnum.ADMIN.getValue())) { if (userType.equals(UserTypeEnum.ADMIN.getValue())) {
AdminUserDO user = adminUserService.getUser(userId); AdminUserDO user = adminUserService.getUser(userId);
return MapUtil.builder(LoginUser.INFO_KEY_NICKNAME, user.getNickname()) return MapUtil.builder(LoginUser.INFO_KEY_NICKNAME, user.getNickname())
.put(LoginUser.INFO_KEY_DEPT_ID, StrUtil.toStringOrNull(user.getDeptId())).build(); .put(LoginUser.INFO_KEY_DEPT_ID, StrUtil.toStringOrNull(user.getDeptId()))
.put(LoginUser.INFO_KEY_MOBILE,StrUtil.toStringOrNull(user.getMobile())).build();
} else if (userType.equals(UserTypeEnum.MEMBER.getValue())) { } else if (userType.equals(UserTypeEnum.MEMBER.getValue())) {
// 注意:目前 Member 暂时不读取,可以按需实现 // 注意:目前 Member 暂时不读取,可以按需实现
return Collections.emptyMap(); return Collections.emptyMap();

@ -1 +1,2 @@
SHOPRO_DEV_BASE_URL = http://192.168.0.135:48080 # SHOPRO_DEV_BASE_URL = https://yanghaodong.51vip.biz
SHOPRO_DEV_BASE_URL = http://192.168.1.118:48080

@ -68,7 +68,10 @@
"schemes": "shopro" "schemes": "shopro"
}, },
"ios": { "ios": {
"urlschemewhitelist": ["baidumap", "iosamap"], "urlschemewhitelist": [
"baidumap",
"iosamap"
],
"dSYMs": false, "dSYMs": false,
"privacyDescription": { "privacyDescription": {
"NSPhotoLibraryUsageDescription": "需要同意访问您的相册选取图片才能完善该条目", "NSPhotoLibraryUsageDescription": "需要同意访问您的相册选取图片才能完善该条目",
@ -79,7 +82,9 @@
"urltypes": "shopro", "urltypes": "shopro",
"capabilities": { "capabilities": {
"entitlements": { "entitlements": {
"com.apple.developer.associated-domains": ["applinks:shopro.sheepjs.com"] "com.apple.developer.associated-domains": [
"applinks:shopro.sheepjs.com"
]
} }
}, },
"idfa": true "idfa": true
@ -98,12 +103,18 @@
}, },
"payment": { "payment": {
"weixin": { "weixin": {
"__platform__": ["ios", "android"], "__platform__": [
"ios",
"android"
],
"appid": "wxae7a0c156da9383b", "appid": "wxae7a0c156da9383b",
"UniversalLinks": "https://shopro.sheepjs.com/uni-universallinks/__UNI__082C0BA/" "UniversalLinks": "https://shopro.sheepjs.com/uni-universallinks/__UNI__082C0BA/"
}, },
"alipay": { "alipay": {
"__platform__": ["ios", "android"] "__platform__": [
"ios",
"android"
]
} }
}, },
"share": { "share": {
@ -113,7 +124,9 @@
} }
} }
}, },
"orientation": ["portrait-primary"], "orientation": [
"portrait-primary"
],
"splashscreen": { "splashscreen": {
"androidStyle": "common", "androidStyle": "common",
"iosStyle": "common", "iosStyle": "common",
@ -157,9 +170,11 @@
"quickapp-native": { "quickapp-native": {
"icon": "/static/logo.png", "icon": "/static/logo.png",
"package": "com.example.demo", "package": "com.example.demo",
"features": [{ "features": [
{
"name": "system.clipboard" "name": "system.clipboard"
}] }
]
}, },
"quickapp-webview": { "quickapp-webview": {
"icon": "/static/logo.png", "icon": "/static/logo.png",
@ -182,7 +197,9 @@
"lazyCodeLoading": "requiredComponents", "lazyCodeLoading": "requiredComponents",
"usingComponents": {}, "usingComponents": {},
"permission": {}, "permission": {},
"requiredPrivateInfos": ["chooseAddress"] "requiredPrivateInfos": [
"chooseAddress"
]
}, },
"mp-alipay": { "mp-alipay": {
"usingComponents": true "usingComponents": true

@ -261,6 +261,42 @@
"group": "用户中心" "group": "用户中心"
} }
}, },
{
"path": "prize",
"style": {
"navigationBarTitleText": "抽奖"
},
"meta": {
"auth": true,
"sync": true,
"title": "抽奖活动",
"group": "用户中心"
}
},
{
"path": "PrizesWon",
"style": {
"navigationBarTitleText": "已获奖品"
},
"meta": {
"auth": true,
"sync": true,
"title": "抽奖活动",
"group": "用户中心"
}
},
{
"path": "ActivityRules",
"style": {
"navigationBarTitleText": "活动规则"
},
"meta": {
"auth": true,
"sync": true,
"title": "活动规则",
"group": "用户中心"
}
},
{ {
"path": "goods-collect", "path": "goods-collect",
"style": { "style": {
@ -297,6 +333,18 @@
"group": "用户中心" "group": "用户中心"
} }
}, },
{
"path": "address/listt",
"style": {
"navigationBarTitleText": "收货地址"
},
"meta": {
"auth": true,
"sync": true,
"title": "地址管理",
"group": "用户中心"
}
},
{ {
"path": "address/edit", "path": "address/edit",
"style": { "style": {
@ -635,7 +683,7 @@
], ],
"globalStyle": { "globalStyle": {
"navigationBarTextStyle": "black", "navigationBarTextStyle": "black",
"navigationBarTitleText": "芋道商城", "navigationBarTitleText": "郑大钒水",
"navigationBarBackgroundColor": "#FFFFFF", "navigationBarBackgroundColor": "#FFFFFF",
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"navigationStyle": "custom" "navigationStyle": "custom"

@ -51,10 +51,15 @@
onLoad((options) => { onLoad((options) => {
// #ifdef MP // #ifdef MP
// //
if (options.scene) { if (options.q) {
const sceneParams = decodeURIComponent(options.scene).split('='); const sceneParams = decodeURIComponent(options.q).split('=');
console.log("sceneParams=>",sceneParams); console.log("sceneParams=>",sceneParams);
options[sceneParams[0]] = sceneParams[1]; options[sceneParams[0]] = sceneParams[1];
console.log(options,'1123456');
uni.setStorageSync('bindUserId', sceneParams[1]);
}
if (options.r) {
uni.setStorageSync('bindUserId', options.r);
} }
// #endif // #endif

@ -1,14 +1,27 @@
<template> <template>
<s-layout title="确认订单"> <s-layout title="确认订单">
<!-- TODO这个判断先删除 v-if="state.orderInfo.need_address === 1" --> <!-- TODO这个判断先删除 v-if="state.orderInfo.need_address === 1" -->
<view class="bg-white address-box ss-m-b-14 ss-r-b-10" @tap="onSelectAddress"> <view class="top">
配送方式是否自提
<switch checked @change="switch1Change" />
</view>
<view class="bg-white address-box ss-m-b-14 ss-r-b-10" @tap="onSelectAddress" v-if='state.deliType === 1'>
<s-address-item :item="state.addressInfo" :hasBorderBottom="false"> <s-address-item :item="state.addressInfo" :hasBorderBottom="false">
<view class="ss-rest-button"> <view class="ss-rest-button">
<text class="_icon-forward" /> <text class="_icon-forward" />
</view> </view>
</s-address-item> </s-address-item>
</view> </view>
<view class="pickUpInfo" @tap="onSelectAddress1" v-else>
<view>
<view>门店信息</view>
<view>{{state.pickUpInfo.detailAddress}}</view>
<view>{{state.pickUpInfo.areaName}}</view>
</view>
<view class="ss-rest-button">
<text class="_icon-forward" />
</view>
</view>
<!-- 商品信息 --> <!-- 商品信息 -->
<view class="order-card-box ss-m-b-14"> <view class="order-card-box ss-m-b-14">
<s-goods-item <s-goods-item
@ -173,6 +186,8 @@
items: [], // items: [], //
price: {}, // price: {}, //
}, },
deliType:2,
pickUpInfo:{},//
addressInfo: {}, // addressInfo: {}, //
showCoupon: false, // showCoupon: false, //
couponInfo: [], // couponInfo: [], //
@ -180,13 +195,24 @@
}); });
// //
function onSelectAddress1() {
uni.$once('SELECT_ADDRESS1', (e) => {
changeConsignee1(e.pickUpInfo);
});
sheep.$router.go('/pages/user/address/listt');
}
function changeConsignee1(pickUpInfo = {}) {
if (!isEmpty(pickUpInfo)) {
state.pickUpInfo = pickUpInfo;
}
}
///////////////////////
function onSelectAddress() { function onSelectAddress() {
uni.$once('SELECT_ADDRESS', (e) => { uni.$once('SELECT_ADDRESS', (e) => {
changeConsignee(e.addressInfo); changeConsignee(e.addressInfo);
}); });
sheep.$router.go('/pages/user/address/list'); sheep.$router.go('/pages/user/address/list');
} }
// & // &
async function changeConsignee(addressInfo = {}) { async function changeConsignee(addressInfo = {}) {
if (!isEmpty(addressInfo)) { if (!isEmpty(addressInfo)) {
@ -210,14 +236,22 @@
} }
submitOrder(); submitOrder();
} }
//
const switch1Change = ()=>{
if(state.deliType == 1){
state.deliType = 2
}else{
state.deliType = 1
}
}
// & // &
async function submitOrder() { async function submitOrder() {
const { code, data } = await OrderApi.createOrder({ const { code, data } = await OrderApi.createOrder({
items: state.orderPayload.items, items: state.orderPayload.items,
couponId: state.orderPayload.couponId, couponId: state.orderPayload.couponId,
addressId: state.addressInfo.id, addressId: state.deliType === 1 ? state.addressInfo.id: null,
deliveryType: 1, // TODO pickUpStoreId:state.deliType === 2 ? state.pickUpInfo.id : null,
deliveryType: state.deliType, // TODO
pointStatus: false, // TODO pointStatus: false, // TODO
combinationActivityId: state.orderPayload.combinationActivityId, combinationActivityId: state.orderPayload.combinationActivityId,
combinationHeadId: state.orderPayload.combinationHeadId, combinationHeadId: state.orderPayload.combinationHeadId,
@ -284,6 +318,14 @@
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.pickUpInfo{
display:flex;
background-color: white;
align-items: center ;
justify-content: space-between;
margin-bottom: 2vw;
padding: 2vw;
}
:deep() { :deep() {
.uni-input-wrapper { .uni-input-wrapper {
width: 320rpx; width: 320rpx;

@ -49,9 +49,25 @@
formatOrderStatusDescription(state.orderInfo) formatOrderStatusDescription(state.orderInfo)
}}</view> }}</view>
</view> </view>
<view class="order-address-box" v-if="state.orderInfo.deliveryType === 2">
<view class="ss-flex ss-col-center">
<text class="address-username">
自提核销码
</text>
<text class="address-phone">{{ state.orderInfo.pickUpVerifyCode }}</text>
</view>
<view class="ss-flex ss-col-center">
<text class="address-username">
{{ state.pinkUpInfo.name }}
</text>
<text class="address-phone">{{ state.pinkUpInfo.phone }}</text>
</view>
<view class="address-detail">
{{ state.pinkUpInfo.areaName }} {{ state.pinkUpInfo.detailAddress }}
</view>
</view>
<!-- 收货地址 --> <!-- 收货地址 -->
<view class="order-address-box" v-if="state.orderInfo.receiverAreaId > 0"> <view class="order-address-box" v-else>
<view class="ss-flex ss-col-center"> <view class="ss-flex ss-col-center">
<text class="address-username"> <text class="address-username">
{{ state.orderInfo.receiverName }} {{ state.orderInfo.receiverName }}
@ -268,8 +284,8 @@
orderInfo: {}, orderInfo: {},
merchantTradeNo: '', // merchantTradeNo: '', //
comeinType: '', // comeinType: '', //
pinkUpInfo:{},//
}); });
// //
const onCopy = () => { const onCopy = () => {
sheep.$helper.copyText(state.orderInfo.sn); sheep.$helper.copyText(state.orderInfo.sn);
@ -378,6 +394,7 @@
async function getOrderDetail(id) { async function getOrderDetail(id) {
// //
let res; let res;
// let pinkUP;
if (state.comeinType === 'wechat') { if (state.comeinType === 'wechat') {
// TODO // TODO
res = await OrderApi.getOrder(id, { res = await OrderApi.getOrder(id, {
@ -388,6 +405,9 @@
} }
if (res.code === 0) { if (res.code === 0) {
state.orderInfo = res.data; state.orderInfo = res.data;
const {data} = await OrderApi.getPinkUp(1)
state.pinkUpInfo = data;
console.log(data,state.pinkUpInfo)
handleOrderButtons(state.orderInfo); handleOrderButtons(state.orderInfo);
} else { } else {
sheep.$router.back(); sheep.$router.back();

@ -0,0 +1,39 @@
<template>
<view>
<s-layout class="set-wrap" title="抽奖规则" :bgStyle="{ color: '#FFF' }">
<!-- <view class="ss-p-30">
<mp-html class="richtext" :content="state.content" />
</view> -->
<rich-text :nodes="data"></rich-text>
</s-layout>
</view>
</template>
<script setup>
import { ref } from 'vue'
import MineApi from '@/sheep/api/prize/index'
import { onLoad, onReachBottom, onShow, onUnload, onHide } from '@dcloudio/uni-app';
const data = ref()
const getActivityRules = async () => {
const res = await MineApi.ActivityRules()
data.value = res.data.name
// data.value = res.data.value = res.result.content.replace(
// /<img(.*?)\s*width=".*?"\s*height=".*?"\s*\/?>/g,
// '<img$1 style="max-width: 100%;" />'
// )
// data.value = data.value.replace(/style="display: block; margin-left: auto; margin-right: auto;"/g, '')
}
onShow(() => {
getActivityRules()
})
</script>
<style lang="scss" scoped>
</style>

@ -0,0 +1,186 @@
<template>
<s-layout class="set-wrap" title="已获奖品" :bgStyle="{ color: '#FFF' }">
<view>
<view class="_thWrap" v-for="(item, index) in list" :key="item.id">
<view class="_cont">
<view class="_left">
<image class="_img" :src="item.imgUrl"></image>
</view>
<view class="_right">
<view class="_h4">
<text>奖品名称{{ item.name }}</text>
</view>
<view class="_h4">
<text>获得时间{{ formattedDateTime(item.createTime) }}</text>
</view>
</view>
</view>
</view>
</view>
</s-layout>
</template>
<script setup>
import { ref, } from 'vue'
import MineApi from '@/sheep/api/prize/index'
// import layOut from '@/components/layout.vue'
import { onLoad, onReachBottom, onShow, onUnload, onHide } from '@dcloudio/uni-app';
const list = ref()
//
const getPrizesWon = async () => {
const r = await MineApi.ActivityRules()
let HDid = r.data?.id
const res = await MineApi.PrizesWon(HDid)
list.value = res.data
}
const formattedDateTime = (timestampInMilliseconds) => {
const date = new Date(timestampInMilliseconds);
const year = date.getFullYear();
const month = ('0' + (date.getMonth() + 1)).slice(-2);
const day = ('0' + date.getDate()).slice(-2);
const hours = ('0' + date.getHours()).slice(-2);
const minutes = ('0' + date.getMinutes()).slice(-2);
const seconds = ('0' + date.getSeconds()).slice(-2);
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};
onShow(async () => {
await getPrizesWon()
})
</script>
<style lang="scss" scoped>
page {
background-color: white;
}
.tabs {
display: flex;
justify-content: space-evenly;
height: 100rpx;
line-height: 90rpx;
font-size: 28rpx;
border-radius: 10rpx;
box-shadow: 0 4rpx 5rpx rgba(200, 200, 200, 0.3);
color: #333;
background-color: #fff;
z-index: 9;
.text {
margin: 0 20rpx;
position: relative;
font-size: 32rpx;
}
.active {
&::after {
content: '';
width: 70rpx;
height: 5rpx;
transform: translate(-50%);
background-color: #4376f5;
position: absolute;
left: 50%;
bottom: 24rpx;
}
}
}
._thWrap {
width: 100%;
border-bottom: 2rpx solid rgba(242, 242, 242, 1);
padding: 20rpx 0;
}
._cont {
display: flex;
justify-content: space-between;
background: #ffffff;
border-radius: 10px;
box-shadow: 0 0 10rpx 5rpx rgba(200, 200, 200, 0.3);
padding: 10px;
flex: 1;
._left {
width: 266rpx;
height: 260rpx;
border: 2rpx solid rgba(242, 242, 242, 1);
text-align: center;
._img {
width: 265rpx;
height: 250rpx;
}
}
._right {
margin-left: 30rpx;
padding-top: 10rpx;
._h4 {
padding-top: 50rpx;
._h5 {
margin-bottom: 10rpx;
}
._h5Two {
font-size: 35rpx;
margin-bottom: 10rpx;
}
._tips {
color: #aaaaaa;
font-size: 22rpx;
}
._tipsTwo {
color: #565353;
font-size: 30rpx;
}
}
.danjia {
display: block;
color: red;
font-size: 25rpx;
// font-weight: bolder;
margin-top: 60rpx;
text {
font-size: 15rpx;
}
}
}
// ._bo {
// margin-top: 20rpx;
// display: flex;
// justify-content: space-between;
// align-items: center;
// ._money {
// color: red($color: #a9a8a8);
// // font-weight: bold;
// font-size: 20rpx;
// margin-right: 16rpx;
// text {
// font-size: 28rpx;
// }
// }
// ._btn {
// width: 192rpx;
// height: 62rpx;
// line-height: 62rpx;
// text-align: center;
// border-radius: 100rpx;
// color: white;
// font-weight: bold;
// background-color: $color-gray-Main;
// }
// }
}
</style>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save