diff --git a/ruoyi-vue-pro-master/yudao-framework/yudao-common/pom.xml b/ruoyi-vue-pro-master/yudao-framework/yudao-common/pom.xml index f364df7..cb960d5 100644 --- a/ruoyi-vue-pro-master/yudao-framework/yudao-common/pom.xml +++ b/ruoyi-vue-pro-master/yudao-framework/yudao-common/pom.xml @@ -144,6 +144,26 @@ spring-boot-starter-test test + + + + com.google.zxing + + core + + 3.4.1 + + + + + + com.google.zxing + + javase + + 3.4.1 + + diff --git a/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/Base64Util.java b/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/Base64Util.java new file mode 100644 index 0000000..f4eaab2 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/Base64Util.java @@ -0,0 +1,107 @@ +package cn.iocoder.yudao.framework.common.util.qccode; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.util.Base64; + +/** + * 编码工具 + * + * Created by FSQ + * CopyRight https://www.huamar.com + */ +public class Base64Util { + + private static final Logger logger = LoggerFactory.getLogger(Base64Util.class); + + public Base64Util() { + // empty + } + + public static byte[] baseEncode(byte[] bytes) { + return Base64.getEncoder().encode(bytes); + } + + public static String baseEncode(String s) { + try { + byte[] e = s.getBytes("UTF-8"); + return Base64.getEncoder().encodeToString(e); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static byte[] baseDecode(byte[] bytes) { + return Base64.getDecoder().decode(bytes); + } + + public static String baseDecode(String s) { + try { + byte[] e = Base64.getDecoder().decode(s); + return new String(e, "UTF-8"); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static byte[] urlEncode(byte[] bytes) { + return Base64.getUrlEncoder().encode(bytes); + } + + public static String urlEncode(String s) { + try { + byte[] e = s.getBytes("UTF-8"); + return Base64.getUrlEncoder().encodeToString(e); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static byte[] urlDecode(byte[] bytes) { + return Base64.getUrlDecoder().decode(bytes); + } + + public static String urlDecode(String s) { + byte[] result = Base64.getUrlDecoder().decode(s); + + try { + return new String(result, "UTF-8"); + } catch (UnsupportedEncodingException var3) { + logger.error(var3.getMessage(), var3); + return null; + } + } + + public static byte[] mimeEncode(byte[] bytes) { + return Base64.getMimeEncoder().encode(bytes); + } + + public static String mimeEncode(String s) { + try { + byte[] e = s.getBytes("UTF-8"); + return Base64.getMimeEncoder().encodeToString(e); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static byte[] mimeDecode(byte[] bytes) { + return Base64.getMimeDecoder().decode(bytes); + } + + public static String mimeDecode(String s) { + try { + byte[] e = Base64.getMimeDecoder().decode(s); + return new String(e, "UTF-8"); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } +} diff --git a/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/QRCodeUtil.java b/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/QRCodeUtil.java new file mode 100644 index 0000000..d3d6b0a --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/QRCodeUtil.java @@ -0,0 +1,158 @@ +package cn.iocoder.yudao.framework.common.util.qccode; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.qrcode.BufferedImageLuminanceSource; +import com.google.zxing.*; + +import com.google.zxing.common.BitMatrix; +import com.google.zxing.common.HybridBinarizer; +import com.google.zxing.qrcode.QRCodeReader; +import com.google.zxing.qrcode.QRCodeWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.reader.ReaderException; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; + +/** + * 二维码生成工具类 + * + * Created by FSQ + * CopyRight https://www.huamar.com + */ +public class QRCodeUtil { + public static final Logger logger = LoggerFactory.getLogger(QRCodeUtil.class); + + /** + * 生成包含字符串信息的二维码图片 + * + * @param outputStream 文件输出流路径 + * @param content 二维码携带信息 + * @param width 宽度 + * @param height 高度 + * @param imageFormat 二维码的格式 + * @param resource 原图 + */ + public static boolean createQrCode(OutputStream outputStream, String content, int width, int height, String imageFormat, String resource) { + //设置二维码纠错级别 + HashMap hints = new HashMap(); + hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); + /* width = width ; + height = height ;*/ + try { + //创建比特矩阵(位矩阵)的QR码编码的字符串 + QRCodeWriter qrCodeWriter = new QRCodeWriter(); + BitMatrix byteMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints); + + // 使BufferedImage勾画QRCode (matrixWidth 是行二维码像素点) + int matrixWidth = byteMatrix.getWidth(); + BufferedImage image = new BufferedImage(matrixWidth - 200, matrixWidth - 200, BufferedImage.TYPE_INT_RGB); + + // 使用比特矩阵画并保存图像 + image.createGraphics(); + Graphics2D graphics = (Graphics2D) image.getGraphics(); + graphics.setColor(Color.WHITE); + graphics.fillRect(0, 0, matrixWidth, matrixWidth); + graphics.setColor(Color.BLACK); + for (int i = 0; i < matrixWidth; i++) { + for (int j = 0; j < matrixWidth; j++) { + if (byteMatrix.get(i, j)) { + graphics.fillRect(i - 100, j - 100, 1, 1); + } + } + } + + if (StrUtil.isNotEmpty(resource)) { + BufferedImage big = getRemoteBufferedImage(resource); + + BufferedImage small = image; + Graphics2D g = big.createGraphics(); + + // 二维码坐标(默认在右上角) + int x = big.getWidth() - small.getWidth() - 2; + int y = 2; + + g.drawImage(small, x, y, small.getWidth(), small.getHeight(), null); + g.dispose(); + + return ImageIO.write(big, imageFormat, outputStream); + } else { + return ImageIO.write(image, imageFormat, outputStream); + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + return false; + } + + /** + * 读二维码并输出携带的信息 + */ + public static void readQrCode(InputStream inputStream) throws IOException { + //设置二维码纠错级别 + HashMap hints = new HashMap(); + hints.put(DecodeHintType.CHARACTER_SET, "utf-8"); + //从输入流中获取字符串信息 + BufferedImage image = ImageIO.read(inputStream); + //将图像转换为二进制位图源 + LuminanceSource source = new BufferedImageLuminanceSource(image); + BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); + QRCodeReader reader = new QRCodeReader(); + Result result = null; + try { + result = reader.decode(bitmap, hints); + } catch (ReaderException e) { + logger.error(e.getMessage(), e); + } catch (ChecksumException e) { + throw new RuntimeException(e); + } catch (NotFoundException e) { + throw new RuntimeException(e); + } catch (FormatException e) { + throw new RuntimeException(e); + } + logger.info(result.getText()); + } + + /** + * 获取远程网络图片信息 + * @param imageURL + * @return + */ + public static BufferedImage getRemoteBufferedImage(String imageURL) { + URL url; + InputStream is = null; + BufferedImage bufferedImage = null; + try { + url = new URL(imageURL); + is = url.openStream(); + bufferedImage = ImageIO.read(is); + } catch (MalformedURLException e) { + e.printStackTrace(); + System.out.println("imageURL: " + imageURL + ",无效!"); + return null; + } catch (IOException e) { + e.printStackTrace(); + System.out.println("imageURL: " + imageURL + ",读取失败!"); + return null; + } finally { + try { + if (is!=null) { + is.close(); + } + } catch (IOException e) { + e.printStackTrace(); + System.out.println("imageURL: " + imageURL + ",流关闭异常!"); + return null; + } + } + return bufferedImage; + } +} diff --git a/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/vo/QRCodeConfig.java b/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/vo/QRCodeConfig.java new file mode 100644 index 0000000..b6d59d7 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/qccode/vo/QRCodeConfig.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.framework.common.util.qccode.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + + +@Schema(description = "QRCodeConfig 二维码 vo") +@Data +@EqualsAndHashCode(callSuper = false) +@ToString(callSuper = true) +public class QRCodeConfig { + // 二维码内容 + @Schema(description = "二维码内容",defaultValue = "我是二维码的内容") + private String content; + + // 二维码的宽度 + @Schema(description = "二维码的宽度",defaultValue = "800") + private int width=800; + + // 二维码的高度 + @Schema(description = "二维码的高度",defaultValue = "800") + private int height=800; + + // 二维码的图片格式,如"png", "jpg"等 + @Schema(description = "二维码的高度",defaultValue = "png,jpg") + private String imageFormat="jpg"; + + // 附加资源或相关信息(具体含义根据项目需求定义) + /*private String resource;*/ +} diff --git a/ruoyi-vue-pro-master/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/LoginUser.java b/ruoyi-vue-pro-master/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/LoginUser.java index 68d1c56..ae8565b 100644 --- a/ruoyi-vue-pro-master/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/LoginUser.java +++ b/ruoyi-vue-pro-master/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/LoginUser.java @@ -19,6 +19,7 @@ public class LoginUser { public static final String INFO_KEY_NICKNAME = "nickname"; public static final String INFO_KEY_DEPT_ID = "deptId"; + public static final String INFO_KEY_MOBILE = "mobile"; /** * 用户编号 diff --git a/ruoyi-vue-pro-master/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/util/SecurityFrameworkUtils.java b/ruoyi-vue-pro-master/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/util/SecurityFrameworkUtils.java index f85d77c..88bf6ba 100644 --- a/ruoyi-vue-pro-master/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/util/SecurityFrameworkUtils.java +++ b/ruoyi-vue-pro-master/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/util/SecurityFrameworkUtils.java @@ -112,6 +112,17 @@ public class SecurityFrameworkUtils { 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; + } + /** * 设置当前用户 * diff --git a/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/pom.xml b/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/pom.xml index f2840cf..5b15541 100644 --- a/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/pom.xml +++ b/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/pom.xml @@ -124,6 +124,12 @@ org.apache.tika tika-core + + cn.iocoder.boot + yudao-module-system-biz + 2.1.0-jdk8-snapshot + compile + diff --git a/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/app/file/AppFileController.java b/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/app/file/AppFileController.java index 62755fc..c633ccc 100644 --- a/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/app/file/AppFileController.java +++ b/ruoyi-vue-pro-master/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/app/file/AppFileController.java @@ -1,21 +1,36 @@ package cn.iocoder.yudao.module.infra.controller.app.file; +import cn.hutool.core.codec.Base64; +import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; +import cn.hutool.core.lang.UUID; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.qccode.Base64Util; +import cn.iocoder.yudao.framework.common.util.qccode.QRCodeUtil; +import cn.iocoder.yudao.framework.common.util.qccode.vo.QRCodeConfig; import cn.iocoder.yudao.module.infra.controller.app.file.vo.AppFileUploadReqVO; import cn.iocoder.yudao.module.infra.service.file.FileService; +import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO; +import cn.iocoder.yudao.module.system.service.dict.DictDataService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; +import javax.validation.Valid; + +import java.io.*; +import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "用户 App - 文件存储") @RestController @@ -27,6 +42,9 @@ public class AppFileController { @Resource private FileService fileService; + @Resource + private DictDataService dictDataService; + @PostMapping("/upload") @Operation(summary = "上传文件") public CommonResult uploadFile(AppFileUploadReqVO uploadReqVO) throws Exception { @@ -35,4 +53,75 @@ public class AppFileController { return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream()))); } + @RequestMapping("/qrCode") + @Operation(summary = "生成二维码") + public CommonResult qrCode(@Valid QRCodeConfig qrCodeConfig) { + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + // 假设QRCodeUtil.createQrCode是一个正确实现的方法,用于生成二维码并写入到ByteArrayOutputStream中 + QRCodeUtil.createQrCode(out, qrCodeConfig.getContent(), qrCodeConfig.getWidth(), qrCodeConfig.getHeight(), qrCodeConfig.getImageFormat(), ""); // 使用PNG格式,不是JPG + // 创建文件,使用PNG扩展名,因为QR码是以PNG格式生成的 + File file = FileUtil.file(UUID.fastUUID()+"."+qrCodeConfig.getImageFormat()); // 注意文件扩展名应为.png + byte[] imageBytes = out.toByteArray(); + // 使用 FileOutputStream 将字节数组写入本地文件 + try (FileOutputStream fos = new FileOutputStream(file)) { + fos.write(imageBytes); + } + // 输出文件名和位置 + //System.out.println("文件名: " + file.getName()); + //System.out.println("文件位置: " + file.getAbsolutePath()); + // 假设fileService.createFile是一个正确实现的方法,用于在您的服务中创建文件记录 + // 读取文件内容并传递给createFile方法 + byte[] fileContent = IoUtil.readBytes(new FileInputStream(file)); // 使用FileInputStream读取文件内容 + String url = fileService.createFile(file.getName(), UUID.fastUUID()+"."+qrCodeConfig.getImageFormat(), fileContent); + out.close(); // 关闭ByteArrayOutputStream,虽然在这个上下文中它会在方法结束时自动关闭 + return success(url); + } catch (IOException e) { + e.printStackTrace(); // 适当的错误处理应该替换这一行,例如记录日志或向用户显示错误消息 + } + + return success(""); + } + + @RequestMapping("/qrCode64") + @Operation(summary = "生成二维码64") + public CommonResult qrCode64(@Valid String type) { + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + // 假设QRCodeUtil.createQrCode是一个正确实现的方法,用于生成二维码并写入到ByteArrayOutputStream中 + QRCodeConfig qrCodeConfig = new QRCodeConfig(); + QRCodeUtil.createQrCode(out, getString(type), qrCodeConfig.getWidth(), qrCodeConfig.getHeight(), qrCodeConfig.getImageFormat(), ""); // 使用PNG格式,不是JPG + // 创建文件,使用PNG扩展名,因为QR码是以PNG格式生成的 + String h5QrCode = new String(Base64Util.baseEncode(out.toByteArray()), "UTF-8"); + out.close(); // 关闭ByteArrayOutputStream,虽然在这个上下文中它会在方法结束时自动关闭 + return success(h5QrCode); + } catch (IOException e) { + e.printStackTrace(); // 适当的错误处理应该替换这一行,例如记录日志或向用户显示错误消息 + } + + return success(null); + } + + @RequestMapping("/qrCode64Url") + @Operation(summary = "生成Url") + public CommonResult qrCode64Url(@Valid String type) { + + // 创建文件,使用PNG扩展名,因为QR码是以PNG格式生成的 + return success( getString(type)); + + } + + private String getString(String type) { + String replace=null; + List list = dictDataService.getDictDataList( + CommonStatusEnum.ENABLE.getStatus(), "xcxscewm_type"); + Long loginUserId = getLoginUserId(); + for (DictDataDO dictDataDO : list) { + if (dictDataDO.getValue().equals(type)) { + replace = dictDataDO.getRemark().replace("{bindUserId}", loginUserId.toString()); + } + } + return replace; + } + } diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java index 3b19d61..a0cb259 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java @@ -124,5 +124,11 @@ public interface ErrorCodeConstants { // ========== 装修页面 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 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, "分销等级不在权限范围"); } diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/PrizeDrawController.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/PrizeDrawController.java new file mode 100644 index 0000000..79230eb --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/PrizeDrawController.java @@ -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 createPrizeDraw(@Valid @RequestBody PrizeDrawSaveReqVO createReqVO) { + return success(prizeDrawService.createPrizeDraw(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新抽奖活动") + @PreAuthorize("@ss.hasPermission('promotion:prize-draw:update')") + public CommonResult 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 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 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> getPrizeDrawPage(@Valid PrizeDrawPageReqVO pageReqVO) { + PageResult pageResult = prizeDrawService.getPrizeDrawPage(pageReqVO); + // 处理用户级别返显 + List 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 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> getActivityPrizeListByActivityId(@RequestParam("activityId") Long activityId) { + return success(prizeDrawService.getActivityPrizeListByActivityId(activityId)); + } + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawPageReqVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawPageReqVO.java new file mode 100644 index 0000000..3b2a278 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawPageReqVO.java @@ -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; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawRespVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawRespVO.java new file mode 100644 index 0000000..465d5e0 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawRespVO.java @@ -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; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawSaveReqVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawSaveReqVO.java new file mode 100644 index 0000000..5165284 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawSaveReqVO.java @@ -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 activityPrizes; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/PrizeLogController.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/PrizeLogController.java new file mode 100644 index 0000000..acf265f --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/PrizeLogController.java @@ -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 createPrizeLog(@Valid @RequestBody PrizeLogSaveReqVO createReqVO) { + return success(prizeLogService.createPrizeLog(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新抽奖记录") + @PreAuthorize("@ss.hasPermission('promotion:prize-log:update')") + public CommonResult 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 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 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> getPrizeLogPage(@Valid PrizeLogPageReqVO pageReqVO) { + PageResult pageResult = prizeLogService.getPrizeLogPage(pageReqVO); + // 拼接用户数据 + Map userMap = memberUserApi.getUserMap( + convertSet(pageResult.getList(), PrizeLogDO::getMebId)); + // 拼接活动数据 + Map 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 list = prizeLogService.getPrizeLogPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "抽奖记录.xls", "数据", PrizeLogRespVO.class, + BeanUtils.toBean(list, PrizeLogRespVO.class)); + } + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogPageReqVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogPageReqVO.java new file mode 100644 index 0000000..7db8eca --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogPageReqVO.java @@ -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; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogRespVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogRespVO.java new file mode 100644 index 0000000..63aee16 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogRespVO.java @@ -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; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogSaveReqVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogSaveReqVO.java new file mode 100644 index 0000000..1fc8442 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogSaveReqVO.java @@ -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; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/AppPrizeDrawController.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/AppPrizeDrawController.java new file mode 100644 index 0000000..d5fa9c4 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/AppPrizeDrawController.java @@ -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 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> getActivityPrizeListByActivityId(@RequestParam("activityId") Long activityId) { + return success(prizeDrawService.getActivityPrizeListByActivityId(activityId)); + } + @GetMapping("/lottery") + @Operation(summary = "用户APP--抽奖") + @Parameter(name = "activityId", description = "关联抽奖活动id") + public CommonResult 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()=prizeDraw.getDrawNum()){ + throw exception(PRIZE_LOG_NOT_DRAWNUM); + } + //抽奖 + ActivityPrizeDO activityPrizeDO = recursionLottery(prizeDraw); + return success(activityPrizeDO); + } + + private ActivityPrizeDO recursionLottery(PrizeDrawDO prizeDraw){ + //获取奖品信息 + List list = prizeDrawService.getActivityPrizeListByActivityId(prizeDraw.getId()); + //获取随机数 + int sortNum = (int) (Math.random() * ((8-list.size()) + 1)); + // TODO: 2023/8/16 0016 后台限制 + List> weightObjList = new ArrayList>(); + list.forEach(s -> { + weightObjList.add(new WeightRandom.WeightObj<>(s.getId().toString(), Double.valueOf(s.getPrizeChance()))); + }); + WeightRandom 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> getPrizeLogPage(@RequestParam("activityId") Long activityId) { + //获取活动信息 + PrizeDrawDO prizeDraw = prizeDrawService.getPrizeDraw(activityId); + List list = prizeLogService.getPrizeLogListByMebId(getLoginUserId(), prizeDraw); + return success(BeanUtils.toBean(list, PrizeLogRespVO.class)); + } +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawPageReqVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawPageReqVO.java new file mode 100644 index 0000000..9116361 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawPageReqVO.java @@ -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; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawRespVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawRespVO.java new file mode 100644 index 0000000..b9cfbbf --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawRespVO.java @@ -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; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawSaveReqVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawSaveReqVO.java new file mode 100644 index 0000000..fab22fa --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawSaveReqVO.java @@ -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 activityPrizes; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/prizedraw/PrizeDrawConvert.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/prizedraw/PrizeDrawConvert.java new file mode 100644 index 0000000..952c582 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/prizedraw/PrizeDrawConvert.java @@ -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 convertPage(PageResult page, + List levels) { + PageResult pageResult = convertPage(page); + Map 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 convertPage(PageResult page); +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/prizelog/PrizeLogConvert.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/prizelog/PrizeLogConvert.java new file mode 100644 index 0000000..58e3819 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/prizelog/PrizeLogConvert.java @@ -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 convertPage(PageResult page, + Map userMap, + Map prizeMap) { + PageResult 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 convertPage(PageResult page); +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizedraw/ActivityPrizeDO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizedraw/ActivityPrizeDO.java new file mode 100644 index 0000000..9fc93f6 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizedraw/ActivityPrizeDO.java @@ -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; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizedraw/PrizeDrawDO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizedraw/PrizeDrawDO.java new file mode 100644 index 0000000..5d755e8 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizedraw/PrizeDrawDO.java @@ -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; + /** + * 活动状态(0:开启;1关闭) + */ + private String status; + /** + * 开始时间 + */ + private LocalDateTime startTime; + /** + * 截至时间 + */ + private LocalDateTime endTime; + /** + * 会员等级 + */ + private Long mebLevel; + + /** + * 单人次抽奖次数 + */ + private Integer drawNum; +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizelog/PrizeLogDO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizelog/PrizeLogDO.java new file mode 100644 index 0000000..a543db0 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizelog/PrizeLogDO.java @@ -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; + /** + * 兑奖状态(0:已兑奖;1:未兑奖) + */ + private String status; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizedraw/ActivityPrizeMapper.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizedraw/ActivityPrizeMapper.java new file mode 100644 index 0000000..67830a5 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizedraw/ActivityPrizeMapper.java @@ -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 { + + default List selectListByActivityId(Long activityId) { + return selectList(ActivityPrizeDO::getActivityId, activityId); + } + + default int deleteByActivityId(Long activityId) { + return delete(ActivityPrizeDO::getActivityId, activityId); + } + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizedraw/PrizeDrawMapper.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizedraw/PrizeDrawMapper.java new file mode 100644 index 0000000..7b0f8d9 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizedraw/PrizeDrawMapper.java @@ -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 { + + default PageResult selectPage(PrizeDrawPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .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)); + } + +} \ No newline at end of file diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizelog/PrizeLogMapper.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizelog/PrizeLogMapper.java new file mode 100644 index 0000000..650d62e --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizelog/PrizeLogMapper.java @@ -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 { + + default PageResult selectPage(PrizeLogPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .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)); + } + +} \ No newline at end of file diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawService.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawService.java new file mode 100644 index 0000000..e57e2b8 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawService.java @@ -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 getPrizeDrawPage(PrizeDrawPageReqVO pageReqVO); + + // ==================== 子表(抽奖活动奖品) ==================== + + /** + * 获得抽奖活动奖品列表 + * + * @param activityId 关联抽奖活动id + * @return 抽奖活动奖品列表 + */ + List getActivityPrizeListByActivityId(Long activityId); + /** + * 获得抽奖活动奖品 + * + * @param id 奖品id + * @return 抽奖活动奖品列表 + */ + ActivityPrizeDO getActivityPrize(Long id); + + /** + * 获得已开启抽奖活动 + * + * @return 抽奖活动 + */ + PrizeDrawDO getOnePrizeDraw(); + + + /** + * 获得活动 Map + * + * @param ids 活动id的数组 + * @return 活动 Map + */ + default Map getPrizeDrawMap(Collection ids) { + List list = getPrizeDrawDOList(ids); + return convertMap(list, PrizeDrawDO::getId); + } + + /** + * 获得活动信息 + * + * @param ids 用户编号的数组 + * @return 用户信息们 + */ + List getPrizeDrawDOList(Collection ids); +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawServiceImpl.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawServiceImpl.java new file mode 100644 index 0000000..7304758 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawServiceImpl.java @@ -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 getPrizeDrawPage(PrizeDrawPageReqVO pageReqVO) { + return prizeDrawMapper.selectPage(pageReqVO); + } + + // ==================== 子表(抽奖活动奖品) ==================== + + @Override + public List getActivityPrizeListByActivityId(Long activityId) { + return activityPrizeMapper.selectListByActivityId(activityId); + } + + private void createActivityPrizeList(Long activityId, List list) { + list.forEach(o -> o.setActivityId(activityId)); + activityPrizeMapper.insertBatch(list); + } + + private void updateActivityPrizeList(Long activityId, List list) { + deleteActivityPrizeByActivityId(activityId); + list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下:1)id 冲突;2)updateTime 不更新 + createActivityPrizeList(activityId, list); + } + + private void deleteActivityPrizeByActivityId(Long activityId) { + activityPrizeMapper.deleteByActivityId(activityId); + } + + + @Override + public PrizeDrawDO getOnePrizeDraw() { + return prizeDrawMapper.selectOne(new LambdaQueryWrapperX() + .eq(PrizeDrawDO::getStatus, 0) + ); + } + + @Override + public List getPrizeDrawDOList(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return ListUtil.empty(); + } + return prizeDrawMapper.selectBatchIds(ids); + } + + @Override + public ActivityPrizeDO getActivityPrize(Long id) { + return activityPrizeMapper.selectById(id); + } + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogService.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogService.java new file mode 100644 index 0000000..d29ac07 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogService.java @@ -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 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 getPrizeLogListByMebId(Long mebId,PrizeDrawDO prizeDraw); + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogServiceImpl.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogServiceImpl.java new file mode 100644 index 0000000..410f7e7 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogServiceImpl.java @@ -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 getPrizeLogPage(PrizeLogPageReqVO pageReqVO) { + return prizeLogMapper.selectPage(pageReqVO); + } + + @Override + public Long getPrizeLogByMebIdList(Long mebId,PrizeDrawDO prizeDraw) { + return prizeLogMapper.selectCount(new LambdaQueryWrapperX() + .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() + .eq(PrizeLogDO::getPrizeId,prizeId) + .ge(PrizeLogDO::getCreateTime, prizeDraw.getStartTime()) + .le(PrizeLogDO::getCreateTime, prizeDraw.getEndTime()) + ); + } + + @Override + public List getPrizeLogListByMebId(Long mebId,PrizeDrawDO prizeDraw) { + return prizeLogMapper.selectList(new LambdaQueryWrapperX() + .eq(PrizeLogDO::getMebId, mebId) + .ge(PrizeLogDO::getCreateTime, prizeDraw.getStartTime()) + .le(PrizeLogDO::getCreateTime, prizeDraw.getEndTime()) + ); + } + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/prizedraw/PrizeDrawMapper.xml b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/prizedraw/PrizeDrawMapper.xml new file mode 100644 index 0000000..3fa77d9 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/prizedraw/PrizeDrawMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/prizelog/PrizeLogMapper.xml b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/prizelog/PrizeLogMapper.xml new file mode 100644 index 0000000..a96a198 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/prizelog/PrizeLogMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawServiceImplTest.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawServiceImplTest.java new file mode 100644 index 0000000..e9395ce --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawServiceImplTest.java @@ -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 pageResult = prizeDrawService.getPrizeDrawPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbPrizeDraw, pageResult.getList().get(0)); + } + +} \ No newline at end of file diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogServiceImplTest.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogServiceImplTest.java new file mode 100644 index 0000000..4f94756 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogServiceImplTest.java @@ -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 pageResult = prizeLogService.getPrizeLogPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbPrizeLog, pageResult.getList().get(0)); + } + +} \ No newline at end of file diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql index 6a1a242..993e5d7 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql @@ -9,4 +9,6 @@ DELETE FROM "promotion_combination_activity"; DELETE FROM "promotion_article_category"; DELETE FROM "promotion_article"; DELETE FROM "promotion_diy_template"; -DELETE FROM "promotion_diy_page"; \ No newline at end of file +DELETE FROM "promotion_diy_page"; +DELETE FROM "promotion_prize_draw"; +DELETE FROM "promotion_prize_log"; diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql index 00ac3f9..6227cb4 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql @@ -253,4 +253,39 @@ CREATE TABLE IF NOT EXISTS "promotion_diy_page" "deleted" bit NOT NULL DEFAULT FALSE, "tenant_id" bigint NOT NULL, PRIMARY KEY ("id") -) COMMENT '装修页面'; \ No newline at end of file +) 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 '抽奖记录表'; diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java index 58acde4..9c9b973 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.admin.order; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; 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.dto.MemberUserRespDTO; 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.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.*; @Tag(name = "管理后台 - 交易订单") @RestController @@ -153,7 +155,10 @@ public class TradeOrderController { @Parameter(name = "pickUpVerifyCode", description = "自提核销码") @PreAuthorize("@ss.hasPermission('trade:order:pick-up')") public CommonResult 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); } diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index 762b238..6c8b745 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -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.PageResult; +import cn.iocoder.yudao.framework.security.core.LoginUser; 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.trade.controller.app.order.vo.*; 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.order.TradeOrderQueryService; import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.google.common.collect.Maps; import io.swagger.v3.oas.annotations.Operation; 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.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; @Tag(name = "用户 App - 交易订单") @@ -54,6 +58,9 @@ public class AppTradeOrderController { @Resource private TradeOrderProperties tradeOrderProperties; + @Resource + private MemberUserApi memberUserApi; + @GetMapping("/settlement") @Operation(summary = "获得订单结算信息") @PreAuthenticated @@ -65,6 +72,9 @@ public class AppTradeOrderController { @Operation(summary = "创建订单") @PreAuthenticated public CommonResult 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); return success(new AppTradeOrderCreateRespVO().setId(order.getId()).setPayOrderId(order.getPayOrderId())); } @@ -74,6 +84,8 @@ public class AppTradeOrderController { public CommonResult updateOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) { tradeOrderUpdateService.updateOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayOrderId()); +// memberUserApi.updateUserUpgradesLevel(); + return success(true); } @@ -116,6 +128,13 @@ public class AppTradeOrderController { return success(TradeOrderConvert.INSTANCE.convertPage02(pageResult, orderItems)); } + @GetMapping("/getPickUpVerifyCode") + @Operation(summary = "根据订单id获取自提核销码") + public CommonResult getPickUpVerifyCode(String id) { + String pickUpVerifyCode = tradeOrderQueryService.getPickUpVerifyCode(id); + return success(pickUpVerifyCode); + } + @GetMapping("/get-count") @Operation(summary = "获得交易订单数量") public CommonResult> getOrderCount() { diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java index ba7b813..4e7cfc3 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java @@ -1,6 +1,7 @@ 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.dal.dataobject.delivery.DeliveryPickUpStoreDO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -45,6 +46,19 @@ public class AppTradeOrderPageItemRespVO { @Schema(description = "配送方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 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; + /** * 订单项数组 */ diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageUserDO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageUserDO.java index 8d73858..1be8990 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageUserDO.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageUserDO.java @@ -59,4 +59,8 @@ public class BrokerageUserDO extends BaseDO { * 冻结佣金 */ private Integer frozenPrice; + /** + * 会员等级 + */ + private Integer level; } diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java index 10b07ce..b95cf7e 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java @@ -130,6 +130,7 @@ public class TradeOrderItemDO extends BaseDO { */ private Integer payPrice; + // ========== 营销基本信息 ========== /** diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java index 6c24cac..f7989f5 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java @@ -53,6 +53,20 @@ public interface BrokerageUserMapper extends BaseMapperX { update(null, lambdaUpdateWrapper); } + /** + * 更新用户可用佣金(增加) + * + * @param id 用户编号 + * @param incrCount 增加佣金(正数) + */ + default void updateUserPriceByBindUserIdIncr(Long id, Integer incrCount) { + Assert.isTrue(incrCount > 0); + LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() + .setSql(" brokerage_price = brokerage_price + " + incrCount) + .eq(BrokerageUserDO::getBindUserId, id); + update(null, lambdaUpdateWrapper); + } + /** * 更新用户可用佣金(减少) * 注意:理论上佣金可能已经提现,这时会扣出负数,确保平台不会造成损失 @@ -69,6 +83,22 @@ public interface BrokerageUserMapper extends BaseMapperX { return update(null, lambdaUpdateWrapper); } + /** + * 更新用户可用佣金(减少) + * 注意:理论上佣金可能已经提现,这时会扣出负数,确保平台不会造成损失 + * + * @param id 用户编号 + * @param incrCount 增加佣金(负数) + * @return 更新行数 + */ + default int updateUserPriceByBindUserIdDecr(Long id, Integer incrCount) { + Assert.isTrue(incrCount < 0); + LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() + .setSql(" brokerage_price = brokerage_price + " + incrCount) // 负数,所以使用 + 号 + .eq(BrokerageUserDO::getBindUserId, id); + return update(null, lambdaUpdateWrapper); + } + /** * 更新用户冻结佣金(增加) * diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java index 21fc038..f5848ec 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java @@ -124,4 +124,7 @@ public interface TradeOrderMapper extends BaseMapperX { ); } + default String getPickUpVerifyCode(String id){ + return selectOne(TradeOrderDO::getId, id).getPickUpVerifyCode(); + }; } diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserService.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserService.java index e5b7e7a..5c1a682 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserService.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserService.java @@ -76,6 +76,16 @@ public interface BrokerageUserService { */ boolean updateUserPrice(Long id, Integer price); + + /** + * 更新用户佣金 + * + * @param id 用户编号 + * @param price 用户可用佣金 + * @return 更新结果 + */ + boolean updateUserPriceByBindUserId(Long id, Integer price); + /** * 更新用户冻结佣金 * diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java index ff958a8..6416e12 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.BooleanUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; @@ -137,6 +138,16 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { 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 public void updateUserFrozenPrice(Long id, Integer frozenPrice) { if (frozenPrice > 0) { @@ -296,27 +307,29 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { private void validateCanBindUser(BrokerageUserDO user, Long bindUserId) { // 校验要绑定的用户有无推广资格 BrokerageUserDO bindUser = brokerageUserMapper.selectById(bindUserId); - if (bindUser == null || BooleanUtil.isFalse(bindUser.getBrokerageEnabled())) { + /*if (bindUser == null || BooleanUtil.isFalse(bindUser.getBrokerageEnabled())) { throw exception(BROKERAGE_BIND_USER_NOT_ENABLED); - } + }*/ // 校验绑定自己 - if (Objects.equals(user.getId(), bindUserId)) { + /* if (Objects.equals(user.getId(), bindUserId)) { throw exception(BROKERAGE_BIND_SELF); + }*/ +if(ObjectUtil.isNotEmpty(bindUser)){ + // 下级不能绑定自己的上级 + for (int i = 0; i <= Short.MAX_VALUE; i++) { + if (Objects.equals(bindUser.getBindUserId(), user.getId())) { + throw exception(BROKERAGE_BIND_LOOP); } - - // 下级不能绑定自己的上级 - for (int i = 0; i <= Short.MAX_VALUE; i++) { - if (Objects.equals(bindUser.getBindUserId(), user.getId())) { - throw exception(BROKERAGE_BIND_LOOP); - } - bindUser = getBrokerageUser(bindUser.getBindUserId()); - // 找到根节点,结束循环 - if (bindUser == null || bindUser.getBindUserId() == null) { - break; - } + bindUser = getBrokerageUser(bindUser.getBindUserId()); + // 找到根节点,结束循环 + if (bindUser == null || bindUser.getBindUserId() == null) { + break; } } +} + + } /** * 根据绑定用户编号,获得下级用户编号列表 diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java index 4457922..dd446f1 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java @@ -155,4 +155,5 @@ public interface TradeOrderQueryService { */ List getOrderItemListByOrderId(Collection orderIds); + String getPickUpVerifyCode(String id); } diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java index 0c1f696..1750772 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java @@ -248,6 +248,11 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService { return tradeOrderItemMapper.selectListByOrderId(orderIds); } + @Override + public String getPickUpVerifyCode(String id) { + return tradeOrderMapper.getPickUpVerifyCode(id); + } + /** * 获得自身的代理对象,解决 AOP 生效问题 * diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java index 9f3c6cf..fb27cf7 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java @@ -126,8 +126,9 @@ public interface TradeOrderUpdateService { * 【管理员】核销订单 * * @param pickUpVerifyCode 自提核销码 + * @param id 用户id */ - void pickUpOrderByAdmin(String pickUpVerifyCode); + void pickUpOrderByAdmin(Long id, String pickUpVerifyCode); /** * 【管理员】根据自提核销码,查询订单 diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java index 75323a7..5754eba 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java @@ -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.core.annotations.TradeOrderLog; 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.delivery.DeliveryExpressService; import cn.iocoder.yudao.module.trade.service.message.TradeMessageService; @@ -107,6 +108,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @Resource private TradeOrderProperties tradeOrderProperties; + @Resource + private BrokerageUserService brokerageUserService; + + // =================== Order =================== @Override @@ -679,7 +684,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @Override @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)); } diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApi.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApi.java index 5876837..222e667 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApi.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApi.java @@ -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.enums.MemberExperienceBizTypeEnum; +import java.util.Collection; +import java.util.List; + /** * 会员等级 API 接口 * @@ -38,4 +41,11 @@ public interface MemberLevelApi { */ void reduceExperience(Long userId, Integer experience, Integer bizType, String bizId); + /** + * 获得会员等级列表 + * + * @param ids 编号 + * @return 会员等级列表 + */ + List getLevelList(Collection ids); } diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java index c9fb801..386b57f 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java @@ -57,4 +57,19 @@ public interface MemberUserApi { * @return 用户信息 */ MemberUserRespDTO getUserByMobile(String mobile); + + /** + * 注册帮扶人 + * + * @param userId 用户编号 + * @return 更新结果 + */ + boolean updateUserLevelId(Long userId); + /** + * 购买1188升级帮扶员 + * + * @param userId 用户编号 + * @return 更新结果 + */ + void updateUserUpgradesLevel(Long userId); } diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/pom.xml b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/pom.xml index 3c9b81e..1a38c75 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/pom.xml +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/pom.xml @@ -85,6 +85,12 @@ cn.iocoder.boot yudao-spring-boot-starter-biz-ip + + cn.iocoder.boot + yudao-module-trade-biz + 2.1.0-jdk8-snapshot + compile + diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApiImpl.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApiImpl.java index 79fed98..8a6e566 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApiImpl.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApiImpl.java @@ -1,5 +1,6 @@ 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.convert.level.MemberLevelConvert; import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; @@ -9,6 +10,9 @@ import org.springframework.validation.annotation.Validated; 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.module.member.enums.ErrorCodeConstants.EXPERIENCE_BIZ_NOT_SUPPORT; @@ -43,4 +47,9 @@ public class MemberLevelApiImpl implements MemberLevelApi { addExperience(userId, -experience, bizType, bizId); } + @Override + public List getLevelList(Collection ids) { + return BeanUtils.toBean(memberLevelService.getLevelList(ids),MemberLevelRespDTO.class); + } + } diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java index 8da857c..a38703d 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java @@ -44,4 +44,15 @@ public class MemberUserApiImpl implements MemberUserApi { 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); + } + + } diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthWeixinMiniAppLoginReqVO.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthWeixinMiniAppLoginReqVO.java index b14f182..5c14883 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthWeixinMiniAppLoginReqVO.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthWeixinMiniAppLoginReqVO.java @@ -27,4 +27,9 @@ public class AppAuthWeixinMiniAppLoginReqVO { @NotEmpty(message = "state 不能为空") private String state; + + + @Schema(description = "bindUserId") + private Long bindUserId; + } diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java index 3a268e8..dbe2f56 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java @@ -38,7 +38,9 @@ public class AppMemberUserController { public CommonResult getUserInfo() { MemberUserDO user = userService.getUser(getLoginUserId()); MemberLevelDO level = levelService.getLevel(user.getLevelId()); - return success(MemberUserConvert.INSTANCE.convert(user, level)); + AppMemberUserInfoRespVO convert = MemberUserConvert.INSTANCE.convert(user, level); + convert.setId(getLoginUserId()+""); + return success(convert); } @PutMapping("/update") diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppMemberUserInfoRespVO.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppMemberUserInfoRespVO.java index fa05e16..cf9d8f2 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppMemberUserInfoRespVO.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppMemberUserInfoRespVO.java @@ -10,6 +10,8 @@ import lombok.NoArgsConstructor; @NoArgsConstructor @AllArgsConstructor public class AppMemberUserInfoRespVO { + @Schema(description = "id") + private String id; @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") private String nickname; diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/user/MemberUserConvert.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/user/MemberUserConvert.java index aae9a76..e2670bf 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/user/MemberUserConvert.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/user/MemberUserConvert.java @@ -29,6 +29,7 @@ public interface MemberUserConvert { @Mapping(source = "level", target = "level") @Mapping(source = "bean.experience", target = "experience") + @Mapping(source = "bean.id",target = "id") AppMemberUserInfoRespVO convert(MemberUserDO bean, MemberLevelDO level); MemberUserRespDTO convert2(MemberUserDO bean); diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java index e1a8ec5..8bb801c 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.service.auth; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.TerminalEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; @@ -27,6 +28,9 @@ import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants; import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO; +import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageUserMapper; +import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -61,6 +65,13 @@ public class MemberAuthServiceImpl implements MemberAuthService { @Resource private OAuth2TokenApi oauth2TokenApi; + @Resource + private BrokerageUserService brokerageUserService; + + + @Resource + private BrokerageUserMapper brokerageUserMapper; + @Override public AppAuthLoginRespVO login(AppAuthLoginReqVO reqVO) { // 使用手机 + 密码,进行登录。 @@ -69,8 +80,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { // 如果 socialType 非空,说明需要绑定社交用户 String openid = null; if (reqVO.getSocialType() != null) { - openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), - reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); + openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); } // 创建 Token 令牌,记录登录日志 @@ -97,8 +107,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { // 如果 socialType 非空,说明需要绑定社交用户 String openid = null; if (reqVO.getSocialType() != null) { - openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), - reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); + openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); } // 创建 Token 令牌,记录登录日志 @@ -109,8 +118,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { @Transactional public AppAuthLoginRespVO socialLogin(AppAuthSocialLoginReqVO reqVO) { // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 - SocialUserRespDTO socialUser = socialUserApi.getSocialUserByCode(UserTypeEnum.MEMBER.getValue(), reqVO.getType(), - reqVO.getCode(), reqVO.getState()); + SocialUserRespDTO socialUser = socialUserApi.getSocialUserByCode(UserTypeEnum.MEMBER.getValue(), reqVO.getType(), reqVO.getCode(), reqVO.getState()); if (socialUser == null) { throw exception(AUTH_SOCIAL_USER_NOT_FOUND); } @@ -119,11 +127,10 @@ public class MemberAuthServiceImpl implements MemberAuthService { MemberUserDO user; if (socialUser.getUserId() != null) { user = userService.getUser(socialUser.getUserId()); - // 情况二:未绑定,注册用户 + 绑定用户 + // 情况二:未绑定,注册用户 + 绑定用户 } else { user = userService.createUser(socialUser.getNickname(), socialUser.getAvatar(), getClientIP(), getTerminal()); - socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), - reqVO.getType(), reqVO.getCode(), reqVO.getState())); + socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), reqVO.getType(), reqVO.getCode(), reqVO.getState())); } if (user == null) { throw exception(USER_NOT_EXISTS); @@ -136,31 +143,35 @@ public class MemberAuthServiceImpl implements MemberAuthService { @Override public AppAuthLoginRespVO weixinMiniAppLogin(AppAuthWeixinMiniAppLoginReqVO reqVO) { // 获得对应的手机号信息 - SocialWxPhoneNumberInfoRespDTO phoneNumberInfo = socialClientApi.getWxMaPhoneNumberInfo( - UserTypeEnum.MEMBER.getValue(), reqVO.getPhoneCode()); + SocialWxPhoneNumberInfoRespDTO phoneNumberInfo = socialClientApi.getWxMaPhoneNumberInfo(UserTypeEnum.MEMBER.getValue(), reqVO.getPhoneCode()); Assert.notNull(phoneNumberInfo, "获得手机信息失败,结果为空"); // 获得获得注册用户 - MemberUserDO user = userService.createUserIfAbsent(phoneNumberInfo.getPurePhoneNumber(), - getClientIP(), TerminalEnum.WECHAT_MINI_PROGRAM.getTerminal()); + MemberUserDO user = userService.createUserIfAbsent(phoneNumberInfo.getPurePhoneNumber(), getClientIP(), TerminalEnum.WECHAT_MINI_PROGRAM.getTerminal()); Assert.notNull(user, "获取用户失败,结果为空"); // 绑定社交用户 - String openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), - SocialTypeEnum.WECHAT_MINI_APP.getType(), reqVO.getLoginCode(), reqVO.getState())); + String openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), SocialTypeEnum.WECHAT_MINI_APP.getType(), reqVO.getLoginCode(), reqVO.getState())); + BrokerageUserDO brokerageUserDO = brokerageUserMapper.selectById(user.getId()); + + if (ObjectUtil.isEmpty(brokerageUserDO) && ObjectUtil.isNotEmpty(reqVO.getBindUserId())) { + brokerageUserService.bindBrokerageUser(user.getId(), reqVO.getBindUserId()); + } else { + if (ObjectUtil.isEmpty(brokerageUserDO)) { + brokerageUserService.bindBrokerageUser(user.getId(), 0L); + } + } + //绑定分销用户 // 创建 Token 令牌,记录登录日志 return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, openid); } - private AppAuthLoginRespVO createTokenAfterLoginSuccess(MemberUserDO user, String mobile, - LoginLogTypeEnum logType, String openid) { + private AppAuthLoginRespVO createTokenAfterLoginSuccess(MemberUserDO user, String mobile, LoginLogTypeEnum logType, String openid) { // 插入登陆日志 createLoginLog(user.getId(), mobile, logType, LoginResultEnum.SUCCESS); // 创建 Token 令牌 - OAuth2AccessTokenRespDTO accessTokenRespDTO = oauth2TokenApi.createAccessToken(new OAuth2AccessTokenCreateReqDTO() - .setUserId(user.getId()).setUserType(getUserType().getValue()) - .setClientId(OAuth2ClientConstants.CLIENT_ID_DEFAULT)); + OAuth2AccessTokenRespDTO accessTokenRespDTO = oauth2TokenApi.createAccessToken(new OAuth2AccessTokenCreateReqDTO().setUserId(user.getId()).setUserType(getUserType().getValue()).setClientId(OAuth2ClientConstants.CLIENT_ID_DEFAULT)); // 构建返回结果 return AuthConvert.INSTANCE.convert(accessTokenRespDTO, openid); } @@ -253,8 +264,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { @Override public AppAuthLoginRespVO refreshToken(String refreshToken) { - OAuth2AccessTokenRespDTO accessTokenDO = oauth2TokenApi.refreshAccessToken(refreshToken, - OAuth2ClientConstants.CLIENT_ID_DEFAULT); + OAuth2AccessTokenRespDTO accessTokenDO = oauth2TokenApi.refreshAccessToken(refreshToken, OAuth2ClientConstants.CLIENT_ID_DEFAULT); return AuthConvert.INSTANCE.convert(accessTokenDO, null); } diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java index fb2e9cd..23aeaf8 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java @@ -186,5 +186,19 @@ public interface MemberUserService { * @return 更新结果 */ boolean updateUserPoint(Long userId, Integer point); + /** + * 注册帮扶人 + * + * @param userId 用户编号 + * @return 更新结果 + */ + boolean updateUserLevelId(Long userId); + /** + * 购买1188升级帮扶员 + * + * @param userId 用户编号 + * @return 更新结果 + */ + void updateUserUpgradesLevel(Long userId); } diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java index f81e9a1..189cd8e 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java @@ -8,12 +8,16 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.MemberUserUpdateReqVO; 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.user.MemberUserConvert; +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.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.mq.producer.user.MemberUserProducer; import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; @@ -21,6 +25,9 @@ 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.dto.SocialWxPhoneNumberInfoRespDTO; import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO; +import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageUserMapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.google.common.annotations.VisibleForTesting; import lombok.extern.slf4j.Slf4j; import org.springframework.security.crypto.password.PasswordEncoder; @@ -64,6 +71,15 @@ public class MemberUserServiceImpl implements MemberUserService { @Resource private MemberUserProducer memberUserProducer; + @Resource + private MemberLevelRecordMapper levelLogMapper; + + @Resource + private MemberLevelMapper memberLevelMapper; + + @Resource + private BrokerageUserMapper brokerageUserMapper; + @Override public MemberUserDO getUserByMobile(String mobile) { return memberUserMapper.selectByMobile(mobile); @@ -314,4 +330,141 @@ public class MemberUserServiceImpl implements MemberUserService { return true; } + @Override + public boolean updateUserLevelId(Long userId) { + //查询帮扶人等级id + MemberLevelDO memberLevelDO = memberLevelMapper.selectOne(new LambdaQueryWrapperX() + .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) { + recursionMemberLevel(userId); +// if(i>0){ +// return true; +// } + } + + private void recursionMemberLevel(Long userId){ + //查询会员信息 + MemberUserDO memberUserDO = memberUserMapper.selectById(userId); + //查询会员当前等级 + MemberLevelDO memberLevelDO = memberLevelMapper.selectById(memberUserDO.getLevelId()); + if(ObjectUtil.isNotEmpty(memberLevelDO)){ + //查询上一级会员等级 + MemberLevelDO upLevelDO = memberLevelMapper.selectOne(new LambdaQueryWrapperX() + .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)){//帮扶人升级帮扶员 + //添加分润 + //升级会员 + //修改会员等级 + 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()); + } + if(ObjectUtil.equal(memberLevelDO.getLevel(),2)){//帮扶员升级帮扶大使 + //查询会员邀请记录下级会员 + List brokerageUserDOS = brokerageUserMapper.selectList(new LambdaQueryWrapperX() + .eq(BrokerageUserDO::getBindUserId, userId) + .eq(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()); + } + if(ObjectUtil.equal(memberLevelDO.getLevel(),3)){//帮扶大使升级帮扶中心 + //查询会员邀请记录下级会员 + List brokerageUserDOS = brokerageUserMapper.selectList(new LambdaQueryWrapperX() + .eq(BrokerageUserDO::getBindUserId, userId) + .eq(BrokerageUserDO::getLevel, memberLevelDO.getLevel()) + .eq(BrokerageUserDO::getDeleted, 0) + ); + if(ObjectUtil.isNotEmpty(brokerageUserDOS)){ + if(brokerageUserDOS.size()>=5){ + //升级会员 + 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()); + } + if(ObjectUtil.equal(memberLevelDO.getLevel(),4)){//帮扶中心升级帮扶驿站 + //查询会员邀请记录下级会员 + List brokerageUserDOS = brokerageUserMapper.selectList(new LambdaQueryWrapperX() + .eq(BrokerageUserDO::getBindUserId, userId) + .eq(BrokerageUserDO::getLevel, memberLevelDO.getLevel()) + .eq(BrokerageUserDO::getDeleted, 0) + ); + if(ObjectUtil.isNotEmpty(brokerageUserDOS)){ + if(brokerageUserDOS.size()>=10){ + //升级会员 + 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()); + } + if(ObjectUtil.equal(memberLevelDO.getLevel(),5)){//帮扶驿站---最终级别 + + } + } + } + } } diff --git a/ruoyi-vue-pro-master/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java b/ruoyi-vue-pro-master/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java index 58834fb..6ca926c 100644 --- a/ruoyi-vue-pro-master/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java +++ b/ruoyi-vue-pro-master/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java @@ -33,6 +33,7 @@ public class PayDemoOrderController { @Resource private PayDemoOrderService payDemoOrderService; + @PostMapping("/create") @Operation(summary = "创建示例订单") public CommonResult createDemoOrder(@Valid @RequestBody PayDemoOrderCreateReqVO createReqVO) { @@ -52,6 +53,8 @@ public class PayDemoOrderController { public CommonResult updateDemoOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) { payDemoOrderService.updateDemoOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayOrderId()); + + return success(true); } diff --git a/ruoyi-vue-pro-master/yudao-module-system/yudao-module-system-biz/pom.xml b/ruoyi-vue-pro-master/yudao-module-system/yudao-module-system-biz/pom.xml index 6de1a58..0b87984 100644 --- a/ruoyi-vue-pro-master/yudao-module-system/yudao-module-system-biz/pom.xml +++ b/ruoyi-vue-pro-master/yudao-module-system/yudao-module-system-biz/pom.xml @@ -127,6 +127,12 @@ com.xingyuv spring-boot-starter-captcha-plus + + cn.iocoder.boot + yudao-module-trade-biz + 2.1.0-jdk8-snapshot + compile + diff --git a/ruoyi-vue-pro-master/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java b/ruoyi-vue-pro-master/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java index d2cfa71..89852ae 100644 --- a/ruoyi-vue-pro-master/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java +++ b/ruoyi-vue-pro-master/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java @@ -178,7 +178,8 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { if (userType.equals(UserTypeEnum.ADMIN.getValue())) { AdminUserDO user = adminUserService.getUser(userId); 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())) { // 注意:目前 Member 暂时不读取,可以按需实现 return Collections.emptyMap(); diff --git a/ruoyi-vue-pro-master/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java b/ruoyi-vue-pro-master/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java index 7458d9c..d95254b 100644 --- a/ruoyi-vue-pro-master/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java +++ b/ruoyi-vue-pro-master/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java @@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserMapper; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; +import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService; import com.xingyuv.jushauth.model.AuthUser; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -46,6 +47,8 @@ public class SocialUserServiceImpl implements SocialUserService { @Resource private SocialClientService socialClientService; + + @Override public List getSocialUserList(Long userId, Integer userType) { // 获得绑定 @@ -77,6 +80,8 @@ public class SocialUserServiceImpl implements SocialUserService { .userId(reqDTO.getUserId()).userType(reqDTO.getUserType()) .socialUserId(socialUser.getId()).socialType(socialUser.getType()).build(); socialUserBindMapper.insert(socialUserBind); + //创建绑定用户 + return socialUser.getOpenid(); } diff --git a/yudao-mall-uniapp-master/.env.development b/yudao-mall-uniapp-master/.env.development index eff223b..def1cc3 100644 --- a/yudao-mall-uniapp-master/.env.development +++ b/yudao-mall-uniapp-master/.env.development @@ -1 +1,2 @@ - SHOPRO_DEV_BASE_URL = http://192.168.0.135:48080 \ No newline at end of file + # SHOPRO_DEV_BASE_URL = https://yanghaodong.51vip.biz + SHOPRO_DEV_BASE_URL = http://192.168.1.129:48080 \ No newline at end of file diff --git a/yudao-mall-uniapp-master/pages.json b/yudao-mall-uniapp-master/pages.json index e712b3d..406a407 100644 --- a/yudao-mall-uniapp-master/pages.json +++ b/yudao-mall-uniapp-master/pages.json @@ -261,6 +261,42 @@ "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", "style": { diff --git a/yudao-mall-uniapp-master/pages/index/index.vue b/yudao-mall-uniapp-master/pages/index/index.vue index 208c959..e1f87dd 100644 --- a/yudao-mall-uniapp-master/pages/index/index.vue +++ b/yudao-mall-uniapp-master/pages/index/index.vue @@ -51,10 +51,15 @@ onLoad((options) => { // #ifdef MP // 小程序识别二维码 - if (options.scene) { - const sceneParams = decodeURIComponent(options.scene).split('='); + if (options.q) { + const sceneParams = decodeURIComponent(options.q).split('='); console.log("sceneParams=>",sceneParams); options[sceneParams[0]] = sceneParams[1]; + console.log(options,'1123456'); + uni.setStorageSync('bindUserId', sceneParams[1]); + } + if (options.r) { + uni.setStorageSync('bindUserId', options.r); } // #endif diff --git a/yudao-mall-uniapp-master/pages/user/ActivityRules.vue b/yudao-mall-uniapp-master/pages/user/ActivityRules.vue new file mode 100644 index 0000000..955d7c1 --- /dev/null +++ b/yudao-mall-uniapp-master/pages/user/ActivityRules.vue @@ -0,0 +1,39 @@ + + + + + diff --git a/yudao-mall-uniapp-master/pages/user/PrizesWon.vue b/yudao-mall-uniapp-master/pages/user/PrizesWon.vue new file mode 100644 index 0000000..2f3cd5a --- /dev/null +++ b/yudao-mall-uniapp-master/pages/user/PrizesWon.vue @@ -0,0 +1,186 @@ + + + + + diff --git a/yudao-mall-uniapp-master/pages/user/prize.vue b/yudao-mall-uniapp-master/pages/user/prize.vue new file mode 100644 index 0000000..8b0b277 --- /dev/null +++ b/yudao-mall-uniapp-master/pages/user/prize.vue @@ -0,0 +1,421 @@ + + + + + diff --git a/yudao-mall-uniapp-master/sheep/api/member/auth.js b/yudao-mall-uniapp-master/sheep/api/member/auth.js index a1c0660..875dd0f 100644 --- a/yudao-mall-uniapp-master/sheep/api/member/auth.js +++ b/yudao-mall-uniapp-master/sheep/api/member/auth.js @@ -103,7 +103,8 @@ const AuthUtil = { data: { phoneCode, loginCode, - state + state, + bindUserId: uni.getStorageSync('bindUserId') || '', }, custom: { showSuccess: true, diff --git a/yudao-mall-uniapp-master/sheep/api/migration/third.js b/yudao-mall-uniapp-master/sheep/api/migration/third.js index 85db8cc..0d0782a 100644 --- a/yudao-mall-uniapp-master/sheep/api/migration/third.js +++ b/yudao-mall-uniapp-master/sheep/api/migration/third.js @@ -20,12 +20,17 @@ export default { // 获取微信小程序码 getWxacode: async (path, query) => { return await request({ - url: '/member/social-user/wxa-qrcode', - method: 'POST', + url: '/infra/file/qrCode64', + method: 'GET', data: { - scene: query, - path, - checkPath: false, // TODO 开发环境暂不检查 path 是否存在 + // scene: query, + // path, + // checkPath: false, // TODO 开发环境暂不检查 path 是否存在 + // content: 'http://cdz.huamar.com/zdfs?bindUserId=12345', + type: '1', + // width: 800, + // height: 800, + // imageFormat: 'png', }, }); }, diff --git a/yudao-mall-uniapp-master/sheep/api/prize/index.js b/yudao-mall-uniapp-master/sheep/api/prize/index.js new file mode 100644 index 0000000..6210c2c --- /dev/null +++ b/yudao-mall-uniapp-master/sheep/api/prize/index.js @@ -0,0 +1,43 @@ +import request from '@/sheep/request'; + +const PayOrderApi = { + + // 开始抽奖 + lottery: (id) => { + return request({ + url: '/promotion/prize-draw/lottery', + method: 'GET', + params: { activityId: id }, + }); + }, + // 已获奖品 + PrizesWon: (id) => { + return request({ + url: '/promotion/prize-draw/getMyPrizeLogDO', + method: 'GET', + params: { activityId: id }, + }); + }, + + + + +// 获得抽奖照片 + prizeImg: (id) => { + return request({ + url: '/promotion/prize-draw/activity-prize/list-by-activity-id', + method: 'GET', + params: { activityId:id }, + }); + }, + // 规则 + ActivityRules: (params) => { + return request({ + url: '/promotion/prize-draw/getOne', + method: 'GET', + params, + }); + }, +}; + +export default PayOrderApi; diff --git a/yudao-mall-uniapp-master/sheep/helper/index.js b/yudao-mall-uniapp-master/sheep/helper/index.js index 38e6afe..162a9eb 100644 --- a/yudao-mall-uniapp-master/sheep/helper/index.js +++ b/yudao-mall-uniapp-master/sheep/helper/index.js @@ -650,8 +650,13 @@ export function getRootUrl() { /** * copyText 多端复制文本 */ -export function copyText(text) { +export function copyText(temp) { + let text = temp; + if (text.startsWith('?')) { + text = text.substring(1); + } // #ifndef H5 + console.log(text, 'text1'); uni.setClipboardData({ data: text, success: function () { diff --git a/yudao-mall-uniapp-master/sheep/platform/share.js b/yudao-mall-uniapp-master/sheep/platform/share.js index a5d1b0a..d693804 100644 --- a/yudao-mall-uniapp-master/sheep/platform/share.js +++ b/yudao-mall-uniapp-master/sheep/platform/share.js @@ -88,7 +88,11 @@ const buildSpmQuery = (params) => { from = platformMap.indexOf(params.from) + 1; } //spmParams = ... 可按需扩展 - return `spm=${shareId}.${page}.${query}.${platform}.${from}`; + if (user.userInfo.urlLink) { + return `${user.userInfo.urlLink}`; + } else { + return `spm=${shareId}.${page}.${query}.${platform}.${from}`; + } }; // 构造页面分享参数: 所有的分享都先到首页进行 spm 参数解析 @@ -173,7 +177,7 @@ const decryptSpm = (spm) => { }; // 绑定推广员 -const bindBrokerageUser = async (val= undefined) => { +const bindBrokerageUser = async (val = undefined) => { try { const shareId = val || uni.getStorageSync('shareId'); if (!shareId) { @@ -181,8 +185,7 @@ const bindBrokerageUser = async (val= undefined) => { } await BrokerageApi.bindBrokerageUser({ bindUserId: shareId }); uni.removeStorageSync('shareId'); - } catch { - } + } catch {} }; // 更新公众号分享sdk diff --git a/yudao-mall-uniapp-master/sheep/store/app.js b/yudao-mall-uniapp-master/sheep/store/app.js index 573c237..811fd8c 100644 --- a/yudao-mall-uniapp-master/sheep/store/app.js +++ b/yudao-mall-uniapp-master/sheep/store/app.js @@ -72,15 +72,16 @@ const app = defineStore({ }; this.platform = { share: { - methods: ["poster", "link"], - linkAddress: "https://shopro.sheepjs.com/#/", + methods: ['poster', 'link'], + // linkAddress: 'http://cdz.huamar.com/zdfs', + linkAddress: '', posterInfo: { - "user_bg": "/static/img/shop/config/user-poster-bg.png", - "goods_bg": "/static/img/shop/config/goods-poster-bg.png", - "groupon_bg": "/static/img/shop/config/groupon-poster-bg.png" - } + user_bg: '/static/img/shop/config/user-poster-bg.png', + goods_bg: '/static/img/shop/config/goods-poster-bg.png', + groupon_bg: '/static/img/shop/config/groupon-poster-bg.png', + }, }, - bind_mobile: 0 + bind_mobile: 0, }; this.chat = { chat_domain: "https://api.shopro.sheepjs.com/chat",