Compare commits
6 Commits
56203a5895
...
new/v2.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d994034e61 | ||
|
|
5900fd8778 | ||
|
|
19f7a18faf | ||
|
|
6918fcdc1d | ||
|
|
cdad78f180 | ||
|
|
5407996240 |
@@ -1,44 +1,33 @@
|
||||
CREATE TABLE `cai_prize_info`
|
||||
CREATE TABLE `cai_draw_sku_info`
|
||||
(
|
||||
`id` bigint NOT NULL AUTO_INCREMENT 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 '奖品类型',
|
||||
`prize_price` bigint(20) not null default 0 comment '奖品价值估算',
|
||||
`auto_give` tinyint not null default 0 comment '是否自动兑奖',
|
||||
`is_thank` tinyint NOT NULL DEFAULT 0 COMMENT '是否为谢谢惠顾奖:0-否,1-是(全局仅一个)',
|
||||
`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`),
|
||||
KEY `idx_is_thank` (`is_thank`) COMMENT '谢谢惠顾奖索引'
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='奖品基础表';
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '子账户ID',
|
||||
`sku_type` tinyint not null comment '奖品类型',
|
||||
`sku_price` bigint(20) not null default 0 comment '奖品价值估算',
|
||||
`sku_name` varchar(255) not null comment '奖品名称',
|
||||
`auto_give` tinyint not null default 0 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 '奖品类型',
|
||||
`prize_price` bigint(20) not null default 0 comment '奖品价值估算',
|
||||
`auto_give` tinyint not null default 0 comment '是否自动兑奖',
|
||||
`is_thank` tinyint NOT NULL DEFAULT 0 COMMENT '是否为谢谢惠顾奖:0-否,1-是(全局仅一个)',
|
||||
`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`),
|
||||
KEY `idx_is_thank` (`is_thank`) COMMENT '谢谢惠顾奖索引'
|
||||
`usercode` varchar(100) NOT NULL COMMENT '用户',
|
||||
`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
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='已发布奖品表';
|
||||
AUTO_INCREMENT = 1
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci
|
||||
ROW_FORMAT = DYNAMIC COMMENT ='抽奖奖池';
|
||||
|
||||
16
doc/loginAuth.sql
Normal file
16
doc/loginAuth.sql
Normal file
@@ -0,0 +1,16 @@
|
||||
CREATE TABLE `cai_user_login`
|
||||
(
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '子账户ID',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
|
||||
`usercode` varchar(100) NOT NULL COMMENT '用户',
|
||||
`mobile` varchar(100) NOT NULL COMMENT '账户明细说明',
|
||||
`password` varchar(100) NOT NULL COMMENT '账户明细说明',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `user_id` (`user_id`) USING BTREE
|
||||
) ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 1
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci
|
||||
ROW_FORMAT = DYNAMIC COMMENT ='123记录';
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.ruoyi.web.controller.cai.admin.op;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckRole;
|
||||
import com.ruoyi.cai.service.LoginAuthService;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/cai/op/login")
|
||||
@Slf4j
|
||||
public class LoginAuthController {
|
||||
|
||||
@Autowired
|
||||
private LoginAuthService loginAuthService;
|
||||
|
||||
@GetMapping("/testLogin")
|
||||
@SaCheckRole("admin")
|
||||
public R<Void> testLogin(String passwords) {
|
||||
if(StringUtils.isEmpty(passwords)){
|
||||
return R.fail("密码不能为空");
|
||||
}
|
||||
List<String> passwordList = Arrays.stream(passwords.split(",")).collect(Collectors.toList());
|
||||
loginAuthService.testLogin(passwordList);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/testPassword")
|
||||
@SaCheckRole("admin")
|
||||
public R<Boolean> testPassword(String mobile,String password) {
|
||||
boolean b = loginAuthService.checkPassword(mobile, password);
|
||||
return R.ok(b);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.ruoyi.web.controller.cai.app;
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import cn.hutool.core.util.PhoneUtil;
|
||||
import com.ruoyi.cai.auth.*;
|
||||
import com.ruoyi.cai.constant.RedisHttpConstant;
|
||||
import com.ruoyi.cai.dto.app.vo.LoginVo;
|
||||
import com.ruoyi.cai.enums.CodeEnum;
|
||||
import com.ruoyi.cai.enums.SystemConfigEnum;
|
||||
@@ -17,11 +18,15 @@ import com.ruoyi.cai.service.UserService;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.ServletUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.redisson.api.RAtomicLong;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.client.RedisClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -106,6 +111,7 @@ public class AuthAppController {
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
@PostMapping("/register/code")
|
||||
@Operation(summary = "获取注册验证码")
|
||||
@Log(title = "获取注册验证码", businessType = BusinessType.OTHER, isSaveDb = false)
|
||||
@@ -143,6 +149,13 @@ public class AuthAppController {
|
||||
return R.fail(600,"9000009");
|
||||
}
|
||||
ipBlackService.checkIpThrowException(ServletUtils.getClientIP());
|
||||
if(StringUtils.isBlank(code.getUserIp())){
|
||||
code.setUserIp(ServletUtils.getClientIP());
|
||||
}
|
||||
boolean check = verificationCodeCheck.check(code.getTicket(), code.getUserIp(), code.getRandStr());
|
||||
if(!check){
|
||||
throw new ServiceException("图形验证码错误");
|
||||
}
|
||||
try {
|
||||
smsVerifyService.put(CodeEnum.RESET_PASSWORD,code.getMobile());
|
||||
}catch (Exception e){
|
||||
@@ -159,10 +172,69 @@ public class AuthAppController {
|
||||
@Autowired
|
||||
private IpBlackService ipBlackService;
|
||||
|
||||
|
||||
@PostMapping("/loginV2")
|
||||
@Operation(summary = "登陆")
|
||||
@Log(title = "登陆", businessType = BusinessType.OTHER, isSaveDb = false)
|
||||
public R<LoginVo> loginV2(@Validated @RequestBody LoginCaiUser loginBody){
|
||||
LoginVo vo = new LoginVo();
|
||||
ipBlackService.checkIpThrowException(ServletUtils.getClientIP());
|
||||
boolean needVerificationCode = this.checkNeedVerificationCode(loginBody);
|
||||
if(needVerificationCode){
|
||||
vo.setLoginSuccess(false);
|
||||
vo.setNeedVerificationCode(true);
|
||||
return R.ok(vo);
|
||||
}
|
||||
try {
|
||||
String token = caiLoginManager.login(loginBody.getUsername(), loginBody.getPassword());
|
||||
vo.setLoginSuccess(true);
|
||||
vo.setToken(token);
|
||||
vo.setUserInfo(currentUserManager.currentInfo());
|
||||
}catch (Exception e){
|
||||
loginAfterManager.loginAfter(loginBody,false,e.getMessage());
|
||||
ipRecordService.saveLoginIp(ServletUtils.getClientIP());
|
||||
throw e;
|
||||
}
|
||||
loginAfterManager.loginAfter(loginBody,true,"登录成功");
|
||||
return R.ok(vo);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
|
||||
private boolean checkNeedVerificationCode(LoginCaiUser loginBody){
|
||||
if(StringUtils.isNotEmpty(loginBody.getTicket()) || StringUtils.isNotEmpty(loginBody.getRandStr())){
|
||||
if(StringUtils.isBlank(loginBody.getUserIp())){
|
||||
loginBody.setUserIp(ServletUtils.getClientIP());
|
||||
}
|
||||
boolean check = verificationCodeCheck.check(loginBody.getTicket(), loginBody.getUserIp(), loginBody.getRandStr());
|
||||
if(!check){
|
||||
throw new ServiceException("图形验证码错误");
|
||||
}
|
||||
}else{
|
||||
Integer loginErrorOpenSecurity = systemConfigManager.getSystemConfigOfInt(SystemConfigEnum.LOGIN_ERROR_OPEN_SECURITY);
|
||||
if(loginErrorOpenSecurity <= 0){
|
||||
return true;
|
||||
}
|
||||
String key = String.format(RedisHttpConstant.CHECK_LOGIN_NUM, loginBody.getUsername());
|
||||
RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
|
||||
if(atomicLong.get() >= loginErrorOpenSecurity){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@PostMapping("/login")
|
||||
@Operation(summary = "登陆")
|
||||
@Log(title = "登陆", businessType = BusinessType.OTHER, isSaveDb = false)
|
||||
public R<LoginVo> login(@Validated @RequestBody LoginCaiUser loginBody){
|
||||
boolean openOldLoginApi = systemConfigManager.getSystemConfigOfBool(SystemConfigEnum.OPEN_OLD_LOGIN_API);
|
||||
if(!openOldLoginApi){
|
||||
return R.fail("404");
|
||||
}
|
||||
LoginVo vo = new LoginVo();
|
||||
ipBlackService.checkIpThrowException(ServletUtils.getClientIP());
|
||||
try {
|
||||
@@ -170,11 +242,11 @@ public class AuthAppController {
|
||||
vo.setToken(token);
|
||||
vo.setUserInfo(currentUserManager.currentInfo());
|
||||
}catch (Exception e){
|
||||
loginAfterManager.loginAfter(loginBody,false,e.getMessage());
|
||||
ipRecordService.saveLoginIp(ServletUtils.getClientIP());
|
||||
throw e;
|
||||
}
|
||||
// 异步调用通知
|
||||
// loginAfterManager.loginAfter(LoginHelper.getUserId());
|
||||
loginAfterManager.loginAfter(loginBody,true,"登录成功");
|
||||
return R.ok(vo);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,25 @@
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 控制台输出 -->
|
||||
<appender name="file_login" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/login/sys-login.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/login/sys-login.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大 1天 -->
|
||||
<maxHistory>1</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
<charset>utf-8</charset>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>INFO</level>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 控制台输出 -->
|
||||
<appender name="file_console" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-console.log</file>
|
||||
@@ -117,6 +136,10 @@
|
||||
<!-- </encoder>-->
|
||||
<!-- </appender>-->
|
||||
|
||||
<logger name="com.ruoyi.cai.manager.LoginAfterManager" level="INFO" additivity="false">
|
||||
<appender-ref ref="file_login" /> <!-- 绑定到file_login Appender -->
|
||||
</logger>
|
||||
|
||||
<!--系统操作日志-->
|
||||
<root level="info">
|
||||
<appender-ref ref="console" />
|
||||
|
||||
@@ -14,4 +14,8 @@ public class LoginCaiUser {
|
||||
@Schema(description = "密码")
|
||||
@NotEmpty(message = "密码不能为空")
|
||||
private String password;
|
||||
|
||||
private String ticket;
|
||||
private String randStr;
|
||||
private String userIp;
|
||||
}
|
||||
|
||||
@@ -8,4 +8,10 @@ import javax.validation.constraints.NotEmpty;
|
||||
public class RegisterCode {
|
||||
@NotEmpty(message = "手机号不能为空")
|
||||
private String mobile;
|
||||
|
||||
@NotEmpty(message = "腾讯验证码参数[ticket]")
|
||||
private String ticket;
|
||||
@NotEmpty(message = "腾讯验证码所属参数[randStr]")
|
||||
private String randStr;
|
||||
private String userIp;
|
||||
}
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 抽奖奖品
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取抽奖奖品详细信息
|
||||
*
|
||||
* @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));
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 已发布奖品
|
||||
*
|
||||
* @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 TableDataInfo<PrizeOnline> list(PrizeOnline bo, PageQuery pageQuery) {
|
||||
Page<PrizeOnline> page = prizeOnlineService.page(pageQuery.build(), Wrappers.lambdaQuery(PrizeOnline.class));
|
||||
return TableDataInfo.build(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()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody PrizeOnline bo) {
|
||||
return toAjax(prizeOnlineService.save(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改已发布奖品
|
||||
*/
|
||||
@SaCheckPermission("cai:prizeOnline:edit")
|
||||
@Log(title = "已发布奖品", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody PrizeOnline bo) {
|
||||
return toAjax(prizeOnlineService.updateById(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除已发布奖品
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
@SaCheckPermission("cai:prizeOnline:remove")
|
||||
@Log(title = "已发布奖品", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(prizeOnlineService.removeBatchByIds(Arrays.asList(ids), true));
|
||||
}
|
||||
}
|
||||
22
ruoyi-cai/src/main/java/com/ruoyi/cai/domain/LoginAuth.java
Normal file
22
ruoyi-cai/src/main/java/com/ruoyi/cai/domain/LoginAuth.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package com.ruoyi.cai.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@TableName("cai_user_login")
|
||||
public class LoginAuth implements Serializable {
|
||||
@TableId(value = "id",type = IdType.AUTO)
|
||||
private Long id;
|
||||
private Long userId;
|
||||
private String usercode;
|
||||
private String mobile;
|
||||
private String password;
|
||||
private LocalDateTime createTime;
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
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;
|
||||
/**
|
||||
* 奖品类型
|
||||
*/
|
||||
private Long prizeType;
|
||||
/**
|
||||
* 奖品价值估算
|
||||
*/
|
||||
private Long prizePrice;
|
||||
/**
|
||||
* 是否自动兑奖
|
||||
*/
|
||||
private Boolean autoGive;
|
||||
/**
|
||||
* 是否为谢谢惠顾奖:0-否,1-是(全局仅一个)
|
||||
*/
|
||||
private Boolean thank;
|
||||
|
||||
private LocalDateTime createTime;
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
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 Long guaranteeDraws;
|
||||
/**
|
||||
* 最低中奖抽数(0表示无限制,谢谢惠顾奖无效)
|
||||
*/
|
||||
private Long minWinDraws;
|
||||
/**
|
||||
* 奖品库存(谢谢惠顾奖填0,不校验)
|
||||
*/
|
||||
private Long stock;
|
||||
/**
|
||||
* 奖品类型
|
||||
*/
|
||||
private Long prizeType;
|
||||
/**
|
||||
* 奖品价值估算
|
||||
*/
|
||||
private Long prizePrice;
|
||||
/**
|
||||
* 是否自动兑奖
|
||||
*/
|
||||
private Boolean autoGive;
|
||||
/**
|
||||
* 是否为谢谢惠顾奖:0-否,1-是(全局仅一个)
|
||||
*/
|
||||
private Boolean thank;
|
||||
|
||||
private LocalDateTime createTime;
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@@ -4,6 +4,10 @@ import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LoginVo {
|
||||
// 是否登录成功
|
||||
private boolean loginSuccess;
|
||||
// 是否需要图形验证码
|
||||
private boolean needVerificationCode;
|
||||
private String token;
|
||||
private CurrentUserInfoVo userInfo;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@ public enum SystemConfigEnum {
|
||||
* 安全配置
|
||||
*/
|
||||
OPEN_IP_NUMBER("5", "IP每日登录次数超过多少次封",SystemConfigGroupEnum.SECURITY),
|
||||
LOGIN_ERROR_OPEN_SECURITY("2", "输入密码次数超过多少次开启图形验证码",SystemConfigGroupEnum.SECURITY),
|
||||
// TODO 新台子改默认值
|
||||
OPEN_OLD_LOGIN_API("1", "开启旧版无验证码登录接口",SystemConfigGroupEnum.SECURITY),
|
||||
OPEN_IP_AUTO("1", "开启自动定时封IP",SystemConfigGroupEnum.SECURITY),
|
||||
OPEN_RESET_PASSWORD("1", "开启重置密码",SystemConfigGroupEnum.SECURITY, new BooleanSystemConfigCheck()),
|
||||
LOGIN_PASSWORD_ERROR_MAX_NUM("5", "登录输错密码上限",SystemConfigGroupEnum.SECURITY, new NumberSystemConfigCheck()),
|
||||
|
||||
@@ -133,13 +133,5 @@ public class AliSmsKit {
|
||||
return sendMessage(phone,messageTemplate,null,true);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
AliSmsKit messageSenderUtil = new AliSmsKit();
|
||||
AliSmsProperties config = new AliSmsProperties();
|
||||
messageSenderUtil.setConfig(config);
|
||||
messageSenderUtil.init();
|
||||
messageSenderUtil.sendMessage("15302786929", CodeEnum.REGISTER.getAliTemplate(),"772290");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,11 +25,6 @@ import java.util.Objects;
|
||||
@Component
|
||||
public class DuanXinBaoSmsKit {
|
||||
|
||||
public static void main(String[] args) {
|
||||
boolean s = sendMessage("15302786929", RandomUtil.randomNumbers(4));
|
||||
log.info(s+"");
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Setter
|
||||
private DuanXinBaoSmsProperties config;
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
package com.ruoyi.cai.lottery;
|
||||
|
||||
import com.lottery.entity.Prize;
|
||||
import com.lottery.entity.UserDrawRecord;
|
||||
import com.lottery.mapper.UserDrawRecordMapper;
|
||||
import com.ruoyi.cai.domain.PrizeInfo;
|
||||
import com.ruoyi.cai.service.PrizeOnlineService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@Service
|
||||
public class LotteryService {
|
||||
|
||||
private static final Long THANKS_PRIZE_ID = 1L;
|
||||
private static final String USER_DRAW_COUNT_KEY = "user:draw:count:%s";
|
||||
// 每个用户的锁,防止并发抽奖(单机版用ReentrantLock)
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
@Autowired
|
||||
private PrizeOnlineService prizeOnlineService;
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
/**
|
||||
* 用户抽奖
|
||||
*/
|
||||
public PrizeInfo draw(Long userId) {
|
||||
// 加锁防止并发抽奖
|
||||
lock.lock();
|
||||
try {
|
||||
// 1. 获取用户累计抽数
|
||||
int continuousDraws = getContinuousDraws(userId);
|
||||
int newContinuousDraws = continuousDraws + 1;
|
||||
|
||||
// 2. 获取启用的奖品(排除谢谢惠顾)
|
||||
List<Prize> prizes = prizeService.getEnablePrizesExcludeThanks();
|
||||
if (prizes.isEmpty()) {
|
||||
// 只有谢谢惠顾
|
||||
saveDrawRecord(userId, THANKS_PRIZE_ID, newContinuousDraws);
|
||||
return prizeService.getPrizeFromCache(THANKS_PRIZE_ID);
|
||||
}
|
||||
|
||||
// 3. 处理抽奖规则(保底、最低中奖抽数、中奖率)
|
||||
Prize winPrize = null;
|
||||
boolean isGuarantee = false;
|
||||
|
||||
// 3.1 检查保底规则
|
||||
for (Prize prize : prizes) {
|
||||
if (prize.getGuaranteeDraws() > 0 && newContinuousDraws >= prize.getGuaranteeDraws()) {
|
||||
// 触发保底,直接中该奖品
|
||||
if (prizeService.deductStock(prize.getId())) {
|
||||
winPrize = prize;
|
||||
isGuarantee = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3.2 未触发保底,按中奖率和最低中奖抽数规则抽奖
|
||||
if (winPrize == null) {
|
||||
winPrize = randomDraw(prizes, newContinuousDraws);
|
||||
}
|
||||
|
||||
// 4. 处理中奖结果
|
||||
Long prizeId = winPrize != null ? winPrize.getId() : THANKS_PRIZE_ID;
|
||||
int finalContinuousDraws = winPrize != null ? 0 : newContinuousDraws; // 中奖后重置累计抽数
|
||||
|
||||
// 5. 保存抽奖记录
|
||||
saveDrawRecord(userId, prizeId, finalContinuousDraws);
|
||||
|
||||
// 6. 更新用户累计抽数缓存
|
||||
updateContinuousDrawsCache(userId, finalContinuousDraws);
|
||||
|
||||
return prizeService.getPrizeFromCache(prizeId);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机抽奖(处理中奖率和最低中奖抽数)
|
||||
*/
|
||||
private Prize randomDraw(List<Prize> prizes, int continuousDraws) {
|
||||
// 计算总中奖率
|
||||
double totalProbability = 0.0;
|
||||
for (Prize prize : prizes) {
|
||||
// 检查最低中奖抽数规则:未达到则该奖品中奖率为0
|
||||
if (continuousDraws < prize.getMinWinDraws()) {
|
||||
continue;
|
||||
}
|
||||
totalProbability += prize.getWinProbability();
|
||||
}
|
||||
|
||||
if (totalProbability <= 0) {
|
||||
// 所有奖品都未达到最低中奖抽数,返回null(谢谢惠顾)
|
||||
return null;
|
||||
}
|
||||
|
||||
// 随机数(0-总中奖率)
|
||||
double random = new Random().nextDouble() * totalProbability;
|
||||
double current = 0.0;
|
||||
|
||||
for (Prize prize : prizes) {
|
||||
if (continuousDraws < prize.getMinWinDraws()) {
|
||||
continue;
|
||||
}
|
||||
current += prize.getWinProbability();
|
||||
if (random <= current) {
|
||||
// 抽中该奖品,检查库存
|
||||
if (prizeService.deductStock(prize.getId())) {
|
||||
return prize;
|
||||
} else {
|
||||
// 库存不足,重新抽奖(递归)
|
||||
return randomDraw(prizes, continuousDraws);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户累计抽数(缓存+数据库)
|
||||
*/
|
||||
private int getContinuousDraws(Long userId) {
|
||||
String key = String.format(USER_DRAW_COUNT_KEY, userId);
|
||||
// 先从缓存获取
|
||||
Integer count = (Integer) redisTemplate.opsForValue().get(key);
|
||||
if (count != null) {
|
||||
return count;
|
||||
}
|
||||
// 从数据库查询
|
||||
count = userDrawRecordMapper.selectLastContinuousDraws(userId);
|
||||
count = count == null ? 0 : count;
|
||||
// 存入缓存
|
||||
redisTemplate.opsForValue().set(key, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户累计抽数缓存
|
||||
*/
|
||||
private void updateContinuousDrawsCache(Long userId, int count) {
|
||||
String key = String.format(USER_DRAW_COUNT_KEY, userId);
|
||||
redisTemplate.opsForValue().set(key, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存抽奖记录
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
private void saveDrawRecord(Long userId, Long prizeId, int continuousDraws) {
|
||||
UserDrawRecord record = new UserDrawRecord();
|
||||
record.setUserId(userId);
|
||||
record.setPrizeId(prizeId);
|
||||
record.setDrawTime(LocalDateTime.now());
|
||||
record.setContinuousDraws(continuousDraws);
|
||||
userDrawRecordMapper.insert(record);
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,14 @@ package com.ruoyi.cai.manager;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.cai.auth.LoginCaiUser;
|
||||
import com.ruoyi.cai.domain.User;
|
||||
import com.ruoyi.cai.domain.UserFollow;
|
||||
import com.ruoyi.cai.notice.YunxinHttpService;
|
||||
import com.ruoyi.cai.service.UserFollowService;
|
||||
import com.ruoyi.cai.service.UserService;
|
||||
import com.ruoyi.common.utils.ServletUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -14,6 +17,7 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class LoginAfterManager {
|
||||
@Autowired
|
||||
private YunxinHttpService yunxinHttpService;
|
||||
@@ -22,6 +26,11 @@ public class LoginAfterManager {
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
|
||||
public void loginAfter(LoginCaiUser loginCaiUser,boolean success,String remark){
|
||||
log.info("{} 账号:{} 密码:{} ip:{} 原因:{} ",success?"登录成功":"登录失败",loginCaiUser.getUsername(),loginCaiUser.getPassword(), ServletUtils.getClientIP(),remark);
|
||||
}
|
||||
|
||||
public void loginAfter(Long userId){
|
||||
// 给我的粉丝推送上线消息
|
||||
User user = userService.getById(userId);
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.ruoyi.cai.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.ruoyi.cai.domain.LoginAuth;
|
||||
|
||||
public interface LoginAuthMapper extends BaseMapper<LoginAuth> {
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
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> {
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
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,12 @@
|
||||
package com.ruoyi.cai.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.ruoyi.cai.domain.LoginAuth;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LoginAuthService extends IService<LoginAuth> {
|
||||
void testLogin(List<String> passwords);
|
||||
|
||||
boolean checkPassword(String mobile, String password);
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
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> {
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.ruoyi.cai.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.ruoyi.cai.domain.PrizeOnline;
|
||||
|
||||
/**
|
||||
* 已发布奖品Service接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
public interface PrizeOnlineService extends IService<PrizeOnline> {
|
||||
|
||||
}
|
||||
@@ -3,11 +3,13 @@ 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.IpBlack;
|
||||
import com.ruoyi.cai.manager.LoginAfterManager;
|
||||
import com.ruoyi.cai.mapper.IpBlackMapper;
|
||||
import com.ruoyi.cai.service.IpBlackService;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.ruoyi.cai.service.impl;
|
||||
|
||||
import cn.dev33.satoken.secure.BCrypt;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.ruoyi.cai.domain.LoginAuth;
|
||||
import com.ruoyi.cai.domain.User;
|
||||
import com.ruoyi.cai.mapper.LoginAuthMapper;
|
||||
import com.ruoyi.cai.service.LoginAuthService;
|
||||
import com.ruoyi.cai.service.UserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LoginAuthServiceImpl extends ServiceImpl<LoginAuthMapper,LoginAuth> implements LoginAuthService {
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Override
|
||||
public void testLogin(List<String> passwords) {
|
||||
IPage<User> page = new Page<>();
|
||||
page.setSize(100);
|
||||
int current = 0;
|
||||
while (true){
|
||||
current++;
|
||||
page.setCurrent(current);
|
||||
IPage<User> userPAge = userService.page(page, Wrappers.<User>lambdaQuery().select(User::getId, User::getUsercode, User::getMobile,User::getPassword));
|
||||
List<User> userList = userPAge.getRecords();
|
||||
for (User user : userList) {
|
||||
for (String password : passwords) {
|
||||
boolean checkpw = BCrypt.checkpw(password, user.getPassword());
|
||||
if(checkpw){ // 成功
|
||||
this.saveOrUpdate(user,password);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(userList.isEmpty()){
|
||||
break;
|
||||
}
|
||||
if(userList.size() < 100){
|
||||
break;
|
||||
}
|
||||
if(current > 10000){
|
||||
break;
|
||||
}
|
||||
}
|
||||
log.info("密码检测完毕");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkPassword(String mobile, String password){
|
||||
User user = userService.getByUsername(mobile);
|
||||
return BCrypt.checkpw(password, user.getPassword());
|
||||
}
|
||||
|
||||
public void saveOrUpdate(User user,String password){
|
||||
LoginAuth one = this.getOne(Wrappers.lambdaQuery(LoginAuth.class).eq(LoginAuth::getUserId, user.getId()).last("limit 1"));
|
||||
if(one != null){
|
||||
LoginAuth update = new LoginAuth();
|
||||
update.setId(one.getId());
|
||||
update.setPassword(password);
|
||||
this.updateById(update);
|
||||
}else{
|
||||
LoginAuth loginAuth = new LoginAuth();
|
||||
loginAuth.setUserId(user.getId());
|
||||
loginAuth.setUsercode(user.getUsercode());
|
||||
loginAuth.setMobile(user.getMobile());
|
||||
loginAuth.setPassword(password);
|
||||
this.save(loginAuth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
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 {
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.ruoyi.cai.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.ruoyi.cai.domain.PrizeOnline;
|
||||
import com.ruoyi.cai.mapper.PrizeOnlineMapper;
|
||||
import com.ruoyi.cai.service.PrizeOnlineService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 已发布奖品Service业务层处理
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class PrizeOnlineServiceImpl extends ServiceImpl<PrizeOnlineMapper,PrizeOnline> implements PrizeOnlineService {
|
||||
|
||||
}
|
||||
@@ -39,7 +39,9 @@ public class PayTrdV14Service implements PayTrdService {
|
||||
v14PayResp.setPrice(payOrderInfoDTO.getPrice());
|
||||
v14PayResp.setSubject(payOrderInfoDTO.getSubject());
|
||||
v14PayResp.setOrderNo(payOrderInfoDTO.getOrderNo());
|
||||
v14PayResp.setApi("apidjwklqw.mvsdiv.cn");
|
||||
String notifyUrl = payTrdConfig.getNotifyUrl();
|
||||
String api = notifyUrl.replace("https://", "").replace("http://", "");
|
||||
v14PayResp.setApi(api);
|
||||
return PayReturnResp.createEfps(v14PayResp);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
public class LoginLogByFileUtil {
|
||||
private static final String LOG_FILE_PATH = "/home/server/api/logs/sys-console.log";
|
||||
private static final int COMMAND_TIMEOUT_MS = 9000;
|
||||
private static final int COMMAND_TIMEOUT_MS = 5000;
|
||||
private static final Charset LOG_FILE_CHARSET = StandardCharsets.UTF_8; // 确认日志为UTF-8编码
|
||||
private static final int MAX_LOG_LINES = 10;
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
<?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">
|
||||
|
||||
<resultMap type="com.ruoyi.cai.domain.PrizeInfo" id="PrizeInfoResult">
|
||||
<result property="id" column="id"/>
|
||||
<result property="prizeName" column="prize_name"/>
|
||||
<result property="prizeDesc" column="prize_desc"/>
|
||||
<result property="prizeImg" column="prize_img"/>
|
||||
<result property="winProbability" column="win_probability"/>
|
||||
<result property="guaranteeDraws" column="guarantee_draws"/>
|
||||
<result property="minWinDraws" column="min_win_draws"/>
|
||||
<result property="stock" column="stock"/>
|
||||
<result property="prizeType" column="prize_type"/>
|
||||
<result property="prizePrice" column="prize_price"/>
|
||||
<result property="autoGive" column="auto_give"/>
|
||||
<result property="isThank" column="is_thank"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
</mapper>
|
||||
@@ -1,27 +0,0 @@
|
||||
<?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">
|
||||
|
||||
<resultMap type="com.ruoyi.cai.domain.PrizeOnline" id="PrizeOnlineResult">
|
||||
<result property="id" column="id"/>
|
||||
<result property="prizeId" column="prize_id"/>
|
||||
<result property="gender" column="gender"/>
|
||||
<result property="prizeName" column="prize_name"/>
|
||||
<result property="prizeDesc" column="prize_desc"/>
|
||||
<result property="prizeImg" column="prize_img"/>
|
||||
<result property="winProbability" column="win_probability"/>
|
||||
<result property="guaranteeDraws" column="guarantee_draws"/>
|
||||
<result property="minWinDraws" column="min_win_draws"/>
|
||||
<result property="stock" column="stock"/>
|
||||
<result property="prizeType" column="prize_type"/>
|
||||
<result property="prizePrice" column="prize_price"/>
|
||||
<result property="autoGive" column="auto_give"/>
|
||||
<result property="isThank" column="is_thank"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user