Compare commits
12 Commits
new/v2.0.0
...
9a2332a61b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a2332a61b | ||
|
|
a2e9e1e476 | ||
|
|
355eb8f9f5 | ||
|
|
29701e9e15 | ||
|
|
f8dfaad63b | ||
|
|
7ed13f3e2c | ||
|
|
432743addf | ||
|
|
20c5908f34 | ||
|
|
56129fb865 | ||
|
|
9cd9841f09 | ||
|
|
f0d4b595f4 | ||
|
|
56203a5895 |
115
doc/20251211.sql
115
doc/20251211.sql
@@ -1,33 +1,88 @@
|
|||||||
CREATE TABLE `cai_draw_sku_info`
|
CREATE TABLE `cai_prize_info`
|
||||||
(
|
(
|
||||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '子账户ID',
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '奖品ID',
|
||||||
`sku_type` tinyint not null comment '奖品类型',
|
`prize_name` varchar(100) NOT NULL COMMENT '奖品名称',
|
||||||
`sku_price` bigint(20) not null default 0 comment '奖品价值估算',
|
`prize_desc` varchar(500) DEFAULT '' COMMENT '奖品描述',
|
||||||
`sku_name` varchar(255) not null comment '奖品名称',
|
`prize_img` varchar(255) DEFAULT '' COMMENT '奖品图片地址',
|
||||||
|
`win_probability` decimal(5, 4) NOT NULL COMMENT '中奖率(0-1,如0.0100表示1%)',
|
||||||
|
`guarantee_draws` int NOT NULL DEFAULT 0 COMMENT '保底抽数(0表示无保底,谢谢惠顾奖无效)',
|
||||||
|
`min_win_draws` int NOT NULL DEFAULT 0 COMMENT '最低中奖抽数(0表示无限制,谢谢惠顾奖无效)',
|
||||||
|
`stock` int NOT NULL DEFAULT 0 COMMENT '奖品库存(谢谢惠顾奖填0,不校验)',
|
||||||
|
`prize_type` tinyint not null comment '奖品类型 1-谢谢惠顾 2-普通奖 3-大奖',
|
||||||
|
`prize_price` bigint(20) not null default 0 comment '奖品价值估算',
|
||||||
`auto_give` tinyint not null default 0 comment '是否自动兑奖',
|
`auto_give` tinyint not null default 0 comment '是否自动兑奖',
|
||||||
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`usercode` varchar(100) NOT NULL COMMENT '用户',
|
PRIMARY KEY (`id`)
|
||||||
`message` varchar(100) NOT NULL COMMENT '账户明细说明',
|
|
||||||
`action_type` varchar(36) DEFAULT NULL COMMENT '触发来源 1-充值 2-分销 3-抽奖',
|
|
||||||
`tar_user_id` bigint DEFAULT NULL COMMENT '目标ID,用户、抽奖ID',
|
|
||||||
`tar_usercode` varchar(20) DEFAULT NULL COMMENT '目标用户Code,有用户才有用',
|
|
||||||
`tar_name` varchar(255) DEFAULT NULL COMMENT '目标名称,用户名称,抽奖名称',
|
|
||||||
`tar_price` bigint DEFAULT NULL COMMENT '礼物价值',
|
|
||||||
`tar_img` varchar(255) DEFAULT NULL COMMENT '目标提前缓存的',
|
|
||||||
`tar_json` JSON DEFAULT NULL COMMENT '目标额外字段',
|
|
||||||
`change_value` bigint NOT NULL DEFAULT '0.00' COMMENT '变化值,为正 或者为负',
|
|
||||||
`operate_ip` varchar(15) DEFAULT '' COMMENT '操作IP',
|
|
||||||
`is_admin` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '是否为后台用户手动调整',
|
|
||||||
`trace_link_type` varchar(36) DEFAULT NULL COMMENT '跟踪类型 1-充值 2-分销 3-抽奖',
|
|
||||||
`trace_id` varchar(50) DEFAULT NULL COMMENT '跟踪ID 订单号-礼物ID',
|
|
||||||
`give_flag` tinyint NOT NULL DEFAULT '0' COMMENT '是否兑换',
|
|
||||||
`give_time` datetime comment '兑换时间',
|
|
||||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
|
||||||
INDEX `user_id` (`user_id`) USING BTREE
|
|
||||||
) ENGINE = InnoDB
|
) ENGINE = InnoDB
|
||||||
AUTO_INCREMENT = 1
|
DEFAULT CHARSET = utf8mb4 COMMENT ='奖品基础表';
|
||||||
DEFAULT CHARSET = utf8mb4
|
|
||||||
COLLATE = utf8mb4_general_ci
|
|
||||||
ROW_FORMAT = DYNAMIC COMMENT ='抽奖奖池';
|
CREATE TABLE `cai_prize_online`
|
||||||
|
(
|
||||||
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '奖品ID',
|
||||||
|
`prize_id` bigint NOT NULL COMMENT '奖品ID',
|
||||||
|
`gender` tinyint(1) NOT NULL DEFAULT '0' COMMENT '性别 1-女 2-男',
|
||||||
|
`prize_name` varchar(100) NOT NULL COMMENT '奖品名称',
|
||||||
|
`prize_desc` varchar(500) DEFAULT '' COMMENT '奖品描述',
|
||||||
|
`prize_img` varchar(255) DEFAULT '' COMMENT '奖品图片地址',
|
||||||
|
`win_probability` decimal(5, 4) NOT NULL COMMENT '中奖率(0-1,如0.0100表示1%)',
|
||||||
|
`guarantee_draws` int NOT NULL DEFAULT 0 COMMENT '保底抽数(0表示无保底,谢谢惠顾奖无效)',
|
||||||
|
`min_win_draws` int NOT NULL DEFAULT 0 COMMENT '最低中奖抽数(0表示无限制,谢谢惠顾奖无效)',
|
||||||
|
`stock` int NOT NULL DEFAULT 0 COMMENT '奖品库存(谢谢惠顾奖填0,不校验)',
|
||||||
|
`prize_type` tinyint not null comment '奖品类型 1-谢谢惠顾 2-普通奖 3-大奖',
|
||||||
|
`prize_price` bigint(20) not null default 0 comment '奖品价值估算',
|
||||||
|
`auto_give` tinyint not null default 0 comment '是否自动兑奖',
|
||||||
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE = InnoDB
|
||||||
|
DEFAULT CHARSET = utf8mb4 COMMENT ='已发布奖品表';
|
||||||
|
|
||||||
|
|
||||||
|
alter table `cai_point_change_log`
|
||||||
|
ADD COLUMN remark varchar(200) null comment '备注';
|
||||||
|
|
||||||
|
|
||||||
|
-- 菜单 SQL
|
||||||
|
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
|
values(2003344862891581442, '抽奖奖品', '1738072642014617602', '1', 'prizeInfo', 'cai/prizeInfo/index', 1, 0, 'C', '0', '0', 'cai:prizeInfo:list', '#', 'admin', sysdate(), '', null, '抽奖奖品菜单');
|
||||||
|
|
||||||
|
-- 按钮 SQL
|
||||||
|
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
|
values(2003344862891581443, '抽奖奖品查询', 2003344862891581442, '1', '#', '', 1, 0, 'F', '0', '0', 'cai:prizeInfo:query', '#', 'admin', sysdate(), '', null, '');
|
||||||
|
|
||||||
|
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
|
values(2003344862891581444, '抽奖奖品新增', 2003344862891581442, '2', '#', '', 1, 0, 'F', '0', '0', 'cai:prizeInfo:add', '#', 'admin', sysdate(), '', null, '');
|
||||||
|
|
||||||
|
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
|
values(2003344862891581445, '抽奖奖品修改', 2003344862891581442, '3', '#', '', 1, 0, 'F', '0', '0', 'cai:prizeInfo:edit', '#', 'admin', sysdate(), '', null, '');
|
||||||
|
|
||||||
|
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
|
values(2003344862891581446, '抽奖奖品删除', 2003344862891581442, '4', '#', '', 1, 0, 'F', '0', '0', 'cai:prizeInfo:remove', '#', 'admin', sysdate(), '', null, '');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE `cai_prize_winning_record`
|
||||||
|
(
|
||||||
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '奖品ID',
|
||||||
|
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
|
||||||
|
`use_point` bigint(20) NOT NULL COMMENT '抽奖消耗',
|
||||||
|
`prize_id` bigint NOT NULL COMMENT '奖品ID',
|
||||||
|
`prize_name` varchar(100) NOT NULL COMMENT '奖品名称',
|
||||||
|
`prize_desc` varchar(500) DEFAULT '' COMMENT '奖品描述',
|
||||||
|
`prize_img` varchar(255) DEFAULT '' COMMENT '奖品图片地址',
|
||||||
|
`win_probability` decimal(5, 4) NOT NULL COMMENT '中奖率(0-1,如0.0100表示1%)',
|
||||||
|
`guarantee_draws` int NOT NULL DEFAULT 0 COMMENT '保底抽数(0表示无保底,谢谢惠顾奖无效)',
|
||||||
|
`min_win_draws` int NOT NULL DEFAULT 0 COMMENT '最低中奖抽数(0表示无限制,谢谢惠顾奖无效)',
|
||||||
|
`stock` int NOT NULL DEFAULT 0 COMMENT '奖品库存(谢谢惠顾奖填0,不校验)',
|
||||||
|
`prize_type` tinyint not null comment '奖品类型 1-谢谢惠顾 2-普通奖 3-大奖',
|
||||||
|
`prize_price` bigint(20) not null default 0 comment '奖品价值估算',
|
||||||
|
`auto_give` tinyint not null default 0 comment '是否自动兑奖',
|
||||||
|
`give_status` tinyint not null default 0 comment '奖品兑换情况 0-未兑换 1-已兑换',
|
||||||
|
`give_remark` varchar(100) not null default 0 comment '兑奖备注说明',
|
||||||
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE = InnoDB
|
||||||
|
DEFAULT CHARSET = utf8mb4 COMMENT ='中奖记录';
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package com.ruoyi.web.controller.cai.app;
|
||||||
|
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.cai.domain.PrizeOnline;
|
||||||
|
import com.ruoyi.cai.domain.PrizeWinningRecord;
|
||||||
|
import com.ruoyi.cai.dto.app.draw.resp.*;
|
||||||
|
import com.ruoyi.cai.lottery.DrawService;
|
||||||
|
import com.ruoyi.cai.service.PrizeOnlineService;
|
||||||
|
import com.ruoyi.cai.service.PrizeWinningRecordService;
|
||||||
|
import com.ruoyi.common.core.domain.PageQuery;
|
||||||
|
import com.ruoyi.common.core.domain.R;
|
||||||
|
import com.ruoyi.common.helper.LoginHelper;
|
||||||
|
import com.ruoyi.common.utils.BeanConvertUtil;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/draw")
|
||||||
|
@Tag(name = "抽奖相关接口")
|
||||||
|
public class DrawController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DrawService drawService;
|
||||||
|
@Autowired
|
||||||
|
private PrizeOnlineService prizeOnlineService;
|
||||||
|
@Autowired
|
||||||
|
private PrizeWinningRecordService prizeWinningRecordService;
|
||||||
|
|
||||||
|
@GetMapping("/baseConfig")
|
||||||
|
@Operation(summary = "获取抽奖相关的基础信息")
|
||||||
|
public R<DrawBaseConfigResp> baseConfig(){
|
||||||
|
DrawBaseConfigResp resp = drawService.baseConfig();
|
||||||
|
return R.ok(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/points/logs")
|
||||||
|
@Operation(summary = "获取积分记录")
|
||||||
|
public R<List<PointLogsResp>> pointsLogs(PageQuery page){
|
||||||
|
List<PointLogsResp> resp = drawService.pointsLogs(page);
|
||||||
|
return R.ok(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/prize/up")
|
||||||
|
@Operation(summary = "获取奖品列表")
|
||||||
|
public R<List<PrizeOnlineResp>> prizeUp(){
|
||||||
|
List<PrizeOnline> prizeOnlines = prizeOnlineService.prizeUp();
|
||||||
|
List<PrizeOnlineResp> resp = BeanConvertUtil.convertListTo(prizeOnlines, PrizeOnlineResp::new);
|
||||||
|
return R.ok(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/winning/record")
|
||||||
|
@Operation(summary = "获取自己的中奖记录")
|
||||||
|
public R<List<UserWinningRecordResp>> winningRecord(PageQuery page){
|
||||||
|
Page<PrizeWinningRecord> page1 = prizeWinningRecordService.page(page.build(), Wrappers.lambdaQuery(PrizeWinningRecord.class)
|
||||||
|
.eq(PrizeWinningRecord::getUserId, LoginHelper.getUserId())
|
||||||
|
.orderByDesc(PrizeWinningRecord::getCreateTime)
|
||||||
|
);
|
||||||
|
List<UserWinningRecordResp> resps = BeanConvertUtil.convertListTo(page1.getRecords(), UserWinningRecordResp::new);
|
||||||
|
return R.ok(resps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/winning/center")
|
||||||
|
@Operation(summary = "全局中奖记录")
|
||||||
|
public R<List<CenterWinningRecordResp>> winningCenter(){
|
||||||
|
List<PrizeWinningRecord> list = prizeWinningRecordService.list(Wrappers.lambdaQuery(PrizeWinningRecord.class)
|
||||||
|
.orderByDesc(PrizeWinningRecord::getCreateTime));
|
||||||
|
List<CenterWinningRecordResp> resps = BeanConvertUtil.convertListTo(list, CenterWinningRecordResp::new);
|
||||||
|
resps.forEach(i -> i.setUserName("****"));
|
||||||
|
return R.ok(resps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/lottery")
|
||||||
|
@Operation(summary = "抽奖接口")
|
||||||
|
public R<Void> lottery(){
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package com.ruoyi.cai.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.cai.domain.PrizeInfo;
|
||||||
|
import com.ruoyi.cai.service.PrizeInfoService;
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.annotation.RepeatSubmit;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.PageQuery;
|
||||||
|
import com.ruoyi.common.core.domain.R;
|
||||||
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.common.core.validate.AddGroup;
|
||||||
|
import com.ruoyi.common.core.validate.EditGroup;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽奖奖品
|
||||||
|
*
|
||||||
|
* @author 77
|
||||||
|
* @date 2025-12-23
|
||||||
|
*/
|
||||||
|
@Validated
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/cai/prizeInfo")
|
||||||
|
public class PrizeInfoController extends BaseController {
|
||||||
|
|
||||||
|
private final PrizeInfoService prizeInfoService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询抽奖奖品列表
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("cai:prizeInfo:list")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public TableDataInfo<PrizeInfo> list(PrizeInfo bo, PageQuery pageQuery) {
|
||||||
|
Page<PrizeInfo> page = prizeInfoService.page(pageQuery.build(), Wrappers.lambdaQuery(PrizeInfo.class));
|
||||||
|
return TableDataInfo.build(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/all")
|
||||||
|
public R<List<PrizeInfo>> all() {
|
||||||
|
return R.ok(prizeInfoService.list());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取抽奖奖品详细信息
|
||||||
|
*
|
||||||
|
* @param id 主键
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("cai:prizeInfo:query")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public R<PrizeInfo> getInfo(@NotNull(message = "主键不能为空")
|
||||||
|
@PathVariable Long id) {
|
||||||
|
return R.ok(prizeInfoService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增抽奖奖品
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("cai:prizeInfo:add")
|
||||||
|
@Log(title = "抽奖奖品", businessType = BusinessType.INSERT)
|
||||||
|
@RepeatSubmit()
|
||||||
|
@PostMapping()
|
||||||
|
public R<Void> add(@Validated(AddGroup.class) @RequestBody PrizeInfo bo) {
|
||||||
|
return toAjax(prizeInfoService.save(bo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改抽奖奖品
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("cai:prizeInfo:edit")
|
||||||
|
@Log(title = "抽奖奖品", businessType = BusinessType.UPDATE)
|
||||||
|
@RepeatSubmit()
|
||||||
|
@PutMapping()
|
||||||
|
public R<Void> edit(@Validated(EditGroup.class) @RequestBody PrizeInfo bo) {
|
||||||
|
return toAjax(prizeInfoService.updateById(bo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除抽奖奖品
|
||||||
|
*
|
||||||
|
* @param ids 主键串
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("cai:prizeInfo:remove")
|
||||||
|
@Log(title = "抽奖奖品", businessType = BusinessType.DELETE)
|
||||||
|
@DeleteMapping("/{ids}")
|
||||||
|
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||||
|
@PathVariable Long[] ids) {
|
||||||
|
return toAjax(prizeInfoService.removeBatchByIds(Arrays.asList(ids), true));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package com.ruoyi.cai.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.cai.domain.PrizeOnline;
|
||||||
|
import com.ruoyi.cai.service.PrizeOnlineService;
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.annotation.RepeatSubmit;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.PageQuery;
|
||||||
|
import com.ruoyi.common.core.domain.R;
|
||||||
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.common.core.validate.AddGroup;
|
||||||
|
import com.ruoyi.common.core.validate.EditGroup;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已发布奖品
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2025-12-23
|
||||||
|
*/
|
||||||
|
@Validated
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/cai/prizeOnline")
|
||||||
|
public class PrizeOnlineController extends BaseController {
|
||||||
|
|
||||||
|
private final PrizeOnlineService prizeOnlineService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询已发布奖品列表
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("cai:prizeOnline:list")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public R<List<PrizeOnline>> list(PrizeOnline bo) {
|
||||||
|
List<PrizeOnline> page = prizeOnlineService.list(Wrappers.lambdaQuery(bo));
|
||||||
|
return R.ok(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取已发布奖品详细信息
|
||||||
|
*
|
||||||
|
* @param id 主键
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("cai:prizeOnline:query")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public R<PrizeOnline> getInfo(@NotNull(message = "主键不能为空")
|
||||||
|
@PathVariable Long id) {
|
||||||
|
return R.ok(prizeOnlineService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增已发布奖品
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("cai:prizeOnline:add")
|
||||||
|
@Log(title = "已发布奖品", businessType = BusinessType.INSERT)
|
||||||
|
@RepeatSubmit()
|
||||||
|
@PostMapping("/reset/{gender}")
|
||||||
|
public R<Void> reset(@PathVariable Integer gender,@Validated(AddGroup.class) @RequestBody List<PrizeOnline> bo) {
|
||||||
|
prizeOnlineService.reset(gender,bo);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package com.ruoyi.cai.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.cai.domain.PrizeWinningRecord;
|
||||||
|
import com.ruoyi.cai.dto.admin.vo.winningRecord.PrizeWinningRecordAdminVO;
|
||||||
|
import com.ruoyi.cai.mapper.PrizeWinningRecordMapper;
|
||||||
|
import com.ruoyi.cai.service.PrizeWinningRecordService;
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.annotation.RepeatSubmit;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.PageQuery;
|
||||||
|
import com.ruoyi.common.core.domain.R;
|
||||||
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.common.core.validate.AddGroup;
|
||||||
|
import com.ruoyi.common.core.validate.EditGroup;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中奖记录
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-01-08
|
||||||
|
*/
|
||||||
|
@Validated
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/cai/prizeWinningRecord")
|
||||||
|
public class PrizeWinningRecordController extends BaseController {
|
||||||
|
|
||||||
|
private final PrizeWinningRecordService prizeWinningRecordService;
|
||||||
|
@Resource
|
||||||
|
private PrizeWinningRecordMapper prizeWinningRecordMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询中奖记录列表
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("cai:prizeWinningRecord:list")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public TableDataInfo<PrizeWinningRecordAdminVO> list(PrizeWinningRecordAdminVO bo, PageQuery pageQuery) {
|
||||||
|
Page<PrizeWinningRecordAdminVO> page = prizeWinningRecordMapper.pageAdmin(pageQuery.build(), bo);
|
||||||
|
return TableDataInfo.build(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取中奖记录详细信息
|
||||||
|
*
|
||||||
|
* @param id 主键
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("cai:prizeWinningRecord:query")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public R<PrizeWinningRecord> getInfo(@NotNull(message = "主键不能为空")
|
||||||
|
@PathVariable Long id) {
|
||||||
|
return R.ok(prizeWinningRecordService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改中奖记录
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("cai:prizeWinningRecord:edit")
|
||||||
|
@Log(title = "中奖记录", businessType = BusinessType.UPDATE)
|
||||||
|
@RepeatSubmit()
|
||||||
|
@PostMapping("/give")
|
||||||
|
public R<Void> give(@Validated(EditGroup.class) @RequestBody PrizeWinningRecord bo) {
|
||||||
|
PrizeWinningRecord update = new PrizeWinningRecord();
|
||||||
|
update.setId(bo.getId());
|
||||||
|
update.setGiveStatus(1);
|
||||||
|
update.setGiveRemark(bo.getGiveRemark());
|
||||||
|
prizeWinningRecordService.updateById(update);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除中奖记录
|
||||||
|
*
|
||||||
|
* @param ids 主键串
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("cai:prizeWinningRecord:remove")
|
||||||
|
@Log(title = "中奖记录", businessType = BusinessType.DELETE)
|
||||||
|
@DeleteMapping("/{ids}")
|
||||||
|
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||||
|
@PathVariable Long[] ids) {
|
||||||
|
return toAjax(prizeWinningRecordService.removeBatchByIds(Arrays.asList(ids), true));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -86,6 +86,7 @@ public class PointChangeLog implements Serializable {
|
|||||||
* 是否兑换
|
* 是否兑换
|
||||||
*/
|
*/
|
||||||
private Integer giveFlag;
|
private Integer giveFlag;
|
||||||
|
private String remark;
|
||||||
/**
|
/**
|
||||||
* 兑换时间
|
* 兑换时间
|
||||||
*/
|
*/
|
||||||
|
|||||||
75
ruoyi-cai/src/main/java/com/ruoyi/cai/domain/PrizeInfo.java
Normal file
75
ruoyi-cai/src/main/java/com/ruoyi/cai/domain/PrizeInfo.java
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
package com.ruoyi.cai.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
|
import org.joda.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽奖奖品对象 cai_prize_info
|
||||||
|
*
|
||||||
|
* @author 77
|
||||||
|
* @date 2025-12-23
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("cai_prize_info")
|
||||||
|
public class PrizeInfo implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID=1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 奖品ID
|
||||||
|
*/
|
||||||
|
@TableId(value = "id",type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 奖品名称
|
||||||
|
*/
|
||||||
|
private String prizeName;
|
||||||
|
/**
|
||||||
|
* 奖品描述
|
||||||
|
*/
|
||||||
|
private String prizeDesc;
|
||||||
|
/**
|
||||||
|
* 奖品图片地址
|
||||||
|
*/
|
||||||
|
private String prizeImg;
|
||||||
|
/**
|
||||||
|
* 中奖率(0-1,如0.0100表示1%)
|
||||||
|
*/
|
||||||
|
private BigDecimal winProbability;
|
||||||
|
/**
|
||||||
|
* 保底抽数(0表示无保底)
|
||||||
|
*/
|
||||||
|
private Long guaranteeDraws;
|
||||||
|
/**
|
||||||
|
* 最低中奖抽数(0表示无限制)
|
||||||
|
*/
|
||||||
|
private Long minWinDraws;
|
||||||
|
/**
|
||||||
|
* 奖品库存(谢谢惠顾奖填0)
|
||||||
|
*/
|
||||||
|
private Long stock;
|
||||||
|
/**
|
||||||
|
* 奖品类型 1-谢谢惠顾 2-普通奖 3-大奖
|
||||||
|
*/
|
||||||
|
private Long prizeType;
|
||||||
|
/**
|
||||||
|
* 奖品价值估算
|
||||||
|
*/
|
||||||
|
private Long prizePrice;
|
||||||
|
/**
|
||||||
|
* 是否自动兑奖
|
||||||
|
*/
|
||||||
|
private Boolean autoGive;
|
||||||
|
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package com.ruoyi.cai.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
|
import org.joda.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已发布奖品对象 cai_prize_online
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2025-12-23
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("cai_prize_online")
|
||||||
|
public class PrizeOnline implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID=1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 奖品ID
|
||||||
|
*/
|
||||||
|
@TableId(value = "id",type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 奖品ID
|
||||||
|
*/
|
||||||
|
private Long prizeId;
|
||||||
|
/**
|
||||||
|
* 性别 1-女 2-男
|
||||||
|
*/
|
||||||
|
private Integer gender;
|
||||||
|
/**
|
||||||
|
* 奖品名称
|
||||||
|
*/
|
||||||
|
private String prizeName;
|
||||||
|
/**
|
||||||
|
* 奖品描述
|
||||||
|
*/
|
||||||
|
private String prizeDesc;
|
||||||
|
/**
|
||||||
|
* 奖品图片地址
|
||||||
|
*/
|
||||||
|
private String prizeImg;
|
||||||
|
/**
|
||||||
|
* 中奖率(0-1,如0.0100表示1%)
|
||||||
|
*/
|
||||||
|
private BigDecimal winProbability;
|
||||||
|
/**
|
||||||
|
* 保底抽数(0表示无保底,谢谢惠顾奖无效)
|
||||||
|
*/
|
||||||
|
private Integer guaranteeDraws;
|
||||||
|
/**
|
||||||
|
* 最低中奖抽数(0表示无限制,谢谢惠顾奖无效)
|
||||||
|
*/
|
||||||
|
private Integer minWinDraws;
|
||||||
|
/**
|
||||||
|
* 奖品库存(谢谢惠顾奖填0,不校验)
|
||||||
|
*/
|
||||||
|
private Long stock;
|
||||||
|
/**
|
||||||
|
* 奖品类型 1-谢谢惠顾 2-普通奖 3-大奖
|
||||||
|
*/
|
||||||
|
private Integer prizeType;
|
||||||
|
/**
|
||||||
|
* 奖品价值估算
|
||||||
|
*/
|
||||||
|
private Long prizePrice;
|
||||||
|
/**
|
||||||
|
* 是否自动兑奖
|
||||||
|
*/
|
||||||
|
private Boolean autoGive;
|
||||||
|
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package com.ruoyi.cai.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
|
import org.joda.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中奖记录对象 cai_prize_winning_record
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-01-08
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("cai_prize_winning_record")
|
||||||
|
public class PrizeWinningRecord implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID=1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 奖品ID
|
||||||
|
*/
|
||||||
|
@TableId(value = "id",type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 用户ID
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
/**
|
||||||
|
* 抽奖消耗
|
||||||
|
*/
|
||||||
|
private Integer usePoint;
|
||||||
|
/**
|
||||||
|
* 奖品ID
|
||||||
|
*/
|
||||||
|
private Long prizeId;
|
||||||
|
/**
|
||||||
|
* 奖品名称
|
||||||
|
*/
|
||||||
|
private String prizeName;
|
||||||
|
/**
|
||||||
|
* 奖品描述
|
||||||
|
*/
|
||||||
|
private String prizeDesc;
|
||||||
|
/**
|
||||||
|
* 奖品图片地址
|
||||||
|
*/
|
||||||
|
private String prizeImg;
|
||||||
|
/**
|
||||||
|
* 中奖率(0-1,如0.0100表示1%)
|
||||||
|
*/
|
||||||
|
private BigDecimal winProbability;
|
||||||
|
/**
|
||||||
|
* 保底抽数(0表示无保底,谢谢惠顾奖无效)
|
||||||
|
*/
|
||||||
|
private Integer guaranteeDraws;
|
||||||
|
/**
|
||||||
|
* 最低中奖抽数(0表示无限制,谢谢惠顾奖无效)
|
||||||
|
*/
|
||||||
|
private Integer minWinDraws;
|
||||||
|
/**
|
||||||
|
* 奖品库存(谢谢惠顾奖填0,不校验)
|
||||||
|
*/
|
||||||
|
private Long stock;
|
||||||
|
/**
|
||||||
|
* 奖品类型 1-谢谢惠顾 2-普通奖 3-大奖
|
||||||
|
*/
|
||||||
|
private Integer prizeType;
|
||||||
|
/**
|
||||||
|
* 奖品价值估算
|
||||||
|
*/
|
||||||
|
private Long prizePrice;
|
||||||
|
/**
|
||||||
|
* 是否自动兑奖
|
||||||
|
*/
|
||||||
|
private Boolean autoGive;
|
||||||
|
/**
|
||||||
|
* 奖品兑换情况 0-未兑换 1-已兑换
|
||||||
|
*/
|
||||||
|
private Integer giveStatus;
|
||||||
|
/**
|
||||||
|
* 兑奖备注说明
|
||||||
|
*/
|
||||||
|
private String giveRemark;
|
||||||
|
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.ruoyi.cai.dto.admin.vo.winningRecord;
|
||||||
|
|
||||||
|
import com.ruoyi.cai.domain.PrizeWinningRecord;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PrizeWinningRecordAdminVO extends PrizeWinningRecord {
|
||||||
|
private String usercode;
|
||||||
|
private String nickname;
|
||||||
|
private String mobile;
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.ruoyi.cai.dto.app.draw.resp;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.joda.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class CenterWinningRecordResp {
|
||||||
|
/**
|
||||||
|
* 用户昵称
|
||||||
|
*/
|
||||||
|
private String userName;
|
||||||
|
/**
|
||||||
|
* 抽奖消耗
|
||||||
|
*/
|
||||||
|
private Long usePoint;
|
||||||
|
/**
|
||||||
|
* 奖品名称
|
||||||
|
*/
|
||||||
|
private String prizeName;
|
||||||
|
private String prizeDesc;
|
||||||
|
/**
|
||||||
|
* 奖品图片地址
|
||||||
|
*/
|
||||||
|
private String prizeImg;
|
||||||
|
/**
|
||||||
|
* 奖品兑换情况 0-未兑换 1-已兑换
|
||||||
|
*/
|
||||||
|
private Integer giveStatus;
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.ruoyi.cai.dto.app.draw.resp;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DrawBaseConfigResp {
|
||||||
|
private boolean openDraw;
|
||||||
|
private Integer drawPoint;
|
||||||
|
private String drawText;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.ruoyi.cai.dto.app.draw.resp;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PointLogsResp {
|
||||||
|
// 1-充值 2-系统调整 3-分销 4-抽奖
|
||||||
|
private String actionType;
|
||||||
|
private String message;
|
||||||
|
private String tarImg;
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.ruoyi.cai.dto.app.draw.resp;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PrizeOnlineResp {
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 奖品名称
|
||||||
|
*/
|
||||||
|
private String prizeName;
|
||||||
|
/**
|
||||||
|
* 奖品描述
|
||||||
|
*/
|
||||||
|
private String prizeDesc;
|
||||||
|
/**
|
||||||
|
* 奖品图片地址
|
||||||
|
*/
|
||||||
|
private String prizeImg;
|
||||||
|
/**
|
||||||
|
* 奖品类型 1-谢谢惠顾 2-普通奖 3-大奖
|
||||||
|
*/
|
||||||
|
private Integer prizeType;
|
||||||
|
/**
|
||||||
|
* 奖品价值估算
|
||||||
|
*/
|
||||||
|
private Long prizePrice;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.ruoyi.cai.dto.app.draw.resp;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.joda.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UserWinningRecordResp {
|
||||||
|
/**
|
||||||
|
* 中奖记录ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 用户ID
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
/**
|
||||||
|
* 抽奖消耗
|
||||||
|
*/
|
||||||
|
private Long usePoint;
|
||||||
|
/**
|
||||||
|
* 奖品名称
|
||||||
|
*/
|
||||||
|
private String prizeName;
|
||||||
|
private String prizeDesc;
|
||||||
|
/**
|
||||||
|
* 奖品图片地址
|
||||||
|
*/
|
||||||
|
private String prizeImg;
|
||||||
|
/**
|
||||||
|
* 奖品兑换情况 0-未兑换 1-已兑换
|
||||||
|
*/
|
||||||
|
private Integer giveStatus;
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -22,4 +22,6 @@ public class UserAccountVo {
|
|||||||
@Schema(description = "收益的紫贝")
|
@Schema(description = "收益的紫贝")
|
||||||
private Long incomeCoin;
|
private Long incomeCoin;
|
||||||
|
|
||||||
|
private Long points;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,16 @@ public enum GenderEnum {
|
|||||||
this.defaultAvatar = defaultAvatar;
|
this.defaultAvatar = defaultAvatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isSelect(Integer code){
|
||||||
|
if(GenderEnum.WOMEN.getCode().equals(code)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(GenderEnum.MAN.getCode().equals(code)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static GenderEnum getByCode(Integer code){
|
public static GenderEnum getByCode(Integer code){
|
||||||
GenderEnum[] values = GenderEnum.values();
|
GenderEnum[] values = GenderEnum.values();
|
||||||
for (GenderEnum value : values) {
|
for (GenderEnum value : values) {
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ public enum SystemConfigEnum {
|
|||||||
*/
|
*/
|
||||||
OPEN_IP_NUMBER("5", "IP每日登录次数超过多少次封",SystemConfigGroupEnum.SECURITY),
|
OPEN_IP_NUMBER("5", "IP每日登录次数超过多少次封",SystemConfigGroupEnum.SECURITY),
|
||||||
LOGIN_ERROR_OPEN_SECURITY("2", "输入密码次数超过多少次开启图形验证码",SystemConfigGroupEnum.SECURITY),
|
LOGIN_ERROR_OPEN_SECURITY("2", "输入密码次数超过多少次开启图形验证码",SystemConfigGroupEnum.SECURITY),
|
||||||
// TODO 新台子改默认值
|
OPEN_OLD_LOGIN_API("0", "开启旧版无验证码登录接口",SystemConfigGroupEnum.SECURITY),
|
||||||
OPEN_OLD_LOGIN_API("1", "开启旧版无验证码登录接口",SystemConfigGroupEnum.SECURITY),
|
OPEN_OLD_REGISTER_CODE("0", "是否开启无验证码注册接口",SystemConfigGroupEnum.SECURITY, new BooleanSystemConfigCheck()),
|
||||||
OPEN_IP_AUTO("1", "开启自动定时封IP",SystemConfigGroupEnum.SECURITY),
|
OPEN_IP_AUTO("1", "开启自动定时封IP",SystemConfigGroupEnum.SECURITY),
|
||||||
OPEN_RESET_PASSWORD("1", "开启重置密码",SystemConfigGroupEnum.SECURITY, new BooleanSystemConfigCheck()),
|
OPEN_RESET_PASSWORD("1", "开启重置密码",SystemConfigGroupEnum.SECURITY, new BooleanSystemConfigCheck()),
|
||||||
LOGIN_PASSWORD_ERROR_MAX_NUM("5", "登录输错密码上限",SystemConfigGroupEnum.SECURITY, new NumberSystemConfigCheck()),
|
LOGIN_PASSWORD_ERROR_MAX_NUM("20", "登录输错密码上限",SystemConfigGroupEnum.SECURITY, new NumberSystemConfigCheck()),
|
||||||
SENSITIVE_ENABLE("1", "是否开启手机号脱敏",SystemConfigGroupEnum.SECURITY,new BooleanSystemConfigCheck()),
|
SENSITIVE_ENABLE("1", "是否开启手机号脱敏",SystemConfigGroupEnum.SECURITY,new BooleanSystemConfigCheck()),
|
||||||
OPEN_CLEAN_DYNAMIC("1", "开启动态定时清除",SystemConfigGroupEnum.SECURITY,new BooleanSystemConfigCheck()),
|
OPEN_CLEAN_DYNAMIC("1", "开启动态定时清除",SystemConfigGroupEnum.SECURITY,new BooleanSystemConfigCheck()),
|
||||||
YUNXIN_ONLINE_ENABLE("1", "是否开启云信监控在线状态",SystemConfigGroupEnum.SECURITY,new BooleanSystemConfigCheck()),
|
YUNXIN_ONLINE_ENABLE("1", "是否开启云信监控在线状态",SystemConfigGroupEnum.SECURITY,new BooleanSystemConfigCheck()),
|
||||||
@@ -32,10 +32,9 @@ public enum SystemConfigEnum {
|
|||||||
IPV6_FILTER("0", "是否开启IPV6请求拦截",SystemConfigGroupEnum.SECURITY, new BooleanSystemConfigCheck()),
|
IPV6_FILTER("0", "是否开启IPV6请求拦截",SystemConfigGroupEnum.SECURITY, new BooleanSystemConfigCheck()),
|
||||||
IPV6_FILTER_PATH("/api/auth/login", "IPV6拦截路由配置(逗号分隔)",SystemConfigGroupEnum.SECURITY, new BooleanSystemConfigCheck(),"textarea"),
|
IPV6_FILTER_PATH("/api/auth/login", "IPV6拦截路由配置(逗号分隔)",SystemConfigGroupEnum.SECURITY, new BooleanSystemConfigCheck(),"textarea"),
|
||||||
VIP_PRIVATE_PLUS("0", "开启VIP隐私模式增强模式",SystemConfigGroupEnum.SECURITY,new BooleanSystemConfigCheck()),
|
VIP_PRIVATE_PLUS("0", "开启VIP隐私模式增强模式",SystemConfigGroupEnum.SECURITY,new BooleanSystemConfigCheck()),
|
||||||
OPEN_ANCHOR_CHAT_COUNT("0", "开启主播主动消息统计",SystemConfigGroupEnum.SECURITY,new BooleanSystemConfigCheck()),
|
OPEN_ANCHOR_CHAT_COUNT("1", "开启主播主动消息统计",SystemConfigGroupEnum.SECURITY,new BooleanSystemConfigCheck()),
|
||||||
// 4-recordId拦截 5-recordId加强拦截 6-性别拦截 7-vip加强拦截
|
// 4-recordId拦截 5-recordId加强拦截 6-性别拦截 7-vip加强拦截
|
||||||
IM_FILTER_PLUS("0", "IM拦截配置(勿动,开发配置)",SystemConfigGroupEnum.SECURITY),
|
IM_FILTER_PLUS("0", "IM拦截配置(勿动,开发配置)",SystemConfigGroupEnum.SECURITY),
|
||||||
OPEN_OLD_REGISTER_CODE("0", "是否开启无验证码注册接口",SystemConfigGroupEnum.SECURITY, new BooleanSystemConfigCheck()),
|
|
||||||
OPEN_NOTICE("1", "是否开启告警",SystemConfigGroupEnum.SECURITY, new BooleanSystemConfigCheck()),
|
OPEN_NOTICE("1", "是否开启告警",SystemConfigGroupEnum.SECURITY, new BooleanSystemConfigCheck()),
|
||||||
PAY_ERROR_NUM_NOTICE("2", "连续调用支付失败N次,发起告警",SystemConfigGroupEnum.SECURITY, new NumberSystemConfigCheck()),
|
PAY_ERROR_NUM_NOTICE("2", "连续调用支付失败N次,发起告警",SystemConfigGroupEnum.SECURITY, new NumberSystemConfigCheck()),
|
||||||
PAY_NOTIFY_ERROR_NUM_NOTICE("5", "连续调用N次支付,但是依旧未支付成功,发起告警",SystemConfigGroupEnum.SECURITY, new NumberSystemConfigCheck()),
|
PAY_NOTIFY_ERROR_NUM_NOTICE("5", "连续调用N次支付,但是依旧未支付成功,发起告警",SystemConfigGroupEnum.SECURITY, new NumberSystemConfigCheck()),
|
||||||
@@ -62,6 +61,32 @@ public enum SystemConfigEnum {
|
|||||||
V12_XIAOCHENGXU_ORG_ID("gh_62790d4f9c57", "V12德商小程序原始id",SystemConfigGroupEnum.PAY),
|
V12_XIAOCHENGXU_ORG_ID("gh_62790d4f9c57", "V12德商小程序原始id",SystemConfigGroupEnum.PAY),
|
||||||
V12_XIAOCHENGXU_PATH("pages/zf/index?", "V12德商小程序页面路径",SystemConfigGroupEnum.PAY),
|
V12_XIAOCHENGXU_PATH("pages/zf/index?", "V12德商小程序页面路径",SystemConfigGroupEnum.PAY),
|
||||||
V12_WX_APP_ID("wxae39c7eed3221d26", "微信开放平台ID",SystemConfigGroupEnum.PAY),
|
V12_WX_APP_ID("wxae39c7eed3221d26", "微信开放平台ID",SystemConfigGroupEnum.PAY),
|
||||||
|
/**
|
||||||
|
* 抽奖和积分
|
||||||
|
*/
|
||||||
|
OPEN_DRAW_WOMEN("1","是否开启女用户积分抽奖",SystemConfigGroupEnum.DRAW,new BooleanSystemConfigCheck()),
|
||||||
|
OPEN_DRAW_MAN("1","是否开启男用户积分抽奖",SystemConfigGroupEnum.DRAW,new BooleanSystemConfigCheck()),
|
||||||
|
WOMEN_DRAW_POINT("100","女用户抽奖分数",SystemConfigGroupEnum.DRAW,new NumberSystemConfigCheck()),
|
||||||
|
MEN_DRAW_POINT("100","男用户抽奖分数",SystemConfigGroupEnum.DRAW,new NumberSystemConfigCheck()),
|
||||||
|
MAX_POINT_DAY("0","用户每日可获取最大积分,0表示不限制",SystemConfigGroupEnum.DRAW,new NumberSystemConfigCheck()),
|
||||||
|
DRAW_DIALOG_TEXT("当日邀请5个新用户充值:奖励108\n" +
|
||||||
|
"当日邀请10个新用户充值:奖励168\n" +
|
||||||
|
"当日邀请20个新用户充值:奖励288\n" +
|
||||||
|
"当日邀请30个新用户充值:奖励388\n" +
|
||||||
|
"当日邀请50个新用户充值:奖励588\n" +
|
||||||
|
"注:必须是当日邀请 当日充值。发现刷单的一律封号 不给予提现\n" +
|
||||||
|
"《凌晨12点之后联系平台客服领取》\n" +
|
||||||
|
"当日邀请榜单活动(发现刷单的一律封号不给予提现)\n" +
|
||||||
|
"第一名:1888\n" +
|
||||||
|
"第二名:999\n" +
|
||||||
|
"第三名:555\n" +
|
||||||
|
"第四名:308\n" +
|
||||||
|
"第五名:188\n" +
|
||||||
|
"第六名至十名:108\n" +
|
||||||
|
"注:(开服期间邀请充值奖励百分之40)\n" +
|
||||||
|
"魅力榜,邀请榜、日榜、周榜双榜奖励!!!\n" +
|
||||||
|
"单笔充值120送普通会员\n" +
|
||||||
|
"单笔充值300送超级会员", "抽奖说明",SystemConfigGroupEnum.BUSINESS,null,"textarea"),
|
||||||
/**
|
/**
|
||||||
* 域名配置
|
* 域名配置
|
||||||
*/
|
*/
|
||||||
@@ -71,6 +96,7 @@ public enum SystemConfigEnum {
|
|||||||
ANCHOR_JOIN_AGREEMENT("/#/agreement/anchor-join", "主播入驻协议地址",SystemConfigGroupEnum.DOMAIN),
|
ANCHOR_JOIN_AGREEMENT("/#/agreement/anchor-join", "主播入驻协议地址",SystemConfigGroupEnum.DOMAIN),
|
||||||
WS_SOCKET_URL("ws://localhost:8080/ws?token=%s&room_id=%s", "ws通讯地址",SystemConfigGroupEnum.DOMAIN),
|
WS_SOCKET_URL("ws://localhost:8080/ws?token=%s&room_id=%s", "ws通讯地址",SystemConfigGroupEnum.DOMAIN),
|
||||||
UPLOAD_FILE_DOMAIN("http://127.0.0.1:8080", "文件上传域名服务器",SystemConfigGroupEnum.DOMAIN),
|
UPLOAD_FILE_DOMAIN("http://127.0.0.1:8080", "文件上传域名服务器",SystemConfigGroupEnum.DOMAIN),
|
||||||
|
PAY_NOTIFY_URL("http://127.0.0.1:8080", "域名回调",SystemConfigGroupEnum.DOMAIN),
|
||||||
// 七牛云 ?imageView2/2/w/120/h/120
|
// 七牛云 ?imageView2/2/w/120/h/120
|
||||||
// 腾讯云 ?thumbnail=120y120&imageView
|
// 腾讯云 ?thumbnail=120y120&imageView
|
||||||
IM_ICON_SUFFIX("?thumbnail=120y120&imageView", "im头像后缀",SystemConfigGroupEnum.DOMAIN),
|
IM_ICON_SUFFIX("?thumbnail=120y120&imageView", "im头像后缀",SystemConfigGroupEnum.DOMAIN),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ public enum SystemConfigGroupEnum {
|
|||||||
BUSINESS,
|
BUSINESS,
|
||||||
SECURITY,
|
SECURITY,
|
||||||
PAY,
|
PAY,
|
||||||
DOMAIN
|
DOMAIN,
|
||||||
|
DRAW
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.ruoyi.cai.enums.prize;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
// 奖品类型 1-谢谢惠顾 2-普通奖 3-大奖
|
||||||
|
@Getter
|
||||||
|
public enum PrizeTypeEnum {
|
||||||
|
NONE(1,"谢谢惠顾"),
|
||||||
|
NORMAL(2,"普通奖"),
|
||||||
|
GOOD(3,"大奖"),
|
||||||
|
;
|
||||||
|
private final Integer code;
|
||||||
|
private final String text;
|
||||||
|
|
||||||
|
PrizeTypeEnum(Integer code, String text) {
|
||||||
|
this.code = code;
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package com.ruoyi.cai.lottery;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.cai.domain.PointChangeLog;
|
||||||
|
import com.ruoyi.cai.dto.app.draw.resp.DrawBaseConfigResp;
|
||||||
|
import com.ruoyi.cai.dto.app.draw.resp.PointLogsResp;
|
||||||
|
import com.ruoyi.cai.dto.commom.user.MinUser;
|
||||||
|
import com.ruoyi.cai.enums.GenderEnum;
|
||||||
|
import com.ruoyi.cai.enums.SystemConfigEnum;
|
||||||
|
import com.ruoyi.cai.manager.SystemConfigManager;
|
||||||
|
import com.ruoyi.cai.service.PointChangeLogService;
|
||||||
|
import com.ruoyi.cai.service.UserService;
|
||||||
|
import com.ruoyi.common.core.domain.PageQuery;
|
||||||
|
import com.ruoyi.common.helper.LoginHelper;
|
||||||
|
import com.ruoyi.common.utils.BeanConvertUtil;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DrawService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SystemConfigManager systemConfigManager;
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
@Autowired
|
||||||
|
private PointChangeLogService pointChangeLogService;
|
||||||
|
|
||||||
|
public DrawBaseConfigResp baseConfig() {
|
||||||
|
Long userId = LoginHelper.getUserId();
|
||||||
|
MinUser minUser = userService.getMinUserById(userId);
|
||||||
|
DrawBaseConfigResp resp = new DrawBaseConfigResp();
|
||||||
|
boolean openDraw = getOpenDraw(minUser.getGender());
|
||||||
|
resp.setOpenDraw(openDraw);
|
||||||
|
Integer drawPoint = this.getDrawPoint(minUser.getGender());
|
||||||
|
resp.setDrawPoint(drawPoint);
|
||||||
|
String drawText = systemConfigManager.getSystemConfig(SystemConfigEnum.DRAW_DIALOG_TEXT);
|
||||||
|
resp.setDrawText(drawText);
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Integer getDrawPoint(Integer gender){
|
||||||
|
if(GenderEnum.WOMEN.getCode().equals(gender)){
|
||||||
|
Integer womenDrawPoint = systemConfigManager.getSystemConfigOfInt(SystemConfigEnum.WOMEN_DRAW_POINT);
|
||||||
|
return womenDrawPoint;
|
||||||
|
}
|
||||||
|
return systemConfigManager.getSystemConfigOfInt(SystemConfigEnum.MEN_DRAW_POINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean getOpenDraw(Integer gender){
|
||||||
|
if(GenderEnum.WOMEN.getCode().equals(gender)){
|
||||||
|
return systemConfigManager.getSystemConfigOfBool(SystemConfigEnum.OPEN_DRAW_WOMEN);
|
||||||
|
}else if(GenderEnum.MAN.getCode().equals(gender)){
|
||||||
|
return systemConfigManager.getSystemConfigOfBool(SystemConfigEnum.OPEN_DRAW_MAN);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PointLogsResp> pointsLogs(PageQuery pageQuery) {
|
||||||
|
Page<PointChangeLog> page = pointChangeLogService.page(pageQuery.build(), Wrappers.lambdaQuery(PointChangeLog.class)
|
||||||
|
.eq(PointChangeLog::getUserId, LoginHelper.getUserId())
|
||||||
|
.orderByDesc(PointChangeLog::getCreateTime));
|
||||||
|
List<PointChangeLog> records = page.getRecords();
|
||||||
|
List<PointLogsResp> pointLogsResps = BeanConvertUtil.convertListTo(records, PointLogsResp::new);
|
||||||
|
return pointLogsResps;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,278 @@
|
|||||||
|
package com.ruoyi.cai.lottery;
|
||||||
|
|
||||||
|
import com.ruoyi.cai.domain.Account;
|
||||||
|
import com.ruoyi.cai.domain.PointChangeLog;
|
||||||
|
import com.ruoyi.cai.domain.PrizeOnline;
|
||||||
|
import com.ruoyi.cai.domain.User;
|
||||||
|
import com.ruoyi.cai.enums.GenderEnum;
|
||||||
|
import com.ruoyi.cai.enums.SystemConfigEnum;
|
||||||
|
import com.ruoyi.cai.manager.IdManager;
|
||||||
|
import com.ruoyi.cai.manager.SystemConfigManager;
|
||||||
|
import com.ruoyi.cai.service.AccountService;
|
||||||
|
import com.ruoyi.cai.service.PrizeOnlineService;
|
||||||
|
import com.ruoyi.cai.service.PrizeWinningRecordService;
|
||||||
|
import com.ruoyi.cai.service.UserService;
|
||||||
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.redisson.api.RBucket;
|
||||||
|
import org.redisson.api.RedissonClient;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽奖核心服务(优化版)
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class LotteryService {
|
||||||
|
|
||||||
|
// 固定配置
|
||||||
|
private static final Long THANKS_PRIZE_ID = 0L;
|
||||||
|
private static final String USER_DRAW_COUNT_KEY = "user:draw:count:%s";
|
||||||
|
private static final long USER_DRAW_COUNT_EXPIRE = 7 * 24 * 60 * 60; // 用户累计抽数缓存过期时间:7天
|
||||||
|
private static final double RANDOM_MAX = 10000; // 概率放大倍数,提升随机数精度
|
||||||
|
private static final long LOCK_TIMEOUT = 500; // 锁超时时间500ms(非阻塞获取)
|
||||||
|
|
||||||
|
// 每个用户的独立锁:key=userId,value=ReentrantLock
|
||||||
|
private final ConcurrentHashMap<Long, ReentrantLock> userLockMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PrizeOnlineService prizeOnlineService;
|
||||||
|
@Autowired
|
||||||
|
private RedissonClient redissonClient;
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
@Autowired
|
||||||
|
private AccountService accountService;
|
||||||
|
@Autowired
|
||||||
|
private SystemConfigManager systemConfigManager;
|
||||||
|
@Autowired
|
||||||
|
private PointManager pointManager;
|
||||||
|
@Autowired
|
||||||
|
private DrawService drawService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户抽奖(核心方法,优化后)
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return 中奖奖品
|
||||||
|
*/
|
||||||
|
public PrizeOnline draw(Long userId) {
|
||||||
|
User user = userService.getById(userId);
|
||||||
|
if(user == null){
|
||||||
|
throw new ServiceException("用户不存在");
|
||||||
|
}
|
||||||
|
boolean openDraw = drawService.getOpenDraw(user.getGender());
|
||||||
|
if(!openDraw){
|
||||||
|
throw new ServiceException("暂未开启积分抽奖,请等待活动通知");
|
||||||
|
}
|
||||||
|
boolean select = GenderEnum.isSelect(user.getGender());
|
||||||
|
if(select){
|
||||||
|
throw new ServiceException("请选择性别后在抽奖");
|
||||||
|
}
|
||||||
|
Account account = accountService.getByUserId(user.getId());
|
||||||
|
Integer drawPoint = drawService.getDrawPoint(user.getGender());
|
||||||
|
if(account.getPoints() < drawPoint){
|
||||||
|
throw new ServiceException("积分不足");
|
||||||
|
}
|
||||||
|
ReentrantLock userLock = userLockMap.computeIfAbsent(userId, k -> new ReentrantLock());
|
||||||
|
try {
|
||||||
|
boolean lockAcquired = userLock.tryLock(LOCK_TIMEOUT, TimeUnit.MILLISECONDS);
|
||||||
|
if (!lockAcquired) {
|
||||||
|
log.warn("用户{}抽奖请求太频繁,获取锁失败", userId);
|
||||||
|
throw new ServiceException("您的请求太频繁,请稍后再试");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Account accountNew = accountService.getByUserId(user.getId());
|
||||||
|
if(accountNew.getPoints() < drawPoint){
|
||||||
|
throw new ServiceException("积分不足");
|
||||||
|
}
|
||||||
|
PrizeOnline winPrize = doDrawLogic(user,drawPoint);
|
||||||
|
return winPrize;
|
||||||
|
} finally {
|
||||||
|
userLock.unlock();
|
||||||
|
// 6. 清理未使用的锁(防止内存溢出)
|
||||||
|
cleanUnusedLock(userId);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.error("用户{}抽奖获取锁被中断", userId, e);
|
||||||
|
Thread.currentThread().interrupt(); // 恢复中断状态
|
||||||
|
throw new ServiceException("抽奖请求处理中,请稍后再试");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("用户{}抽奖失败", userId, e);
|
||||||
|
throw new ServiceException("抽奖失败,请重新刷新页面后在尝试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实际抽奖逻辑(抽离出来,便于维护)
|
||||||
|
*/
|
||||||
|
private PrizeOnline doDrawLogic(User user,Integer drawPoint) {
|
||||||
|
Long userId = user.getId();
|
||||||
|
// 步骤1:获取用户当前累计抽数(缓存+数据库兜底)
|
||||||
|
int currentContinuousDraws = getContinuousDraws(userId);
|
||||||
|
int newContinuousDraws = currentContinuousDraws + 1;
|
||||||
|
log.info("用户{}当前累计抽数:{},本次抽数:{}", userId, currentContinuousDraws, newContinuousDraws);
|
||||||
|
// 步骤2:获取有效奖品列表(启用状态,排除谢谢惠顾)
|
||||||
|
List<PrizeOnline> validPrizes = prizeOnlineService.selectPrizeOnlineList(user.getGender());
|
||||||
|
if (validPrizes.isEmpty()) {
|
||||||
|
throw new ServiceException("无有效奖品,请刷新页面后再次抽奖");
|
||||||
|
}
|
||||||
|
// 步骤3:执行抽奖规则(保底→最低抽数过滤→概率抽奖)
|
||||||
|
PrizeOnline winPrize = null;
|
||||||
|
// 3.1 保底规则判断(优先触发)
|
||||||
|
winPrize = checkGuaranteeRule(validPrizes, newContinuousDraws);
|
||||||
|
// 3.2 未触发保底,执行概率抽奖(含最低中奖抽数过滤)
|
||||||
|
if (winPrize == null) {
|
||||||
|
winPrize = executeProbabilityDraw(validPrizes, newContinuousDraws);
|
||||||
|
}
|
||||||
|
// 步骤4:处理中奖结果,确定最终奖品ID和累计抽数重置
|
||||||
|
if(winPrize == null){
|
||||||
|
winPrize = new PrizeOnline(); // TODO 谢谢惠顾
|
||||||
|
}
|
||||||
|
// 步骤5:持久化抽奖记录+更新缓存
|
||||||
|
winPrizeAfter(winPrize, user, drawPoint, newContinuousDraws);
|
||||||
|
// 步骤6:返回中奖奖品
|
||||||
|
return winPrize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保底规则判断
|
||||||
|
* @param validPrizes 有效奖品列表
|
||||||
|
* @param currentDraws 当前累计抽数
|
||||||
|
* @return 保底中奖的奖品(无则返回null)
|
||||||
|
*/
|
||||||
|
private PrizeOnline checkGuaranteeRule(List<PrizeOnline> validPrizes, int currentDraws) {
|
||||||
|
// 按保底抽数升序排序,优先触发保底抽数小的奖品
|
||||||
|
validPrizes.sort(Comparator.comparingInt(PrizeOnline::getGuaranteeDraws));
|
||||||
|
for (PrizeOnline prize : validPrizes) {
|
||||||
|
int guaranteeDraws = prize.getGuaranteeDraws();
|
||||||
|
if (guaranteeDraws > 0 && currentDraws >= guaranteeDraws) {
|
||||||
|
log.info("触发保底规则,用户抽中奖品:{}", prize.getPrizeName());
|
||||||
|
return prize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行概率抽奖(含最低中奖抽数过滤)
|
||||||
|
* @param validPrizes 有效奖品列表
|
||||||
|
* @param currentDraws 当前累计抽数
|
||||||
|
* @return 中奖奖品(无则返回null)
|
||||||
|
*/
|
||||||
|
private PrizeOnline executeProbabilityDraw(List<PrizeOnline> validPrizes, int currentDraws) {
|
||||||
|
// 步骤1:过滤出满足最低中奖抽数的奖品
|
||||||
|
List<PrizeOnline> filterPrizes = filterByMinWinDraws(validPrizes, currentDraws);
|
||||||
|
if (filterPrizes.isEmpty()) {
|
||||||
|
log.info("无满足最低中奖抽数的奖品,返回谢谢惠顾");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 步骤2:计算奖品的概率总和(放大为整数,提升精度)
|
||||||
|
double totalProbability = 0.0;
|
||||||
|
Map<PrizeOnline, Double> prizeProbMap = new LinkedHashMap<>(); // 保留顺序
|
||||||
|
for (PrizeOnline prize : filterPrizes) {
|
||||||
|
double prob = prize.getWinProbability().doubleValue();
|
||||||
|
if (prob < 0 || prob > 1) {
|
||||||
|
log.warn("奖品{}中奖率{}非法,默认设为0", prize.getPrizeName(), prob);
|
||||||
|
prob = 0.0;
|
||||||
|
}
|
||||||
|
prizeProbMap.put(prize, prob);
|
||||||
|
totalProbability += prob;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 步骤3:若总概率为0,直接返回null
|
||||||
|
if (totalProbability <= 0) {
|
||||||
|
log.info("满足条件的奖品总中奖率为0,返回谢谢惠顾");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 步骤4:生成随机数(放大10000倍,转为整数计算,减少浮点误差)
|
||||||
|
int randomNum = new Random().nextInt((int) (totalProbability * RANDOM_MAX));
|
||||||
|
int currentNum = 0;
|
||||||
|
|
||||||
|
// 步骤5:匹配中奖奖品
|
||||||
|
for (Map.Entry<PrizeOnline, Double> entry : prizeProbMap.entrySet()) {
|
||||||
|
PrizeOnline prize = entry.getKey();
|
||||||
|
double prob = entry.getValue();
|
||||||
|
int probInt = (int) (prob * RANDOM_MAX);
|
||||||
|
currentNum += probInt;
|
||||||
|
if (randomNum < currentNum) {
|
||||||
|
log.info("概率抽奖抽中奖品:{}", prize.getPrizeName());
|
||||||
|
return prize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过滤出满足最低中奖抽数的奖品
|
||||||
|
*/
|
||||||
|
private List<PrizeOnline> filterByMinWinDraws(List<PrizeOnline> prizes, int currentDraws) {
|
||||||
|
List<PrizeOnline> filterList = new ArrayList<>();
|
||||||
|
for (PrizeOnline prize : prizes) {
|
||||||
|
if (currentDraws >= prize.getMinWinDraws()) {
|
||||||
|
filterList.add(prize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filterList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户累计抽数(缓存优先,数据库兜底)
|
||||||
|
*/
|
||||||
|
private int getContinuousDraws(Long userId) {
|
||||||
|
String cacheKey = String.format(USER_DRAW_COUNT_KEY, userId);
|
||||||
|
// 1. 从Redis缓存获取
|
||||||
|
RBucket<Integer> bucket = redissonClient.getBucket(cacheKey);
|
||||||
|
Integer cacheCount = bucket.get();
|
||||||
|
if (cacheCount != null) {
|
||||||
|
return cacheCount;
|
||||||
|
}
|
||||||
|
// 2. 缓存未命中,从数据库查询最后一次累计抽数
|
||||||
|
// Integer dbCount = userDrawRecordMapper.selectLastContinuousDraws(userId);
|
||||||
|
Integer dbCount = 0;
|
||||||
|
int finalCount = dbCount == null ? 0 : dbCount;
|
||||||
|
// 3. 存入缓存(设置过期时间)
|
||||||
|
bucket.set(finalCount, USER_DRAW_COUNT_EXPIRE, java.util.concurrent.TimeUnit.SECONDS);
|
||||||
|
return finalCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PrizeWinningRecordService prizeWinningRecordService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存抽奖记录(事务控制)
|
||||||
|
*/
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void winPrizeAfter(PrizeOnline prizeOnline, User user,Integer drawPoint, int continuousDraws) {
|
||||||
|
// 扣减积分
|
||||||
|
String traceId = IdManager.nextIdStr();
|
||||||
|
PointChangeLog pointChangeLog = pointManager.drawPoint(prizeOnline, user, drawPoint, traceId);
|
||||||
|
// 记录用户抽奖记录
|
||||||
|
prizeWinningRecordService.winningRecord(pointChangeLog, prizeOnline, user, drawPoint);
|
||||||
|
// 更新缓存
|
||||||
|
String cacheKey = String.format(USER_DRAW_COUNT_KEY, user.getId());
|
||||||
|
RBucket<Integer> bucket = redissonClient.getBucket(cacheKey);
|
||||||
|
bucket.set(continuousDraws, USER_DRAW_COUNT_EXPIRE, java.util.concurrent.TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理长时间未使用的用户锁(可选,防止内存溢出)
|
||||||
|
* 这里简单实现:若锁未被持有,则移除(可根据业务增加时间判断)
|
||||||
|
*/
|
||||||
|
private void cleanUnusedLock(Long userId) {
|
||||||
|
ReentrantLock lock = userLockMap.get(userId);
|
||||||
|
if (lock != null && !lock.isLocked()) {
|
||||||
|
userLockMap.remove(userId);
|
||||||
|
log.debug("清理用户{}的锁", userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
207
ruoyi-cai/src/main/java/com/ruoyi/cai/lottery/PointManager.java
Normal file
207
ruoyi-cai/src/main/java/com/ruoyi/cai/lottery/PointManager.java
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
package com.ruoyi.cai.lottery;
|
||||||
|
|
||||||
|
import com.ruoyi.cai.domain.*;
|
||||||
|
import com.ruoyi.cai.enums.SystemConfigEnum;
|
||||||
|
import com.ruoyi.cai.enums.point.PointChangeLogActionTypeEnum;
|
||||||
|
import com.ruoyi.cai.enums.point.PointChangeTraceTypeEnum;
|
||||||
|
import com.ruoyi.cai.manager.SystemConfigManager;
|
||||||
|
import com.ruoyi.cai.mapper.AccountMapper;
|
||||||
|
import com.ruoyi.cai.service.PointChangeLogService;
|
||||||
|
import com.ruoyi.cai.service.PointRecordLogService;
|
||||||
|
import com.ruoyi.cai.service.UserService;
|
||||||
|
import com.ruoyi.cai.ws.constant.RedisConstant;
|
||||||
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
|
import com.ruoyi.common.utils.ServletUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.redisson.api.RAtomicLong;
|
||||||
|
import org.redisson.api.RedissonClient;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class PointManager {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SystemConfigManager systemConfigManager;
|
||||||
|
@Autowired
|
||||||
|
private RedissonClient redissonClient;
|
||||||
|
@Resource
|
||||||
|
private AccountMapper accountMapper;
|
||||||
|
@Autowired
|
||||||
|
private PointChangeLogService pointChangeLogService;
|
||||||
|
@Autowired
|
||||||
|
private PointRecordLogService pointRecordLogService;
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
public String getRedisKey(Long userId){
|
||||||
|
LocalDate date = LocalDate.now();
|
||||||
|
String dateStr = date.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
||||||
|
return String.format(RedisConstant.POINT_DAYS_USER, dateStr, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class CheckPointIncr{
|
||||||
|
private boolean allowPoint;
|
||||||
|
private Long givePoint;
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public CheckPointIncr checkPointIncr(Long userId,Long givePoint){
|
||||||
|
CheckPointIncr result = new CheckPointIncr();
|
||||||
|
Long maxPointDays = systemConfigManager.getSystemConfigOfLong(SystemConfigEnum.MAX_POINT_DAY);
|
||||||
|
if(maxPointDays == null || maxPointDays <= 0){ // 未开启
|
||||||
|
result.setAllowPoint(true);
|
||||||
|
result.setGivePoint(givePoint);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
String redisKey = getRedisKey(userId);
|
||||||
|
RAtomicLong atomicLong = redissonClient.getAtomicLong(redisKey);
|
||||||
|
Long userDaysPoint = atomicLong.get();
|
||||||
|
if(userDaysPoint >= maxPointDays){ // 今日获取积分已超过每日最大积分
|
||||||
|
result.setAllowPoint(false);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if(givePoint + userDaysPoint >= maxPointDays) { // 算上这次已经超过每日最大积分
|
||||||
|
Long currentGivePoint = maxPointDays - userDaysPoint;
|
||||||
|
String remark = String.format("实际需赠送%s,今日已超过上限%s,只需赠送%s", givePoint,maxPointDays,currentGivePoint);
|
||||||
|
result.setAllowPoint(true);
|
||||||
|
result.setGivePoint(currentGivePoint);
|
||||||
|
result.setRemark(remark);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.setAllowPoint(true);
|
||||||
|
result.setGivePoint(givePoint);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void adminChange(Long userId, Long givePoint){
|
||||||
|
accountMapper.incrPoint(userId, givePoint);
|
||||||
|
User user = userService.getById(userId);
|
||||||
|
PointChangeLog pointChangeLog = new PointChangeLog();
|
||||||
|
pointChangeLog.setUserId(userId);
|
||||||
|
pointChangeLog.setUsercode(user.getUsercode());
|
||||||
|
pointChangeLog.setActionType(PointChangeLogActionTypeEnum.SYSTEM.getCode());
|
||||||
|
String message = String.format("系统调整:%s%s积分", givePoint > 0 ? "新增" : "减少", givePoint);
|
||||||
|
pointChangeLog.setMessage(message);
|
||||||
|
pointChangeLog.setChangeValue(givePoint);
|
||||||
|
pointChangeLog.setIsAdmin(true);
|
||||||
|
pointChangeLog.setTraceLinkType(PointChangeTraceTypeEnum.SYSTEM.getCode());
|
||||||
|
pointChangeLogService.save(pointChangeLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void adminInvite(Long userId, Long givePoint, Long inviteUserId, String traceId){
|
||||||
|
CheckPointIncr checkPointIncr = this.checkPointIncr(userId, givePoint);
|
||||||
|
if(checkPointIncr.isAllowPoint()){
|
||||||
|
User user = userService.getById(userId);
|
||||||
|
User inviteUser = userService.getById(inviteUserId);
|
||||||
|
PointChangeLog pointChangeLog = new PointChangeLog();
|
||||||
|
pointChangeLog.setUserId(userId);
|
||||||
|
pointChangeLog.setUsercode(user.getUsercode());
|
||||||
|
pointChangeLog.setActionType(PointChangeLogActionTypeEnum.SYSTEM.getCode());
|
||||||
|
String message = String.format("从【%s】的充值中获得%s积分", inviteUser.getNickname(), givePoint);
|
||||||
|
pointChangeLog.setMessage(message);
|
||||||
|
pointChangeLog.setTarUserId(inviteUser.getId());
|
||||||
|
pointChangeLog.setTarUsercode(inviteUser.getUsercode());
|
||||||
|
pointChangeLog.setTarName(inviteUser.getNickname());
|
||||||
|
pointChangeLog.setTarImg(inviteUser.getAvatar());
|
||||||
|
pointChangeLog.setChangeValue(givePoint);
|
||||||
|
pointChangeLog.setIsAdmin(true);
|
||||||
|
pointChangeLog.setRemark(checkPointIncr.getRemark());
|
||||||
|
pointChangeLog.setTraceLinkType(PointChangeTraceTypeEnum.INVITE.getCode());
|
||||||
|
pointChangeLog.setTraceId(traceId);
|
||||||
|
pointChangeLogService.save(pointChangeLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public PointRecordLog rechargePoint(RechargeOrder rechargeOrder, User user){
|
||||||
|
if(rechargeOrder.getGivePoint() == null || rechargeOrder.getGivePoint() == 0){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
log.info("开始赠送积分 orderNo={}", rechargeOrder.getOrderNo());
|
||||||
|
CheckPointIncr checkPointIncr = this.checkPointIncr(user.getId(), rechargeOrder.getGivePoint());
|
||||||
|
if(!checkPointIncr.isAllowPoint()){ // 不参与分销
|
||||||
|
PointRecordLog pointRecordLog = pointRecordLogService.initOrder(rechargeOrder, user);
|
||||||
|
return pointRecordLog;
|
||||||
|
}
|
||||||
|
accountMapper.incrPoint(user.getId(), checkPointIncr.getGivePoint());
|
||||||
|
PointChangeLog pointChangeLog = new PointChangeLog();
|
||||||
|
pointChangeLog.setUserId(user.getId());
|
||||||
|
pointChangeLog.setUsercode(user.getUsercode());
|
||||||
|
pointChangeLog.setActionType(PointChangeLogActionTypeEnum.PAY.getCode());
|
||||||
|
pointChangeLog.setMessage("充值赠送"+checkPointIncr.getGivePoint()+"积分");
|
||||||
|
pointChangeLog.setChangeValue(checkPointIncr.getGivePoint());
|
||||||
|
pointChangeLog.setIsAdmin(false);
|
||||||
|
pointChangeLog.setTraceLinkType(PointChangeTraceTypeEnum.PAY.getCode());
|
||||||
|
pointChangeLog.setTraceId(rechargeOrder.getOrderNo());
|
||||||
|
pointChangeLogService.save(pointChangeLog);
|
||||||
|
PointRecordLog pointRecordLog = pointRecordLogService.initOrder(rechargeOrder, user);
|
||||||
|
String redisKey = getRedisKey(user.getId());
|
||||||
|
RAtomicLong atomicLong = redissonClient.getAtomicLong(redisKey);
|
||||||
|
atomicLong.addAndGet(checkPointIncr.getGivePoint());
|
||||||
|
return pointRecordLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单分销分成
|
||||||
|
*/
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void rechargeOrderInviteChange(Long userId, Long givePoint, Long inviteUserId, String traceId){
|
||||||
|
CheckPointIncr checkPointIncr = this.checkPointIncr(userId, givePoint);
|
||||||
|
if(checkPointIncr.isAllowPoint()){ // 参与积分
|
||||||
|
User user = userService.getById(userId);
|
||||||
|
User inviteUser = userService.getById(inviteUserId);
|
||||||
|
PointChangeLog pointChangeLog = new PointChangeLog();
|
||||||
|
pointChangeLog.setUserId(userId);
|
||||||
|
pointChangeLog.setUsercode(user.getUsercode());
|
||||||
|
pointChangeLog.setActionType(PointChangeLogActionTypeEnum.INVITE.getCode());
|
||||||
|
String message = String.format("从【%s】中充值分成新增%s积分", inviteUser.getNickname(), givePoint);
|
||||||
|
pointChangeLog.setMessage(message);
|
||||||
|
pointChangeLog.setTarUserId(inviteUser.getId());
|
||||||
|
pointChangeLog.setTarUsercode(inviteUser.getUsercode());
|
||||||
|
pointChangeLog.setTarName(inviteUser.getNickname());
|
||||||
|
pointChangeLog.setTarImg(inviteUser.getAvatar());
|
||||||
|
pointChangeLog.setChangeValue(givePoint);
|
||||||
|
pointChangeLog.setRemark(checkPointIncr.getRemark());
|
||||||
|
pointChangeLog.setIsAdmin(false);
|
||||||
|
pointChangeLog.setTraceLinkType(PointChangeTraceTypeEnum.INVITE.getCode());
|
||||||
|
pointChangeLog.setTraceId(traceId);
|
||||||
|
pointChangeLogService.save(pointChangeLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public PointChangeLog drawPoint(PrizeOnline prizeOnline, User user, Integer drawPoint, String traceId){
|
||||||
|
boolean bb = accountMapper.decrPoint(user.getId(), Long.valueOf(drawPoint));
|
||||||
|
if(!bb){
|
||||||
|
throw new ServiceException("积分不足");
|
||||||
|
}
|
||||||
|
PointChangeLog pointChangeLog = new PointChangeLog();
|
||||||
|
pointChangeLog.setActionType(PointChangeLogActionTypeEnum.USE.getCode());
|
||||||
|
pointChangeLog.setUserId(user.getId());
|
||||||
|
pointChangeLog.setUsercode(user.getUsercode());
|
||||||
|
String message = String.format("抽中【%s】", prizeOnline.getPrizeName());
|
||||||
|
pointChangeLog.setMessage(message);
|
||||||
|
pointChangeLog.setChangeValue(Long.valueOf(drawPoint));
|
||||||
|
pointChangeLog.setOperateIp(ServletUtils.getClientIP());
|
||||||
|
pointChangeLog.setIsAdmin(false);
|
||||||
|
pointChangeLog.setTraceLinkType(PointChangeTraceTypeEnum.USE.getCode());
|
||||||
|
pointChangeLog.setTraceId(traceId);
|
||||||
|
pointChangeLogService.save(pointChangeLog);
|
||||||
|
return pointChangeLog;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.ruoyi.cai.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.ruoyi.cai.domain.PrizeInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽奖奖品Mapper接口
|
||||||
|
*
|
||||||
|
* @author 77
|
||||||
|
* @date 2025-12-23
|
||||||
|
*/
|
||||||
|
public interface PrizeInfoMapper extends BaseMapper<PrizeInfo> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.ruoyi.cai.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.ruoyi.cai.domain.PrizeOnline;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已发布奖品Mapper接口
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2025-12-23
|
||||||
|
*/
|
||||||
|
public interface PrizeOnlineMapper extends BaseMapper<PrizeOnline> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.ruoyi.cai.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.cai.domain.PrizeWinningRecord;
|
||||||
|
import com.ruoyi.cai.dto.admin.vo.winningRecord.PrizeWinningRecordAdminVO;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中奖记录Mapper接口
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-01-08
|
||||||
|
*/
|
||||||
|
public interface PrizeWinningRecordMapper extends BaseMapper<PrizeWinningRecord> {
|
||||||
|
|
||||||
|
Page<PrizeWinningRecordAdminVO> pageAdmin(Page<Object> build, @Param("query") PrizeWinningRecordAdminVO query);
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
|
|||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.alipay.api.AlipayApiException;
|
import com.alipay.api.AlipayApiException;
|
||||||
import com.alipay.api.domain.AlipayTradeQueryModel;
|
import com.alipay.api.domain.AlipayTradeQueryModel;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.ijpay.alipay.AliPayApi;
|
import com.ijpay.alipay.AliPayApi;
|
||||||
import com.ijpay.alipay.AliPayApiConfig;
|
import com.ijpay.alipay.AliPayApiConfig;
|
||||||
@@ -12,22 +13,23 @@ import com.ijpay.core.enums.SignType;
|
|||||||
import com.ijpay.core.kit.WxPayKit;
|
import com.ijpay.core.kit.WxPayKit;
|
||||||
import com.ijpay.wxpay.WxPayApi;
|
import com.ijpay.wxpay.WxPayApi;
|
||||||
import com.ijpay.wxpay.model.OrderQueryModel;
|
import com.ijpay.wxpay.model.OrderQueryModel;
|
||||||
import com.ruoyi.cai.domain.Goods;
|
import com.ruoyi.cai.domain.*;
|
||||||
import com.ruoyi.cai.domain.PayConfig;
|
|
||||||
import com.ruoyi.cai.domain.RechargeOrder;
|
|
||||||
import com.ruoyi.cai.domain.VipOrder;
|
|
||||||
import com.ruoyi.cai.dto.ConsumeResp;
|
import com.ruoyi.cai.dto.ConsumeResp;
|
||||||
import com.ruoyi.cai.dto.app.vo.pay.OrderPayStatusResp;
|
import com.ruoyi.cai.dto.app.vo.pay.OrderPayStatusResp;
|
||||||
import com.ruoyi.cai.dto.commom.consumer.RechargeConsumerResp;
|
import com.ruoyi.cai.dto.commom.consumer.RechargeConsumerResp;
|
||||||
|
import com.ruoyi.cai.enums.SystemConfigEnum;
|
||||||
import com.ruoyi.cai.manager.AwardManager;
|
import com.ruoyi.cai.manager.AwardManager;
|
||||||
import com.ruoyi.cai.manager.ConsumerManager;
|
import com.ruoyi.cai.manager.ConsumerManager;
|
||||||
|
import com.ruoyi.cai.manager.SystemConfigManager;
|
||||||
import com.ruoyi.cai.pay.model.PayQueryModel;
|
import com.ruoyi.cai.pay.model.PayQueryModel;
|
||||||
import com.ruoyi.cai.service.*;
|
import com.ruoyi.cai.service.*;
|
||||||
|
import com.ruoyi.cai.trdpay.TrdPayTypeEnum;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -51,6 +53,27 @@ public class PayManager {
|
|||||||
private PayConfigManager payConfigManager;
|
private PayConfigManager payConfigManager;
|
||||||
@Autowired
|
@Autowired
|
||||||
private GoodsService goodsService;
|
private GoodsService goodsService;
|
||||||
|
@Autowired
|
||||||
|
private SystemConfigManager systemConfigManager;
|
||||||
|
|
||||||
|
|
||||||
|
public String getNotifyDomain(String notifyUrl) {
|
||||||
|
if(!StringUtils.isBlank(notifyUrl)){
|
||||||
|
return notifyUrl;
|
||||||
|
}else{
|
||||||
|
String baseNotifyUrl = systemConfigManager.getSystemConfig(SystemConfigEnum.PAY_NOTIFY_URL);
|
||||||
|
return baseNotifyUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNotifyUrl(PayTrdConfig config, TrdPayTypeEnum type,boolean wx) {
|
||||||
|
if(!StringUtils.isBlank(config.getNotifyUrl())){
|
||||||
|
return type.getNotifyUrl(config.getNotifyUrl(),wx);
|
||||||
|
}else{
|
||||||
|
String notifyUrl = systemConfigManager.getSystemConfig(SystemConfigEnum.PAY_NOTIFY_URL);
|
||||||
|
return type.getNotifyUrl(notifyUrl,wx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public PayQueryModel queryOrder(PayConfig payConfig,String orderNo,String appid) throws AlipayApiException {
|
public PayQueryModel queryOrder(PayConfig payConfig,String orderNo,String appid) throws AlipayApiException {
|
||||||
if(PayTypeEnum.ALI.getCode().equals(payConfig.getPayType())){
|
if(PayTypeEnum.ALI.getCode().equals(payConfig.getPayType())){
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ package com.ruoyi.cai.service;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.ruoyi.cai.domain.*;
|
import com.ruoyi.cai.domain.Account;
|
||||||
|
import com.ruoyi.cai.domain.ConsumeLog;
|
||||||
|
import com.ruoyi.cai.domain.Gift;
|
||||||
|
import com.ruoyi.cai.domain.User;
|
||||||
import com.ruoyi.cai.dto.admin.vo.AccountAdminVo;
|
import com.ruoyi.cai.dto.admin.vo.AccountAdminVo;
|
||||||
import com.ruoyi.cai.dto.video.VideoSettleResp;
|
import com.ruoyi.cai.dto.video.VideoSettleResp;
|
||||||
import com.ruoyi.cai.dto.video.WithholdingFeeUserResp;
|
import com.ruoyi.cai.dto.video.WithholdingFeeUserResp;
|
||||||
@@ -31,8 +34,6 @@ public interface AccountService extends IService<Account> {
|
|||||||
|
|
||||||
void withdrawFail(Long userId, Long incomeCoin, Long traceId);
|
void withdrawFail(Long userId, Long incomeCoin, Long traceId);
|
||||||
|
|
||||||
PointRecordLog rechargePoint(RechargeOrder rechargeOrder, User user);
|
|
||||||
|
|
||||||
void recharge(ConsumeLog consumeLog);
|
void recharge(ConsumeLog consumeLog);
|
||||||
|
|
||||||
void rechargeAdminIgnoreAccount(ConsumeLog consumeLog);
|
void rechargeAdminIgnoreAccount(ConsumeLog consumeLog);
|
||||||
|
|||||||
@@ -11,11 +11,4 @@ import com.ruoyi.cai.domain.PointChangeLog;
|
|||||||
*/
|
*/
|
||||||
public interface PointChangeLogService extends IService<PointChangeLog> {
|
public interface PointChangeLogService extends IService<PointChangeLog> {
|
||||||
|
|
||||||
void rechargeOrderChange(String orderNo, Long userId, Long givePoint);
|
|
||||||
|
|
||||||
void rechargeOrderInviteChange(Long userId, Long givePoint, Long inviteUserId, String traceId);
|
|
||||||
|
|
||||||
void adminChange(Long userId, Long givePoint);
|
|
||||||
|
|
||||||
void adminInvite(Long userId, Long givePoint, Long inviteUserId, String traceId);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.ruoyi.cai.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.ruoyi.cai.domain.PrizeInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽奖奖品Service接口
|
||||||
|
*
|
||||||
|
* @author 77
|
||||||
|
* @date 2025-12-23
|
||||||
|
*/
|
||||||
|
public interface PrizeInfoService extends IService<PrizeInfo> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.ruoyi.cai.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.ruoyi.cai.domain.PrizeOnline;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已发布奖品Service接口
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2025-12-23
|
||||||
|
*/
|
||||||
|
public interface PrizeOnlineService extends IService<PrizeOnline> {
|
||||||
|
|
||||||
|
List<PrizeOnline> selectPrizeOnlineList(Integer gender);
|
||||||
|
|
||||||
|
void reset(Integer gender, List<PrizeOnline> bo);
|
||||||
|
|
||||||
|
List<PrizeOnline> prizeUp();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.ruoyi.cai.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.ruoyi.cai.domain.PointChangeLog;
|
||||||
|
import com.ruoyi.cai.domain.PrizeOnline;
|
||||||
|
import com.ruoyi.cai.domain.PrizeWinningRecord;
|
||||||
|
import com.ruoyi.cai.domain.User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中奖记录Service接口
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-01-08
|
||||||
|
*/
|
||||||
|
public interface PrizeWinningRecordService extends IService<PrizeWinningRecord> {
|
||||||
|
|
||||||
|
void winningRecord(PointChangeLog pointChangeLog, PrizeOnline prizeOnline, User user, Integer drawPoint);
|
||||||
|
}
|
||||||
@@ -51,8 +51,14 @@ public class AccountCashServiceImpl extends ServiceImpl<AccountCashMapper, Accou
|
|||||||
private RankAdminManager rankAdminManager;
|
private RankAdminManager rankAdminManager;
|
||||||
@Autowired
|
@Autowired
|
||||||
private AccountBlackService accountBlackService;
|
private AccountBlackService accountBlackService;
|
||||||
|
@Autowired
|
||||||
|
private SystemConfigManager systemConfigManager;
|
||||||
@Override
|
@Override
|
||||||
public void withdraw(WithdrawReq res) {
|
public void withdraw(WithdrawReq res) {
|
||||||
|
boolean openWithdraw = systemConfigManager.getSystemConfigOfBool(SystemConfigEnum.OPEN_WITHDRAW);
|
||||||
|
if(!openWithdraw){
|
||||||
|
throw new ServiceException("提现失败,错误码: 800100");
|
||||||
|
}
|
||||||
AccountBankcard one = accountBankcardService.getOne(Wrappers.lambdaQuery(AccountBankcard.class)
|
AccountBankcard one = accountBankcardService.getOne(Wrappers.lambdaQuery(AccountBankcard.class)
|
||||||
.eq(AccountBankcard::getUserId, res.getUserId()).last("limit 1"));
|
.eq(AccountBankcard::getUserId, res.getUserId()).last("limit 1"));
|
||||||
if(one == null){
|
if(one == null){
|
||||||
|
|||||||
@@ -217,22 +217,6 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
accountChangeLogService.saveLogNoAdmin(user.getId(),user.getUsercode(), AccountChangeCodeEnum.WITHDRAW_FAIL,incomeCoin,traceId);
|
accountChangeLogService.saveLogNoAdmin(user.getId(),user.getUsercode(), AccountChangeCodeEnum.WITHDRAW_FAIL,incomeCoin,traceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private PointRecordLogService pointRecordLogService;
|
|
||||||
@Autowired
|
|
||||||
private PointChangeLogService pointChangeLogService;
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
@Override
|
|
||||||
public PointRecordLog rechargePoint(RechargeOrder rechargeOrder, User user){
|
|
||||||
if(rechargeOrder.getGivePoint() == null || rechargeOrder.getGivePoint() == 0){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
log.info("开始赠送积分 orderNo={}", rechargeOrder.getOrderNo());
|
|
||||||
pointChangeLogService.rechargeOrderChange(rechargeOrder.getOrderNo(), rechargeOrder.getUserId(),rechargeOrder.getGivePoint());
|
|
||||||
PointRecordLog pointRecordLog = pointRecordLogService.initOrder(rechargeOrder, user);
|
|
||||||
return pointRecordLog;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.ruoyi.cai.service.impl;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.ruoyi.cai.domain.PointChangeLog;
|
import com.ruoyi.cai.domain.PointChangeLog;
|
||||||
|
import com.ruoyi.cai.domain.PrizeOnline;
|
||||||
import com.ruoyi.cai.domain.User;
|
import com.ruoyi.cai.domain.User;
|
||||||
import com.ruoyi.cai.enums.point.PointChangeLogActionTypeEnum;
|
import com.ruoyi.cai.enums.point.PointChangeLogActionTypeEnum;
|
||||||
import com.ruoyi.cai.enums.point.PointChangeTraceTypeEnum;
|
import com.ruoyi.cai.enums.point.PointChangeTraceTypeEnum;
|
||||||
@@ -9,6 +10,7 @@ import com.ruoyi.cai.mapper.AccountMapper;
|
|||||||
import com.ruoyi.cai.mapper.PointChangeLogMapper;
|
import com.ruoyi.cai.mapper.PointChangeLogMapper;
|
||||||
import com.ruoyi.cai.service.PointChangeLogService;
|
import com.ruoyi.cai.service.PointChangeLogService;
|
||||||
import com.ruoyi.cai.service.UserService;
|
import com.ruoyi.cai.service.UserService;
|
||||||
|
import com.ruoyi.common.utils.ServletUtils;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -21,88 +23,6 @@ import javax.annotation.Resource;
|
|||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
* @date 2025-12-10
|
* @date 2025-12-10
|
||||||
*/
|
*/
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Service
|
@Service
|
||||||
public class PointChangeLogServiceImpl extends ServiceImpl<PointChangeLogMapper,PointChangeLog> implements PointChangeLogService {
|
public class PointChangeLogServiceImpl extends ServiceImpl<PointChangeLogMapper,PointChangeLog> implements PointChangeLogService {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserService userService;
|
|
||||||
@Resource
|
|
||||||
private AccountMapper accountMapper;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void rechargeOrderChange(String orderNo, Long userId, Long givePoint){
|
|
||||||
accountMapper.incrPoint(userId, givePoint);
|
|
||||||
User user = userService.getById(userId);
|
|
||||||
PointChangeLog pointChangeLog = new PointChangeLog();
|
|
||||||
pointChangeLog.setUserId(userId);
|
|
||||||
pointChangeLog.setUsercode(user.getUsercode());
|
|
||||||
pointChangeLog.setActionType(PointChangeLogActionTypeEnum.PAY.getCode());
|
|
||||||
pointChangeLog.setMessage("充值赠送"+givePoint+"积分");
|
|
||||||
pointChangeLog.setChangeValue(givePoint);
|
|
||||||
pointChangeLog.setIsAdmin(false);
|
|
||||||
pointChangeLog.setTraceLinkType(PointChangeTraceTypeEnum.PAY.getCode());
|
|
||||||
pointChangeLog.setTraceId(orderNo);
|
|
||||||
this.save(pointChangeLog);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void rechargeOrderInviteChange(Long userId, Long givePoint, Long inviteUserId, String traceId){
|
|
||||||
accountMapper.incrPoint(userId, givePoint);
|
|
||||||
User user = userService.getById(userId);
|
|
||||||
User inviteUser = userService.getById(inviteUserId);
|
|
||||||
PointChangeLog pointChangeLog = new PointChangeLog();
|
|
||||||
pointChangeLog.setUserId(userId);
|
|
||||||
pointChangeLog.setUsercode(user.getUsercode());
|
|
||||||
pointChangeLog.setActionType(PointChangeLogActionTypeEnum.INVITE.getCode());
|
|
||||||
String message = String.format("从【%s】中充值分成新增%s积分", inviteUser.getNickname(), givePoint);
|
|
||||||
pointChangeLog.setMessage(message);
|
|
||||||
pointChangeLog.setTarUserId(inviteUser.getId());
|
|
||||||
pointChangeLog.setTarUsercode(inviteUser.getUsercode());
|
|
||||||
pointChangeLog.setTarName(inviteUser.getNickname());
|
|
||||||
pointChangeLog.setTarImg(inviteUser.getAvatar());
|
|
||||||
pointChangeLog.setChangeValue(givePoint);
|
|
||||||
pointChangeLog.setIsAdmin(false);
|
|
||||||
pointChangeLog.setTraceLinkType(PointChangeTraceTypeEnum.INVITE.getCode());
|
|
||||||
pointChangeLog.setTraceId(traceId);
|
|
||||||
this.save(pointChangeLog);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void adminChange(Long userId, Long givePoint){
|
|
||||||
accountMapper.incrPoint(userId, givePoint);
|
|
||||||
User user = userService.getById(userId);
|
|
||||||
PointChangeLog pointChangeLog = new PointChangeLog();
|
|
||||||
pointChangeLog.setUserId(userId);
|
|
||||||
pointChangeLog.setUsercode(user.getUsercode());
|
|
||||||
pointChangeLog.setActionType(PointChangeLogActionTypeEnum.SYSTEM.getCode());
|
|
||||||
String message = String.format("系统调整:%s%s积分", givePoint > 0 ? "新增" : "减少", givePoint);
|
|
||||||
pointChangeLog.setMessage(message);
|
|
||||||
pointChangeLog.setChangeValue(givePoint);
|
|
||||||
pointChangeLog.setIsAdmin(true);
|
|
||||||
pointChangeLog.setTraceLinkType(PointChangeTraceTypeEnum.SYSTEM.getCode());
|
|
||||||
this.save(pointChangeLog);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void adminInvite(Long userId, Long givePoint, Long inviteUserId, String traceId){
|
|
||||||
accountMapper.incrPoint(userId, givePoint);
|
|
||||||
User user = userService.getById(userId);
|
|
||||||
User inviteUser = userService.getById(inviteUserId);
|
|
||||||
PointChangeLog pointChangeLog = new PointChangeLog();
|
|
||||||
pointChangeLog.setUserId(userId);
|
|
||||||
pointChangeLog.setUsercode(user.getUsercode());
|
|
||||||
pointChangeLog.setActionType(PointChangeLogActionTypeEnum.SYSTEM.getCode());
|
|
||||||
String message = String.format("从【%s】的充值中获得%s积分", inviteUser.getNickname(), givePoint);
|
|
||||||
pointChangeLog.setMessage(message);
|
|
||||||
pointChangeLog.setTarUserId(inviteUser.getId());
|
|
||||||
pointChangeLog.setTarUsercode(inviteUser.getUsercode());
|
|
||||||
pointChangeLog.setTarName(inviteUser.getNickname());
|
|
||||||
pointChangeLog.setTarImg(inviteUser.getAvatar());
|
|
||||||
pointChangeLog.setChangeValue(givePoint);
|
|
||||||
pointChangeLog.setIsAdmin(true);
|
|
||||||
pointChangeLog.setTraceLinkType(PointChangeTraceTypeEnum.INVITE.getCode());
|
|
||||||
pointChangeLog.setTraceId(traceId);
|
|
||||||
this.save(pointChangeLog);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.ruoyi.cai.domain.*;
|
|||||||
import com.ruoyi.cai.dto.AddPointAdminDto;
|
import com.ruoyi.cai.dto.AddPointAdminDto;
|
||||||
import com.ruoyi.cai.enums.ConsumeLogStatus;
|
import com.ruoyi.cai.enums.ConsumeLogStatus;
|
||||||
import com.ruoyi.cai.enums.PointLogType;
|
import com.ruoyi.cai.enums.PointLogType;
|
||||||
|
import com.ruoyi.cai.lottery.PointManager;
|
||||||
import com.ruoyi.cai.manager.IdManager;
|
import com.ruoyi.cai.manager.IdManager;
|
||||||
import com.ruoyi.cai.mapper.AccountMapper;
|
import com.ruoyi.cai.mapper.AccountMapper;
|
||||||
import com.ruoyi.cai.mapper.PointRecordLogMapper;
|
import com.ruoyi.cai.mapper.PointRecordLogMapper;
|
||||||
@@ -39,6 +40,8 @@ public class PointRecordLogServiceImpl extends ServiceImpl<PointRecordLogMapper,
|
|||||||
private AccountMapper accountMapper;
|
private AccountMapper accountMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private PointChangeLogService pointChangeLogService;
|
private PointChangeLogService pointChangeLogService;
|
||||||
|
@Autowired
|
||||||
|
private PointManager pointManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@@ -53,7 +56,7 @@ public class PointRecordLogServiceImpl extends ServiceImpl<PointRecordLogMapper,
|
|||||||
throw new ServiceException("开启分销情况下,无法调整积分为负数");
|
throw new ServiceException("开启分销情况下,无法调整积分为负数");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pointChangeLogService.adminChange(user.getId(),dto.getChangePoints());
|
pointManager.adminChange(user.getId(),dto.getChangePoints());
|
||||||
PointRecordLog pointLog = new PointRecordLog();
|
PointRecordLog pointLog = new PointRecordLog();
|
||||||
pointLog.setPoints(dto.getChangePoints());
|
pointLog.setPoints(dto.getChangePoints());
|
||||||
pointLog.setSourceUserId(user.getId());
|
pointLog.setSourceUserId(user.getId());
|
||||||
@@ -76,7 +79,7 @@ public class PointRecordLogServiceImpl extends ServiceImpl<PointRecordLogMapper,
|
|||||||
pointLog.setStatus(ConsumeLogStatus.ALREADY.getCode());
|
pointLog.setStatus(ConsumeLogStatus.ALREADY.getCode());
|
||||||
if(pointLog.getOnePoints() >= 0 && pointLog.getOneUserId() != null && pointLog.getOneJoin()){
|
if(pointLog.getOnePoints() >= 0 && pointLog.getOneUserId() != null && pointLog.getOneJoin()){
|
||||||
String traceId = IdManager.nextIdStr();
|
String traceId = IdManager.nextIdStr();
|
||||||
pointChangeLogService.adminInvite(pointLog.getOneUserId(),pointLog.getOnePoints(),pointLog.getSourceUserId(),traceId);
|
pointManager.adminInvite(pointLog.getOneUserId(),pointLog.getOnePoints(),pointLog.getSourceUserId(),traceId);
|
||||||
pointLog.setTraceId(traceId);
|
pointLog.setTraceId(traceId);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@@ -141,8 +144,9 @@ public class PointRecordLogServiceImpl extends ServiceImpl<PointRecordLogMapper,
|
|||||||
if(!pointRecordLog.getOneJoin()){
|
if(!pointRecordLog.getOneJoin()){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pointChangeLogService.adminInvite(pointRecordLog.getOneUserId(),pointRecordLog.getOnePoints(),pointRecordLog.getSourceUserId(),traceId);
|
pointManager.rechargeOrderInviteChange(pointRecordLog.getOneUserId(),pointRecordLog.getOnePoints(),pointRecordLog.getSourceUserId(),traceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.ruoyi.cai.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.ruoyi.cai.domain.PrizeInfo;
|
||||||
|
import com.ruoyi.cai.mapper.PrizeInfoMapper;
|
||||||
|
import com.ruoyi.cai.service.PrizeInfoService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽奖奖品Service业务层处理
|
||||||
|
*
|
||||||
|
* @author 77
|
||||||
|
* @date 2025-12-23
|
||||||
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class PrizeInfoServiceImpl extends ServiceImpl<PrizeInfoMapper,PrizeInfo> implements PrizeInfoService {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package com.ruoyi.cai.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.ruoyi.cai.domain.PrizeOnline;
|
||||||
|
import com.ruoyi.cai.dto.commom.user.MinUser;
|
||||||
|
import com.ruoyi.cai.enums.GenderEnum;
|
||||||
|
import com.ruoyi.cai.enums.prize.PrizeTypeEnum;
|
||||||
|
import com.ruoyi.cai.mapper.PrizeOnlineMapper;
|
||||||
|
import com.ruoyi.cai.service.PrizeOnlineService;
|
||||||
|
import com.ruoyi.cai.service.UserService;
|
||||||
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
|
import com.ruoyi.common.helper.LoginHelper;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已发布奖品Service业务层处理
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2025-12-23
|
||||||
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class PrizeOnlineServiceImpl extends ServiceImpl<PrizeOnlineMapper,PrizeOnline> implements PrizeOnlineService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PrizeOnline> selectPrizeOnlineList(Integer gender){
|
||||||
|
return this.list(Wrappers.lambdaQuery(PrizeOnline.class).eq(PrizeOnline::getGender, gender));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void reset(Integer gender, List<PrizeOnline> bo) {
|
||||||
|
if(bo.size() != 9){
|
||||||
|
throw new ServiceException("奖品必须为9个");
|
||||||
|
}
|
||||||
|
boolean hasNone = false;
|
||||||
|
List<Long> prizeIds = new ArrayList<>();
|
||||||
|
for (PrizeOnline prizeOnline : bo) {
|
||||||
|
prizeOnline.setGender(gender);
|
||||||
|
if(PrizeTypeEnum.NONE.getCode().equals(prizeOnline.getPrizeType())){
|
||||||
|
hasNone = true;
|
||||||
|
}
|
||||||
|
if(prizeOnline.getId() != null){
|
||||||
|
prizeIds.add(prizeOnline.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!hasNone){
|
||||||
|
throw new ServiceException("奖品必须包含谢谢惠顾");
|
||||||
|
}
|
||||||
|
List<PrizeOnline> dbList = this.selectPrizeOnlineList(gender);
|
||||||
|
List<Long> dbIds = dbList.stream().map(PrizeOnline::getId).collect(Collectors.toList());
|
||||||
|
for (PrizeOnline prizeOnline : bo) {
|
||||||
|
if(prizeOnline.getId() != null){
|
||||||
|
this.updateById(prizeOnline);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this.save(prizeOnline);
|
||||||
|
}
|
||||||
|
dbIds.removeAll(prizeIds);
|
||||||
|
this.removeByIds(dbIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PrizeOnline> prizeUp() {
|
||||||
|
Long userId = LoginHelper.getUserId();
|
||||||
|
MinUser minUser = userService.getMinUserById(userId);
|
||||||
|
GenderEnum genderEnum = GenderEnum.getByCode(minUser.getGender());
|
||||||
|
if(genderEnum == null || genderEnum == GenderEnum.NONE){
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
List<PrizeOnline> prizeOnlines = this.selectPrizeOnlineList(genderEnum.getCode());
|
||||||
|
return prizeOnlines;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.ruoyi.cai.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.ruoyi.cai.domain.PointChangeLog;
|
||||||
|
import com.ruoyi.cai.domain.PrizeOnline;
|
||||||
|
import com.ruoyi.cai.domain.PrizeWinningRecord;
|
||||||
|
import com.ruoyi.cai.domain.User;
|
||||||
|
import com.ruoyi.cai.mapper.PrizeWinningRecordMapper;
|
||||||
|
import com.ruoyi.cai.service.PrizeWinningRecordService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中奖记录Service业务层处理
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2026-01-08
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class PrizeWinningRecordServiceImpl extends ServiceImpl<PrizeWinningRecordMapper,PrizeWinningRecord> implements PrizeWinningRecordService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void winningRecord(PointChangeLog pointChangeLog, PrizeOnline prizeOnline, User user, Integer drawPoint) {
|
||||||
|
PrizeWinningRecord prizeWinningRecord = new PrizeWinningRecord();
|
||||||
|
prizeWinningRecord.setUserId(user.getId());
|
||||||
|
prizeWinningRecord.setUsePoint(drawPoint);
|
||||||
|
prizeWinningRecord.setPrizeId(prizeOnline.getPrizeId());
|
||||||
|
prizeWinningRecord.setPrizeName(prizeOnline.getPrizeName());
|
||||||
|
prizeWinningRecord.setPrizeDesc(prizeOnline.getPrizeDesc());
|
||||||
|
prizeWinningRecord.setPrizeImg(prizeOnline.getPrizeImg());
|
||||||
|
prizeWinningRecord.setWinProbability(prizeOnline.getWinProbability());
|
||||||
|
prizeWinningRecord.setGuaranteeDraws(prizeOnline.getGuaranteeDraws());
|
||||||
|
prizeWinningRecord.setMinWinDraws(prizeOnline.getMinWinDraws());
|
||||||
|
prizeWinningRecord.setStock(prizeOnline.getStock());
|
||||||
|
prizeWinningRecord.setPrizeType(prizeOnline.getPrizeType());
|
||||||
|
prizeWinningRecord.setPrizePrice(prizeOnline.getPrizePrice());
|
||||||
|
prizeWinningRecord.setAutoGive(prizeOnline.getAutoGive());
|
||||||
|
prizeWinningRecord.setGiveStatus(0);
|
||||||
|
this.save(prizeWinningRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ import com.ruoyi.cai.dto.commom.consumer.RechargeConsumerResp;
|
|||||||
import com.ruoyi.cai.enums.ConsumeLogType;
|
import com.ruoyi.cai.enums.ConsumeLogType;
|
||||||
import com.ruoyi.cai.enums.account.AccountChangeCodeEnum;
|
import com.ruoyi.cai.enums.account.AccountChangeCodeEnum;
|
||||||
import com.ruoyi.cai.enums.account.AccountTypeEnum;
|
import com.ruoyi.cai.enums.account.AccountTypeEnum;
|
||||||
|
import com.ruoyi.cai.lottery.PointManager;
|
||||||
import com.ruoyi.cai.manager.IdManager;
|
import com.ruoyi.cai.manager.IdManager;
|
||||||
import com.ruoyi.cai.mapper.AccountMapper;
|
import com.ruoyi.cai.mapper.AccountMapper;
|
||||||
import com.ruoyi.cai.mapper.RechargeOrderMapper;
|
import com.ruoyi.cai.mapper.RechargeOrderMapper;
|
||||||
@@ -55,6 +56,8 @@ public class RechargeOrderServiceImpl extends ServiceImpl<RechargeOrderMapper,Re
|
|||||||
private AccountMapper accountMapper;
|
private AccountMapper accountMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private AccountChangeLogService accountChangeLogService;
|
private AccountChangeLogService accountChangeLogService;
|
||||||
|
@Autowired
|
||||||
|
private PointManager pointManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RechargeOrder getByOrderNo(String orderNo){
|
public RechargeOrder getByOrderNo(String orderNo){
|
||||||
@@ -127,7 +130,7 @@ public class RechargeOrderServiceImpl extends ServiceImpl<RechargeOrderMapper,Re
|
|||||||
consumeLog.setType(ConsumeLogType.RECHARGE.getCode());
|
consumeLog.setType(ConsumeLogType.RECHARGE.getCode());
|
||||||
consumeLog.setAmount(rechargeOrder.getRechargeCoin());
|
consumeLog.setAmount(rechargeOrder.getRechargeCoin());
|
||||||
accountService.recharge(consumeLog);
|
accountService.recharge(consumeLog);
|
||||||
PointRecordLog pointRecordLog = accountService.rechargePoint(rechargeOrder, user);
|
PointRecordLog pointRecordLog = pointManager.rechargePoint(rechargeOrder, user); // 处理充值积分
|
||||||
RechargeConsumerResp resp = new RechargeConsumerResp();
|
RechargeConsumerResp resp = new RechargeConsumerResp();
|
||||||
resp.setSuccess(true);
|
resp.setSuccess(true);
|
||||||
resp.setConsumeLogId(consumeLog.getId());
|
resp.setConsumeLogId(consumeLog.getId());
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package com.ruoyi.cai.service.impl;
|
package com.ruoyi.cai.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.ruoyi.cai.domain.UserCodeGen;
|
import com.ruoyi.cai.domain.UserCodeGen;
|
||||||
import com.ruoyi.cai.mapper.UserCodeGenMapper;
|
import com.ruoyi.cai.mapper.UserCodeGenMapper;
|
||||||
import com.ruoyi.cai.service.UserCodeGenService;
|
import com.ruoyi.cai.service.UserCodeGenService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* idService业务层处理
|
* idService业务层处理
|
||||||
*
|
*
|
||||||
@@ -15,10 +18,49 @@ import org.springframework.stereotype.Service;
|
|||||||
@Service
|
@Service
|
||||||
public class UserCodeGenServiceImpl extends ServiceImpl<UserCodeGenMapper, UserCodeGen> implements UserCodeGenService {
|
public class UserCodeGenServiceImpl extends ServiceImpl<UserCodeGenMapper, UserCodeGen> implements UserCodeGenService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户号范围:1000 到 9999999 (4-7位数字)
|
||||||
|
*/
|
||||||
|
private static final long MIN_USER_CODE = 1000L;
|
||||||
|
private static final long MAX_USER_CODE = 9999999L;
|
||||||
|
private static final int MAX_RETRY_COUNT = 10;
|
||||||
|
|
||||||
|
private final Random random = new Random();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCodeGen(){
|
public String getCodeGen() {
|
||||||
|
// 使用数据库唯一索引保证不重复 + 随机生成
|
||||||
|
for (int i = 0; i < MAX_RETRY_COUNT; i++) {
|
||||||
|
// 生成随机用户号
|
||||||
|
long userCode = generateRandomUserCode();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 尝试保存,如果ID重复会抛出DuplicateKeyException
|
||||||
|
UserCodeGen gen = new UserCodeGen();
|
||||||
|
gen.setId(userCode);
|
||||||
|
this.save(gen);
|
||||||
|
return userCode + "";
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 捕获异常,说明ID重复,继续循环重试
|
||||||
|
// 记录日志(可选)
|
||||||
|
if (i == MAX_RETRY_COUNT - 1) {
|
||||||
|
// 最后一次重试失败,抛出异常
|
||||||
|
throw new RuntimeException("生成用户号失败:重试次数已达上限", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果随机生成多次都失败,回退到自增方式(兜底方案)
|
||||||
UserCodeGen gen = new UserCodeGen();
|
UserCodeGen gen = new UserCodeGen();
|
||||||
this.save(gen);
|
this.save(gen);
|
||||||
return gen.getId()+"";
|
return gen.getId() + "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成随机用户号(4-7位数字)
|
||||||
|
*/
|
||||||
|
private long generateRandomUserCode() {
|
||||||
|
// 生成 MIN_USER_CODE 到 MAX_USER_CODE 之间的随机数
|
||||||
|
return MIN_USER_CODE + (long) (random.nextDouble() * (MAX_USER_CODE - MIN_USER_CODE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ public class V14Manager {
|
|||||||
String customerCode = payTrdConfig.getMchId();
|
String customerCode = payTrdConfig.getMchId();
|
||||||
long payAmount = payOrderInfoDTO.getPriceFen(); // 支付金额,分为单位
|
long payAmount = payOrderInfoDTO.getPriceFen(); // 支付金额,分为单位
|
||||||
String payCurrency = "CNY"; // 币种,写死
|
String payCurrency = "CNY"; // 币种,写死
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), true);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, true);
|
||||||
String transactionStartTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); // 交易开始时间
|
String transactionStartTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); // 交易开始时间
|
||||||
// String transactionEndTime = ""; // 交易结束时间
|
// String transactionEndTime = ""; // 交易结束时间
|
||||||
WxJsOrderInfo orderInfo = new WxJsOrderInfo();
|
WxJsOrderInfo orderInfo = new WxJsOrderInfo();
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class PayTrdV10Service implements PayTrdService {
|
|||||||
params.put("pay_orderid", payOrderInfoDTO.getOrderNo());
|
params.put("pay_orderid", payOrderInfoDTO.getOrderNo());
|
||||||
params.put("pay_applydate", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
params.put("pay_applydate", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||||
params.put("pay_bankcode", payTrdConfig.getProductId(wx));
|
params.put("pay_bankcode", payTrdConfig.getProductId(wx));
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), wx);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, wx);
|
||||||
params.put("pay_notifyurl", notifyUrl);
|
params.put("pay_notifyurl", notifyUrl);
|
||||||
params.put("pay_amount", payOrderInfoDTO.getPriceYuanStr());
|
params.put("pay_amount", payOrderInfoDTO.getPriceYuanStr());
|
||||||
MultiValueMap<String, String> map = PayMd5Util.createParamsOfMap(params, payTrdConfig.getSign(), "pay_md5sign");
|
MultiValueMap<String, String> map = PayMd5Util.createParamsOfMap(params, payTrdConfig.getSign(), "pay_md5sign");
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class PayTrdV11Service implements PayTrdService {
|
|||||||
params.put("pay_orderid", payOrderInfoDTO.getOrderNo());
|
params.put("pay_orderid", payOrderInfoDTO.getOrderNo());
|
||||||
params.put("pay_applydate", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
params.put("pay_applydate", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||||
params.put("pay_bankcode", payTrdConfig.getProductId(wx));
|
params.put("pay_bankcode", payTrdConfig.getProductId(wx));
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), wx);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, wx);
|
||||||
params.put("pay_notifyurl", notifyUrl);
|
params.put("pay_notifyurl", notifyUrl);
|
||||||
params.put("pay_amount", payOrderInfoDTO.getPriceYuanStr());
|
params.put("pay_amount", payOrderInfoDTO.getPriceYuanStr());
|
||||||
MultiValueMap<String, String> map = PayMd5Util.createParamsOfMap(params, payTrdConfig.getSign(), "pay_md5sign");
|
MultiValueMap<String, String> map = PayMd5Util.createParamsOfMap(params, payTrdConfig.getSign(), "pay_md5sign");
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ public class PayTrdV12Service implements PayTrdService {
|
|||||||
}else {
|
}else {
|
||||||
bizRequest.setFuncCodeList(Collections.singletonList(FuncCodeEnum.FC02020004.getCode()));
|
bizRequest.setFuncCodeList(Collections.singletonList(FuncCodeEnum.FC02020004.getCode()));
|
||||||
}
|
}
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), wx);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, wx);
|
||||||
payerInfo.setFrontUrl(notifyUrl);
|
payerInfo.setFrontUrl(notifyUrl);
|
||||||
payerInfo.setPayExtra(payExtraList);
|
payerInfo.setPayExtra(payExtraList);
|
||||||
bizRequest.setPayerInfo(payerInfo);
|
bizRequest.setPayerInfo(payerInfo);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class PayTrdV13Service implements PayTrdService {
|
|||||||
params.put("type", "alipay");
|
params.put("type", "alipay");
|
||||||
}
|
}
|
||||||
params.put("out_trade_no", payOrderInfoDTO.getOrderNo());
|
params.put("out_trade_no", payOrderInfoDTO.getOrderNo());
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), wx);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, wx);
|
||||||
params.put("notify_url", notifyUrl);
|
params.put("notify_url", notifyUrl);
|
||||||
// params.put("return_url", notifyUrl);
|
// params.put("return_url", notifyUrl);
|
||||||
params.put("name", payOrderInfoDTO.getSubject());
|
params.put("name", payOrderInfoDTO.getSubject());
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.ruoyi.cai.trdpay.handle;
|
|||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.ruoyi.cai.domain.PayTrdConfig;
|
import com.ruoyi.cai.domain.PayTrdConfig;
|
||||||
|
import com.ruoyi.cai.pay.PayManager;
|
||||||
import com.ruoyi.cai.pay.PayOrderInfoDTO;
|
import com.ruoyi.cai.pay.PayOrderInfoDTO;
|
||||||
import com.ruoyi.cai.pay.PayReturnResp;
|
import com.ruoyi.cai.pay.PayReturnResp;
|
||||||
import com.ruoyi.cai.trdpay.PayTrdService;
|
import com.ruoyi.cai.trdpay.PayTrdService;
|
||||||
@@ -23,6 +24,8 @@ import java.util.Map;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class PayTrdV14Service implements PayTrdService {
|
public class PayTrdV14Service implements PayTrdService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PayManager payManager;
|
||||||
@Autowired
|
@Autowired
|
||||||
private V14Manager v14Manager;
|
private V14Manager v14Manager;
|
||||||
|
|
||||||
@@ -39,8 +42,8 @@ public class PayTrdV14Service implements PayTrdService {
|
|||||||
v14PayResp.setPrice(payOrderInfoDTO.getPrice());
|
v14PayResp.setPrice(payOrderInfoDTO.getPrice());
|
||||||
v14PayResp.setSubject(payOrderInfoDTO.getSubject());
|
v14PayResp.setSubject(payOrderInfoDTO.getSubject());
|
||||||
v14PayResp.setOrderNo(payOrderInfoDTO.getOrderNo());
|
v14PayResp.setOrderNo(payOrderInfoDTO.getOrderNo());
|
||||||
String notifyUrl = payTrdConfig.getNotifyUrl();
|
String notifyDomain = payManager.getNotifyDomain(payTrdConfig.getNotifyUrl());
|
||||||
String api = notifyUrl.replace("https://", "").replace("http://", "");
|
String api = notifyDomain.replace("https://", "").replace("http://", "");
|
||||||
v14PayResp.setApi(api);
|
v14PayResp.setApi(api);
|
||||||
return PayReturnResp.createEfps(v14PayResp);
|
return PayReturnResp.createEfps(v14PayResp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class PayTrdV15Service implements PayTrdService {
|
|||||||
}else{
|
}else{
|
||||||
params.put("pay_bankcode", payTrdConfig.getAliProductId());
|
params.put("pay_bankcode", payTrdConfig.getAliProductId());
|
||||||
}
|
}
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), wx);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, wx);
|
||||||
params.put("pay_notifyurl", notifyUrl);
|
params.put("pay_notifyurl", notifyUrl);
|
||||||
params.put("pay_callbackurl", notifyUrl);
|
params.put("pay_callbackurl", notifyUrl);
|
||||||
params.put("pay_amount", payOrderInfoDTO.getPriceYuanStr());
|
params.put("pay_amount", payOrderInfoDTO.getPriceYuanStr());
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class PayTrdV1Service implements PayTrdService {
|
|||||||
params.put("productId", payTrdConfig.getProductId(wx));
|
params.put("productId", payTrdConfig.getProductId(wx));
|
||||||
params.put("mchOrderNo", payOrderInfoDTO.getOrderNo());
|
params.put("mchOrderNo", payOrderInfoDTO.getOrderNo());
|
||||||
params.put("amount", payOrderInfoDTO.getPriceFenStr());
|
params.put("amount", payOrderInfoDTO.getPriceFenStr());
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), wx);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, wx);
|
||||||
params.put("notifyUrl", notifyUrl);
|
params.put("notifyUrl", notifyUrl);
|
||||||
String para = PayMd5Util.createParams(params, payTrdConfig.getSign());
|
String para = PayMd5Util.createParams(params, payTrdConfig.getSign());
|
||||||
String gatewayUrl = getGatewayUrl(payTrdConfig);
|
String gatewayUrl = getGatewayUrl(payTrdConfig);
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public class PayTrdV2Service implements PayTrdService {
|
|||||||
params.put("subject",payOrderInfoDTO.getSubject());
|
params.put("subject",payOrderInfoDTO.getSubject());
|
||||||
params.put("body",payOrderInfoDTO.getBody());
|
params.put("body",payOrderInfoDTO.getBody());
|
||||||
params.put("currency","cny");
|
params.put("currency","cny");
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), wx);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, wx);
|
||||||
params.put("notifyUrl", notifyUrl);
|
params.put("notifyUrl", notifyUrl);
|
||||||
String para = PayMd5Util.createParams(params, payTrdConfig.getSign());
|
String para = PayMd5Util.createParams(params, payTrdConfig.getSign());
|
||||||
String gatewayUrl = getGatewayUrl(payTrdConfig);
|
String gatewayUrl = getGatewayUrl(payTrdConfig);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class PayTrdV3Service implements PayTrdService {
|
|||||||
params.put("productId", payTrdConfig.getProductId(wx));
|
params.put("productId", payTrdConfig.getProductId(wx));
|
||||||
params.put("mchOrderNo", payOrderInfoDTO.getOrderNo());
|
params.put("mchOrderNo", payOrderInfoDTO.getOrderNo());
|
||||||
params.put("amount", payOrderInfoDTO.getPriceFenStr());
|
params.put("amount", payOrderInfoDTO.getPriceFenStr());
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), wx);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, wx);
|
||||||
params.put("notifyUrl", notifyUrl);
|
params.put("notifyUrl", notifyUrl);
|
||||||
String para = PayMd5Util.createParams(params, payTrdConfig.getSign());
|
String para = PayMd5Util.createParams(params, payTrdConfig.getSign());
|
||||||
String gatewayUrl = getGatewayUrl(payTrdConfig);
|
String gatewayUrl = getGatewayUrl(payTrdConfig);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class PayTrdV4Service implements PayTrdService {
|
|||||||
params.put("tradeType", payTrdConfig.getProductId(wx));
|
params.put("tradeType", payTrdConfig.getProductId(wx));
|
||||||
params.put("merchantPayNo", payOrderInfoDTO.getOrderNo());
|
params.put("merchantPayNo", payOrderInfoDTO.getOrderNo());
|
||||||
params.put("amt", payOrderInfoDTO.getPrice().toString());
|
params.put("amt", payOrderInfoDTO.getPrice().toString());
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), wx);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, wx);
|
||||||
params.put("notifyUrl", notifyUrl);
|
params.put("notifyUrl", notifyUrl);
|
||||||
params.put("goodsName",payOrderInfoDTO.getBody());
|
params.put("goodsName",payOrderInfoDTO.getBody());
|
||||||
String para = PayMd5Util.createParams(params, payTrdConfig.getSign());
|
String para = PayMd5Util.createParams(params, payTrdConfig.getSign());
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class PayTrdV5Service implements PayTrdService {
|
|||||||
params.put("pay_orderid", payOrderInfoDTO.getOrderNo());
|
params.put("pay_orderid", payOrderInfoDTO.getOrderNo());
|
||||||
params.put("pay_applydate", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
params.put("pay_applydate", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||||
params.put("pay_bankcode", payTrdConfig.getProductId(wx));
|
params.put("pay_bankcode", payTrdConfig.getProductId(wx));
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), wx);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, wx);
|
||||||
params.put("pay_notifyurl", notifyUrl);
|
params.put("pay_notifyurl", notifyUrl);
|
||||||
params.put("pay_amount", payOrderInfoDTO.getPriceYuanStr());
|
params.put("pay_amount", payOrderInfoDTO.getPriceYuanStr());
|
||||||
MultiValueMap<String, String> map = PayMd5Util.createParamsOfMap(params, payTrdConfig.getSign(), "pay_md5sign");
|
MultiValueMap<String, String> map = PayMd5Util.createParamsOfMap(params, payTrdConfig.getSign(), "pay_md5sign");
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class PayTrdV6Service implements PayTrdService {
|
|||||||
params.put("productId", payTrdConfig.getProductId(wx));
|
params.put("productId", payTrdConfig.getProductId(wx));
|
||||||
params.put("extra", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
params.put("extra", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||||
params.put("amount", payOrderInfoDTO.getPriceFenStr());
|
params.put("amount", payOrderInfoDTO.getPriceFenStr());
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), wx);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, wx);
|
||||||
params.put("notifyUrl", notifyUrl);
|
params.put("notifyUrl", notifyUrl);
|
||||||
params.put("subject",payOrderInfoDTO.getSubject());
|
params.put("subject",payOrderInfoDTO.getSubject());
|
||||||
params.put("body",payOrderInfoDTO.getBody());
|
params.put("body",payOrderInfoDTO.getBody());
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class PayTrdV7Service implements PayTrdService {
|
|||||||
params.put("channelType", payTrdConfig.getProductId(wx));
|
params.put("channelType", payTrdConfig.getProductId(wx));
|
||||||
params.put("merchantOrderNo", payOrderInfoDTO.getOrderNo());
|
params.put("merchantOrderNo", payOrderInfoDTO.getOrderNo());
|
||||||
params.put("amount", payOrderInfoDTO.getPriceYuanStr());
|
params.put("amount", payOrderInfoDTO.getPriceYuanStr());
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), wx);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, wx);
|
||||||
params.put("notifyUrl", notifyUrl);
|
params.put("notifyUrl", notifyUrl);
|
||||||
params.put("ip", ServletUtils.getClientIP());
|
params.put("ip", ServletUtils.getClientIP());
|
||||||
params.put("title", payOrderInfoDTO.getSubject());
|
params.put("title", payOrderInfoDTO.getSubject());
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public class PayTrdV8Service implements PayTrdService {
|
|||||||
params.put("device", "mobile");
|
params.put("device", "mobile");
|
||||||
params.put("type", "alipay");
|
params.put("type", "alipay");
|
||||||
params.put("out_trade_no", payOrderInfoDTO.getOrderNo());
|
params.put("out_trade_no", payOrderInfoDTO.getOrderNo());
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), wx);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, wx);
|
||||||
params.put("notify_url", notifyUrl);
|
params.put("notify_url", notifyUrl);
|
||||||
params.put("name", payOrderInfoDTO.getSubject());
|
params.put("name", payOrderInfoDTO.getSubject());
|
||||||
params.put("money", payOrderInfoDTO.getPriceYuanStr());
|
params.put("money", payOrderInfoDTO.getPriceYuanStr());
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class PayTrdV9Service implements PayTrdService {
|
|||||||
params.put("pay_orderid", payOrderInfoDTO.getOrderNo());
|
params.put("pay_orderid", payOrderInfoDTO.getOrderNo());
|
||||||
params.put("pay_applydate", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
params.put("pay_applydate", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||||
params.put("pay_bankcode", payTrdConfig.getProductId(wx));
|
params.put("pay_bankcode", payTrdConfig.getProductId(wx));
|
||||||
String notifyUrl = type.getNotifyUrl(payTrdConfig.getNotifyUrl(), wx);
|
String notifyUrl = payManager.getNotifyUrl(payTrdConfig, type, wx);
|
||||||
params.put("pay_notifyurl", notifyUrl);
|
params.put("pay_notifyurl", notifyUrl);
|
||||||
params.put("pay_amount", payOrderInfoDTO.getPriceYuanStr());
|
params.put("pay_amount", payOrderInfoDTO.getPriceYuanStr());
|
||||||
MultiValueMap<String, String> map = PayMd5Util.createParamsOfMap(params, payTrdConfig.getSign(), "pay_md5sign");
|
MultiValueMap<String, String> map = PayMd5Util.createParamsOfMap(params, payTrdConfig.getSign(), "pay_md5sign");
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import java.util.stream.Collectors;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class LoginLogByFileUtil {
|
public class LoginLogByFileUtil {
|
||||||
private static final String LOG_FILE_PATH = "/home/server/api/logs/sys-console.log";
|
private static final String LOG_FILE_PATH = "/home/server/api/logs/sys-console.log";
|
||||||
private static final int COMMAND_TIMEOUT_MS = 5000;
|
private static final int COMMAND_TIMEOUT_MS = 9000;
|
||||||
private static final Charset LOG_FILE_CHARSET = StandardCharsets.UTF_8; // 确认日志为UTF-8编码
|
private static final Charset LOG_FILE_CHARSET = StandardCharsets.UTF_8; // 确认日志为UTF-8编码
|
||||||
private static final int MAX_LOG_LINES = 10;
|
private static final int MAX_LOG_LINES = 10;
|
||||||
|
|
||||||
|
|||||||
@@ -12,4 +12,5 @@ public class RedisConstant {
|
|||||||
public static final String INIT_ROOM_LOCK = REDIS_P + "lock:initRoom:%s-%s";
|
public static final String INIT_ROOM_LOCK = REDIS_P + "lock:initRoom:%s-%s";
|
||||||
public static final String Y4X_REDIS_CACHE = REDIS_P + "shareUrl:y4x:%s";
|
public static final String Y4X_REDIS_CACHE = REDIS_P + "shareUrl:y4x:%s";
|
||||||
public static final String START_SEND_MESSAGE_CACHE = REDIS_P + "starSendMessage:%s";
|
public static final String START_SEND_MESSAGE_CACHE = REDIS_P + "starSendMessage:%s";
|
||||||
|
public static final String POINT_DAYS_USER = REDIS_P + "pointDaysUser:%s:%s";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ruoyi.cai.mapper.PrizeInfoMapper">
|
||||||
|
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ruoyi.cai.mapper.PrizeOnlineMapper">
|
||||||
|
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ruoyi.cai.mapper.PrizeWinningRecordMapper">
|
||||||
|
|
||||||
|
<select id="pageAdmin" resultType="com.ruoyi.cai.dto.admin.vo.winningRecord.PrizeWinningRecordAdminVO">
|
||||||
|
select t2.usercode, t2.mobile, t2.nickname, t1.*
|
||||||
|
from cai_prize_winning_record t1
|
||||||
|
left join cai_user t2 on t1.user_id = t2.id
|
||||||
|
<where>
|
||||||
|
<if test="query.usercode != null and query.usercode != ''">
|
||||||
|
and t2.usercode = #{query.usercode}
|
||||||
|
</if>
|
||||||
|
<if test="query.mobile != null and query.mobile != ''">
|
||||||
|
and t2.mobile = #{query.mobile}
|
||||||
|
</if>
|
||||||
|
<if test="query.prizeName != null and query.prizeName != ''">
|
||||||
|
and t1.prize_name like concat('%',#{query.prizeName},'%')
|
||||||
|
</if>
|
||||||
|
<if test="query.autoGive != null">
|
||||||
|
and t1.auto_give = #{query.autoGive}
|
||||||
|
</if>
|
||||||
|
<if test="query.giveStatus != null">
|
||||||
|
and t1.give_status = #{query.giveStatus}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
order by t1.create_time desc
|
||||||
|
</select>
|
||||||
|
</mapper>
|
||||||
Reference in New Issue
Block a user