feat: 添加获取当前用户积分余额的接口
This commit is contained in:
9
.claude/settings.local.json
Normal file
9
.claude/settings.local.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"permissions": {
|
||||||
|
"allow": [
|
||||||
|
"Bash(git add:*)"
|
||||||
|
],
|
||||||
|
"deny": [],
|
||||||
|
"ask": []
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package com.gameplatform.server.controller.admin;
|
|||||||
import com.gameplatform.server.model.dto.account.*;
|
import com.gameplatform.server.model.dto.account.*;
|
||||||
import com.gameplatform.server.model.dto.common.PageResult;
|
import com.gameplatform.server.model.dto.common.PageResult;
|
||||||
import com.gameplatform.server.service.account.AccountService;
|
import com.gameplatform.server.service.account.AccountService;
|
||||||
|
import com.gameplatform.server.security.JwtService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
@@ -16,9 +17,11 @@ import reactor.core.publisher.Mono;
|
|||||||
@Tag(name = "管理员账户管理", description = "管理员账户的增删改查操作")
|
@Tag(name = "管理员账户管理", description = "管理员账户的增删改查操作")
|
||||||
public class AccountController {
|
public class AccountController {
|
||||||
private final AccountService accountService;
|
private final AccountService accountService;
|
||||||
|
private final JwtService jwtService;
|
||||||
|
|
||||||
public AccountController(AccountService accountService) {
|
public AccountController(AccountService accountService, JwtService jwtService) {
|
||||||
this.accountService = accountService;
|
this.accountService = accountService;
|
||||||
|
this.jwtService = jwtService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@@ -72,5 +75,27 @@ public class AccountController {
|
|||||||
public Mono<Void> resetPassword(@Parameter(description = "账户ID") @PathVariable Long id, @Valid @RequestBody ResetPasswordRequest req) {
|
public Mono<Void> resetPassword(@Parameter(description = "账户ID") @PathVariable Long id, @Valid @RequestBody ResetPasswordRequest req) {
|
||||||
return accountService.resetPassword(id, req.getNewPassword(), Boolean.TRUE.equals(req.getForceLogout()));
|
return accountService.resetPassword(id, req.getNewPassword(), Boolean.TRUE.equals(req.getForceLogout()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/me/points-balance")
|
||||||
|
@Operation(summary = "获取当前用户积分余额", description = "根据token解析用户ID并获取当前用户的积分余额")
|
||||||
|
public Mono<PointsBalanceResponse> getCurrentUserPointsBalance(
|
||||||
|
@Parameter(hidden = true) @RequestHeader("Authorization") String authHeader) {
|
||||||
|
return Mono.fromCallable(() -> {
|
||||||
|
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
|
||||||
|
throw new IllegalArgumentException("Authorization header is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
String token = authHeader.substring(7);
|
||||||
|
io.jsonwebtoken.Claims claims = jwtService.parse(token);
|
||||||
|
Long userId = claims.get("userId", Long.class);
|
||||||
|
|
||||||
|
if (userId == null) {
|
||||||
|
throw new IllegalArgumentException("Invalid token: userId not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
return userId;
|
||||||
|
})
|
||||||
|
.flatMap(accountService::getCurrentUserPointsBalance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.gameplatform.server.model.dto.account;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "用户积分余额响应")
|
||||||
|
public class PointsBalanceResponse {
|
||||||
|
@Schema(description = "用户ID")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Schema(description = "用户名")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Schema(description = "用户类型")
|
||||||
|
private String userType;
|
||||||
|
|
||||||
|
@Schema(description = "积分余额")
|
||||||
|
private Long pointsBalance;
|
||||||
|
|
||||||
|
public Long getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserId(Long userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserType() {
|
||||||
|
return userType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserType(String userType) {
|
||||||
|
this.userType = userType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getPointsBalance() {
|
||||||
|
return pointsBalance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPointsBalance(Long pointsBalance) {
|
||||||
|
this.pointsBalance = pointsBalance;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import com.gameplatform.server.mapper.account.UserAccountMapper;
|
|||||||
import com.gameplatform.server.model.dto.account.AccountCreateRequest;
|
import com.gameplatform.server.model.dto.account.AccountCreateRequest;
|
||||||
import com.gameplatform.server.model.dto.account.AccountResponse;
|
import com.gameplatform.server.model.dto.account.AccountResponse;
|
||||||
import com.gameplatform.server.model.dto.account.AccountUpdateRequest;
|
import com.gameplatform.server.model.dto.account.AccountUpdateRequest;
|
||||||
|
import com.gameplatform.server.model.dto.account.PointsBalanceResponse;
|
||||||
import com.gameplatform.server.model.dto.common.PageResult;
|
import com.gameplatform.server.model.dto.common.PageResult;
|
||||||
import com.gameplatform.server.model.entity.account.UserAccount;
|
import com.gameplatform.server.model.entity.account.UserAccount;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
@@ -144,6 +145,24 @@ public class AccountService {
|
|||||||
.then();
|
.then();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Mono<PointsBalanceResponse> getCurrentUserPointsBalance(Long userId) {
|
||||||
|
return Mono.fromCallable(() -> {
|
||||||
|
UserAccount account = mapper.selectById(userId);
|
||||||
|
if (account == null) {
|
||||||
|
throw new IllegalArgumentException("用户不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
PointsBalanceResponse response = new PointsBalanceResponse();
|
||||||
|
response.setUserId(account.getId());
|
||||||
|
response.setUsername(account.getUsername());
|
||||||
|
response.setUserType(account.getUserType());
|
||||||
|
response.setPointsBalance(account.getPointsBalance());
|
||||||
|
|
||||||
|
return response;
|
||||||
|
})
|
||||||
|
.subscribeOn(Schedulers.boundedElastic());
|
||||||
|
}
|
||||||
|
|
||||||
private AccountResponse toResp(UserAccount a) {
|
private AccountResponse toResp(UserAccount a) {
|
||||||
if (a == null) return null;
|
if (a == null) return null;
|
||||||
AccountResponse r = new AccountResponse();
|
AccountResponse r = new AccountResponse();
|
||||||
|
|||||||
32
test_target_score.http
Normal file
32
test_target_score.http
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
### 获取目标点数接口测试
|
||||||
|
|
||||||
|
# 测试获取目标点数
|
||||||
|
GET http://localhost:8080/api/link/target-score?codeNo=YOUR_CODE_NO_HERE
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
# 示例:使用实际的codeNo测试
|
||||||
|
# GET http://localhost:8080/api/link/target-score?codeNo=ABC123DEF456
|
||||||
|
# Accept: application/json
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
# 响应格式示例:
|
||||||
|
# 成功时:
|
||||||
|
# {
|
||||||
|
# "success": true,
|
||||||
|
# "completedPoints": 13750,
|
||||||
|
# "machineId": "device123",
|
||||||
|
# "codeNo": "ABC123DEF456",
|
||||||
|
# "errorMessage": null
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# 失败时:
|
||||||
|
# {
|
||||||
|
# "success": false,
|
||||||
|
# "completedPoints": null,
|
||||||
|
# "machineId": "device123",
|
||||||
|
# "codeNo": "ABC123DEF456",
|
||||||
|
# "errorMessage": "网络繁忙,稍后再试"
|
||||||
|
# }
|
||||||
155
积分余额接口文档.md
Normal file
155
积分余额接口文档.md
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
# 用户积分余额接口文档
|
||||||
|
|
||||||
|
## 接口概述
|
||||||
|
|
||||||
|
获取当前登录用户的积分余额信息,通过JWT token自动识别用户身份。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 接口详情
|
||||||
|
|
||||||
|
### 基本信息
|
||||||
|
- **接口路径**: `/api/admin/accounts/me/points-balance`
|
||||||
|
- **请求方法**: `GET`
|
||||||
|
- **接口描述**: 根据token解析用户ID并获取当前用户的积分余额
|
||||||
|
- **认证方式**: JWT Bearer Token
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 请求参数
|
||||||
|
|
||||||
|
### Headers
|
||||||
|
| 参数名 | 类型 | 必填 | 说明 |
|
||||||
|
|--------|------|------|------|
|
||||||
|
| Authorization | string | 是 | Bearer {token},JWT认证令牌 |
|
||||||
|
|
||||||
|
### 请求示例
|
||||||
|
```http
|
||||||
|
GET /api/admin/accounts/me/points-balance HTTP/1.1
|
||||||
|
Host: localhost:8080
|
||||||
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
||||||
|
Content-Type: application/json
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 响应结果
|
||||||
|
|
||||||
|
### 成功响应 (200 OK)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"userId": 12345,
|
||||||
|
"username": "agent001",
|
||||||
|
"userType": "AGENT",
|
||||||
|
"pointsBalance": 15000
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 响应字段说明
|
||||||
|
| 字段名 | 类型 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| userId | Long | 用户ID |
|
||||||
|
| username | String | 用户名 |
|
||||||
|
| userType | String | 用户类型,ADMIN(管理员)或 AGENT(代理) |
|
||||||
|
| pointsBalance | Long | 积分余额(单位:积分点数) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 错误响应
|
||||||
|
|
||||||
|
### 401 未授权
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": "Unauthorized",
|
||||||
|
"message": "Authorization header is required"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 400 请求错误
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": "Bad Request",
|
||||||
|
"message": "Invalid token: userId not found"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 404 用户不存在
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": "Not Found",
|
||||||
|
"message": "用户不存在"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 调用示例
|
||||||
|
|
||||||
|
### JavaScript (fetch)
|
||||||
|
```javascript
|
||||||
|
const token = 'your-jwt-token-here';
|
||||||
|
|
||||||
|
fetch('/api/admin/accounts/me/points-balance', {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${token}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
console.log('用户积分余额:', data.pointsBalance);
|
||||||
|
console.log('用户信息:', data);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('获取积分余额失败:', error);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### curl
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:8080/api/admin/accounts/me/points-balance" \
|
||||||
|
-H "Authorization: Bearer your-jwt-token-here" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Java (Spring WebFlux)
|
||||||
|
```java
|
||||||
|
WebClient webClient = WebClient.create("http://localhost:8080");
|
||||||
|
|
||||||
|
Mono<PointsBalanceResponse> response = webClient
|
||||||
|
.get()
|
||||||
|
.uri("/api/admin/accounts/me/points-balance")
|
||||||
|
.header("Authorization", "Bearer " + jwtToken)
|
||||||
|
.retrieve()
|
||||||
|
.bodyToMono(PointsBalanceResponse.class);
|
||||||
|
|
||||||
|
response.subscribe(
|
||||||
|
pointsBalance -> System.out.println("积分余额: " + pointsBalance.getPointsBalance()),
|
||||||
|
error -> System.err.println("请求失败: " + error.getMessage())
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. **Token有效性**: JWT token必须有效且未过期
|
||||||
|
2. **用户类型**:
|
||||||
|
- ADMIN用户的积分余额通常为0
|
||||||
|
- AGENT用户才有实际的积分余额
|
||||||
|
3. **权限控制**: 只能查询当前登录用户自己的积分余额
|
||||||
|
4. **数据格式**: 积分余额以长整型返回,单位为积分点数
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 状态码说明
|
||||||
|
|
||||||
|
| 状态码 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| 200 | 请求成功,返回积分余额信息 |
|
||||||
|
| 400 | 请求参数错误或token无效 |
|
||||||
|
| 401 | 未提供认证信息或认证失败 |
|
||||||
|
| 404 | 用户不存在 |
|
||||||
|
| 500 | 服务器内部错误 |
|
||||||
Reference in New Issue
Block a user