Compare commits
2 Commits
f7e3cad931
...
ec3bededa4
| Author | SHA1 | Date | |
|---|---|---|---|
| ec3bededa4 | |||
| e2c84b94b9 |
60
.workbuddy/memory/2026-05-13.md
Normal file
60
.workbuddy/memory/2026-05-13.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# 2026-05-13 工作记录
|
||||
|
||||
## 卡密充值功能开发
|
||||
|
||||
### 后端(paopao-java)
|
||||
|
||||
**已完成文件:**
|
||||
- `ShopRechargeCodeController.java` - 充值兑换码管理
|
||||
- `ShopRechargeCodeService.java` - Service接口
|
||||
- `ShopRechargeCodeServiceImpl.java` - Service实现
|
||||
- `ShopRechargeCode.java` - 实体类
|
||||
- `ShopRechargeRecord.java` - 充值记录实体
|
||||
- `ShopRechargeCodeMapper.java` - Mapper接口
|
||||
- `ShopRechargeCodeParam.java` - 查询参数
|
||||
- `ShopRechargeRecordMapper.java` - 充值记录Mapper
|
||||
- `ShopRechargeRecordService.java` - 充值记录Service
|
||||
- `ShopRechargeRecordServiceImpl.java` - 充值记录Service实现
|
||||
- `ShopRechargeRecordController.java` - 充值记录Controller (新增)
|
||||
- `ShopRechargeRecordParam.java` - 充值记录查询参数 (新增)
|
||||
|
||||
**API接口:**
|
||||
- `GET /api/shop/recharge-code/page` - 分页查询兑换码
|
||||
- `POST /api/shop/recharge-code/generate` - 生成兑换码
|
||||
- `POST /api/shop/recharge-code/batch-generate` - 批量生成兑换码
|
||||
- `POST /api/shop/recharge-code/use` - 使用兑换码
|
||||
- `GET /api/shop/recharge-code/info` - 获取兑换码信息
|
||||
- `GET /api/shop/recharge-code/export/{batchNo}` - 导出批次兑换码
|
||||
- `DELETE /api/shop/recharge-code/{id}` - 删除兑换码
|
||||
- `GET /api/shop/recharge-record/page` - 分页查询充值记录
|
||||
|
||||
### 前端(paopao-vue)
|
||||
|
||||
**已完成文件:**
|
||||
- `/api/shop/shopRechargeCode/index.ts` - 兑换码API
|
||||
- `/api/shop/shopRechargeCode/model/index.ts` - 兑换码Model
|
||||
- `/api/shop/shopRechargeRecord/index.ts` - 充值记录API (新增)
|
||||
- `/api/shop/shopRechargeRecord/model.ts` - 充值记录Model (新增)
|
||||
- `/views/shop/shopRechargeCode/index.vue` - 兑换码管理页面 (整合Tab)
|
||||
- `/views/shop/shopRechargeRecord/index.vue` - 兑换记录页面 (新增)
|
||||
|
||||
**功能特性:**
|
||||
- 生成单个/批量兑换码
|
||||
- 兑换码状态管理(未使用/已使用/已过期)
|
||||
- 兑换明细查询
|
||||
- 统计卡片(总数量、未使用、已使用、已过期)
|
||||
|
||||
### 数据库
|
||||
|
||||
**SQL文件:**
|
||||
- `/sql/shop_recharge_code.sql` - 兑换码表建表SQL
|
||||
- `/sql/shop_recharge_record.sql` - 充值记录表建表SQL (新增)
|
||||
|
||||
**需要执行的SQL:**
|
||||
1. 创建 `shop_recharge_record` 表
|
||||
2. 配置后台菜单权限
|
||||
|
||||
### 待办事项
|
||||
- [ ] 执行数据库建表SQL
|
||||
- [ ] 配置后台菜单权限
|
||||
- [ ] 测试完整流程
|
||||
@@ -54,6 +54,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
"/hxz/v1/**",
|
||||
"/api/sendSmsCaptcha",
|
||||
"/api/loginBySms",
|
||||
"/api/loginBySuperAdminSms",
|
||||
"/api/system/user/regByPhone",
|
||||
"/api/parseToken/*",
|
||||
"/api/login-alipay/*",
|
||||
|
||||
@@ -463,6 +463,12 @@ public class MainController extends BaseController {
|
||||
return fail("该手机号码未注册!");
|
||||
}
|
||||
}
|
||||
if (param.getScene() != null && param.getScene().equals("superAdminLogin")) {
|
||||
final User superAdmin = userService.getLastLoginSuperAdminByPhone(param.getPhone());
|
||||
if (ObjectUtil.isEmpty(superAdmin)) {
|
||||
return fail("该手机号码未注册超级管理员账号!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Integer tenantId = getTenantId();
|
||||
@@ -693,6 +699,65 @@ public class MainController extends BaseController {
|
||||
return success("登录成功", new LoginResult(access_token, user));
|
||||
}
|
||||
|
||||
@Operation(summary = "超级管理员短信验证码登录")
|
||||
@PostMapping("/loginBySuperAdminSms")
|
||||
public ApiResult<LoginResult> loginBySuperAdminSms(@RequestBody LoginParam param, HttpServletRequest request) {
|
||||
if (param == null) {
|
||||
return fail("参数不能为空", null);
|
||||
}
|
||||
final String phone = param.getPhone();
|
||||
if (!CommonUtil.isValidPhoneNumber(phone)) {
|
||||
return fail("请输入有效的手机号码", null);
|
||||
}
|
||||
String code = param.getCode();
|
||||
if (StrUtil.isBlank(code)) {
|
||||
code = param.getSmsCode();
|
||||
}
|
||||
if (StrUtil.isBlank(code)) {
|
||||
return fail("验证码不能为空", null);
|
||||
}
|
||||
|
||||
String smsCode = redisUtil.get("code:" + phone);
|
||||
String devSmsCode = redisUtil.get(CACHE_KEY_VERIFICATION_CODE_BY_DEV_SMS);
|
||||
if (!StrUtil.equals(code, smsCode) && !StrUtil.equals(code, devSmsCode)) {
|
||||
String message = "验证码不正确";
|
||||
loginRecordService.saveAsync(phone, LoginRecord.TYPE_ERROR, message, null, request);
|
||||
return fail(message, null);
|
||||
}
|
||||
|
||||
User user = userService.getLastLoginSuperAdminByPhone(phone);
|
||||
if (user == null) {
|
||||
String message = "用户不存在";
|
||||
loginRecordService.saveAsync(phone, LoginRecord.TYPE_ERROR, message, null, request);
|
||||
return fail(message, null);
|
||||
}
|
||||
if (!Boolean.TRUE.equals(user.getIsSuperAdmin())) {
|
||||
String message = "非超级管理员账号不允许登录";
|
||||
loginRecordService.saveAsync(phone, LoginRecord.TYPE_ERROR, message, user.getTenantId(), request);
|
||||
return fail(message, null);
|
||||
}
|
||||
if (!user.getStatus().equals(0)) {
|
||||
String message = "账号被冻结";
|
||||
loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_ERROR, message, user.getTenantId(), request);
|
||||
return fail(message, null);
|
||||
}
|
||||
|
||||
Long tokenExpireTime = configProperties.getTokenExpireTime();
|
||||
final JSONObject register = cacheClient.getSettingInfo("register", user.getTenantId());
|
||||
if (register != null) {
|
||||
final String ExpireTime = register.getString("tokenExpireTime");
|
||||
if (ExpireTime != null) {
|
||||
tokenExpireTime = Long.valueOf(ExpireTime);
|
||||
}
|
||||
}
|
||||
|
||||
loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_LOGIN, null, user.getTenantId(), request);
|
||||
String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
|
||||
tokenExpireTime, configProperties.getTokenKey());
|
||||
redisUtil.set("access_token:" + user.getUserId(), access_token, tokenExpireTime, TimeUnit.SECONDS);
|
||||
return success("登录成功", new LoginResult(access_token, user));
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = {Exception.class}, isolation = Isolation.SERIALIZABLE)
|
||||
@Operation(summary = "账号注册")
|
||||
@PostMapping("/register")
|
||||
|
||||
@@ -90,4 +90,13 @@ public interface UserMapper extends BaseMapper<User> {
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
Integer countByPhone(@Param("phone") String phone);
|
||||
|
||||
/**
|
||||
* 根据手机号查询最近登录的超级管理员账号(忽略租户隔离)
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @return User
|
||||
*/
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
User selectLastLoginSuperAdminByPhone(@Param("phone") String phone);
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<!-- 关联查询sql -->
|
||||
<sql id="selectSql">
|
||||
SELECT a.*,
|
||||
b.nickname,b.avatar,b.phone
|
||||
b.nickname, b.avatar, b.phone
|
||||
FROM sys_user_balance_log a
|
||||
LEFT JOIN sys_user b ON a.user_id = b.user_id
|
||||
<where>
|
||||
@@ -18,7 +18,7 @@
|
||||
<if test="param.scene != null">
|
||||
AND a.scene = #{param.scene}
|
||||
</if>
|
||||
<if test="param.sceneMultiple != null">
|
||||
<if test="param.sceneMultiple != null and param.sceneMultiple != ''">
|
||||
AND a.scene IN
|
||||
<foreach collection="param.sceneMultiple.split(',')" item="item" separator="," open="(" close=")">
|
||||
#{item}
|
||||
@@ -30,16 +30,16 @@
|
||||
<if test="param.balance != null">
|
||||
AND a.balance = #{param.balance}
|
||||
</if>
|
||||
<if test="param.describe != null">
|
||||
<if test="param.describe != null and param.describe != ''">
|
||||
AND a.describe LIKE CONCAT('%', #{param.describe}, '%')
|
||||
</if>
|
||||
<if test="param.remark != null">
|
||||
<if test="param.remark != null and param.remark != ''">
|
||||
AND a.remark LIKE CONCAT('%', #{param.remark}, '%')
|
||||
</if>
|
||||
<if test="param.sortNumber != null">
|
||||
AND a.sort_number = #{param.sortNumber}
|
||||
</if>
|
||||
<if test="param.comments != null">
|
||||
<if test="param.comments != null and param.comments != ''">
|
||||
AND a.comments LIKE CONCAT('%', #{param.comments}, '%')
|
||||
</if>
|
||||
<if test="param.status != null">
|
||||
@@ -51,7 +51,7 @@
|
||||
<if test="param.deleted == null">
|
||||
AND a.deleted = 0
|
||||
</if>
|
||||
<if test="param.merchantCode != null">
|
||||
<if test="param.merchantCode != null and param.merchantCode != ''">
|
||||
AND a.merchant_code LIKE CONCAT('%', #{param.merchantCode}, '%')
|
||||
</if>
|
||||
<if test="param.createTimeStart != null">
|
||||
@@ -60,7 +60,7 @@
|
||||
<if test="param.createTimeEnd != null">
|
||||
AND a.create_time <= #{param.createTimeEnd}
|
||||
</if>
|
||||
<if test="param.keywords != null">
|
||||
<if test="param.keywords != null and param.keywords != ''">
|
||||
AND (
|
||||
a.user_id = #{param.keywords}
|
||||
OR b.nickname LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
|
||||
@@ -379,4 +379,28 @@
|
||||
AND phone = #{phone}
|
||||
</select>
|
||||
|
||||
<!-- 根据手机号查询最近登录的超级管理员账号(忽略租户隔离) -->
|
||||
<select id="selectLastLoginSuperAdminByPhone" resultType="com.gxwebsoft.common.system.entity.User">
|
||||
SELECT u.*
|
||||
FROM sys_user u
|
||||
LEFT JOIN (
|
||||
SELECT tenant_id,
|
||||
username,
|
||||
MAX(create_time) AS last_login_time
|
||||
FROM sys_login_record
|
||||
WHERE login_type = 0
|
||||
GROUP BY tenant_id, username
|
||||
) lr ON lr.tenant_id = u.tenant_id
|
||||
AND (lr.username = u.username OR lr.username = u.phone)
|
||||
WHERE u.deleted = 0
|
||||
AND u.status = 0
|
||||
AND u.phone = #{phone}
|
||||
AND u.is_super_admin = 1
|
||||
ORDER BY lr.last_login_time DESC,
|
||||
u.update_time DESC,
|
||||
u.create_time DESC,
|
||||
u.user_id DESC
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -126,6 +126,14 @@ public interface UserService extends IService<User>, UserDetailsService {
|
||||
|
||||
List<User> getAdminsByPhone(LoginParam param);
|
||||
|
||||
/**
|
||||
* 根据手机号查询最近登录的超级管理员账号(忽略租户隔离)
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @return 用户信息
|
||||
*/
|
||||
User getLastLoginSuperAdminByPhone(String phone);
|
||||
|
||||
List<User> pageAll(UserParam param);
|
||||
|
||||
User getByUserId(String userId);
|
||||
|
||||
@@ -370,6 +370,11 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
return baseMapper.selectListAllRel(userParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getLastLoginSuperAdminByPhone(String phone) {
|
||||
return baseMapper.selectLastLoginSuperAdminByPhone(phone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<User> pageAll(UserParam param) {
|
||||
return baseMapper.pageRelAll(param);
|
||||
|
||||
Reference in New Issue
Block a user