Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,56 @@ curl --location --request POST 'https://fishpi.cn/report' \

`GET /user/{用户名}/point`

### 查询积分记录

`GET /api/user/points`

分页查询当前用户积分记录。管理员可通过 `userId` 查询指定用户。

请求:

| Key | 说明 | 示例 |
| ------ | ----------------------- | -------------------------------- |
| apiKey | 通用密钥 | oXTQTD4ljryXoIxa1lySgEl6aObrIhSS |
| p | 页码,默认 1 | 1 |
| size | 每页数量,默认 20,最大 200 | 20 |
| userId | 用户 oId,仅管理员可用 | 1659430635383 |

请求示例:

```bash
curl --location --request GET 'https://fishpi.cn/api/user/points?apiKey=oXTQTD4ljryXoIxa1lySgEl6aObrIhSS&p=1&size=20' \
--header 'User-Agent: Mozilla/5.0'
```

响应:

| Key | 说明 | 示例 |
| -------------------------------- | -------------------- | ------------- |
| code | 0 为成功,-1 为失败 | 0 |
| msg | 错误消息 | |
| data | 响应数据 | |
| - userId | 用户 oId | 1659430635383 |
| - records | 积分记录列表 | |
| -- oId | 记录 oId | 1760000000000 |
| -- fromId | 支出用户 oId | 1659430635383 |
| -- toId | 收入用户 oId | sys |
| -- sum | 积分数量 | 20 |
| -- type | 记录类型 | 8 |
| -- time | 记录时间 | 1760000000000 |
| -- dataId | 关联数据 | 1760000000000 |
| -- memo | 备注 | hello |
| -- operation | 收支方向 | + |
| -- balance | 操作后余额 | 183939 |
| -- displayType | 类型名称 | 活动收益 |
| -- description | 记录描述 | 签到奖励 |
| - pagination | 分页信息 | |
| -- paginationCurrentPageNum | 当前页 | 1 |
| -- paginationPageSize | 每页数量 | 20 |
| -- paginationRecordCount | 总记录数 | 100 |
| -- paginationPageCount | 总页数 | 5 |
| -- paginationPageNums | 页码列表 | [1,2,3,4,5] |

### 查询用户勋章

`GET /user/{用户名}/medal`
Expand Down
112 changes: 112 additions & 0 deletions src/main/java/org/b3log/symphony/processor/UserProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ public static void register() {
Dispatcher.post("/user/edit/points", userProcessor::adjustPoint);
Dispatcher.post("/user/edit/notification", userProcessor::sendSystemNotification);
Dispatcher.post("/user/identify", userProcessor::submitIdentify, loginCheck::handle);
Dispatcher.get("/api/user/points", userProcessor::getUserPointRecords, loginCheck::handle);
Dispatcher.get("/api/user/{userName}/articles", userProcessor::userArticles, loginCheck::handle);
Dispatcher.get("/api/user/{userName}/breezemoons", userProcessor::userBreezemoons, loginCheck::handle);
}
Expand Down Expand Up @@ -1666,6 +1667,117 @@ public void showHomePoints(final RequestContext context) {
dataModel.put(Common.TYPE, "points");
}

/**
* Gets user point records.
*
* @param context the specified context
*/
public void getUserPointRecords(final RequestContext context) {
final JSONObject currentUser = (JSONObject) context.attr(User.USER);
if (null == currentUser) {
context.sendError(401);
return;
}

final boolean isAdmin = Role.ROLE_ID_C_ADMIN.equals(currentUser.optString(User.USER_ROLE));
final String currentUserId = currentUser.optString(Keys.OBJECT_ID);
String targetUserId = StringUtils.trim(context.param("userId"));
if (StringUtils.isBlank(targetUserId)) {
targetUserId = currentUserId;
} else if (!StringUtils.isNumeric(targetUserId) || targetUserId.length() > 19) {
renderUserPointRecordsError(context, "参数错误");
return;
}

if (!isAdmin && !currentUserId.equals(targetUserId)) {
renderUserPointRecordsError(context, "无权限");
return;
}

final JSONObject targetUser = userQueryService.getUser(targetUserId);
if (null == targetUser) {
renderUserPointRecordsError(context, "用户不存在");
return;
}

final int pageNum = getPositiveIntParam(context, "p", 1);
final int pageSize = Math.min(getPositiveIntParam(context, "size", Symphonys.USER_HOME_LIST_CNT), 200);
final int windowSize = Symphonys.USER_HOME_LIST_WIN_SIZE;

final JSONObject userPointsResult = pointtransferQueryService.getUserPoints(targetUserId, pageNum, pageSize);
if (null == userPointsResult) {
renderUserPointRecordsError(context, "查询失败");
return;
}

final int recordCount = userPointsResult.optInt(Pagination.PAGINATION_RECORD_COUNT);
final int pageCount = (int) Math.ceil(recordCount / (double) pageSize);
final List<Integer> pageNums = Paginator.paginate(pageNum, pageSize, pageCount, windowSize);

final JSONArray records = new JSONArray();
final JSONArray points = userPointsResult.optJSONArray(Keys.RESULTS);
if (null != points) {
for (int i = 0; i < points.length(); i++) {
final Object item = points.opt(i);
if (!(item instanceof JSONObject)) {
continue;
}

final JSONObject point = (JSONObject) item;
records.put(new JSONObject()
.put(Keys.OBJECT_ID, point.optString(Keys.OBJECT_ID))
.put(Pointtransfer.FROM_ID, point.optString(Pointtransfer.FROM_ID))
.put(Pointtransfer.TO_ID, point.optString(Pointtransfer.TO_ID))
.put(Pointtransfer.SUM, point.optInt(Pointtransfer.SUM))
.put(Pointtransfer.TYPE, point.optInt(Pointtransfer.TYPE))
.put(Pointtransfer.TIME, point.optLong(Pointtransfer.TIME))
.put(Pointtransfer.DATA_ID, point.optString(Pointtransfer.DATA_ID))
.put(Pointtransfer.MEMO, point.optString(Pointtransfer.MEMO))
.put(Common.OPERATION, point.optString(Common.OPERATION))
.put(Common.BALANCE, point.optInt(Common.BALANCE))
.put(Common.DISPLAY_TYPE, point.optString(Common.DISPLAY_TYPE))
.put(Common.DESCRIPTION, point.optString(Common.DESCRIPTION)));
}
}

final JSONObject pagination = new JSONObject()
.put(Pagination.PAGINATION_CURRENT_PAGE_NUM, pageNum)
.put(Pagination.PAGINATION_PAGE_SIZE, pageSize)
.put(Pagination.PAGINATION_RECORD_COUNT, recordCount)
.put(Pagination.PAGINATION_PAGE_COUNT, pageCount)
.put(Pagination.PAGINATION_PAGE_NUMS, pageNums);
final JSONObject data = new JSONObject()
.put("userId", targetUserId)
.put("records", records)
.put(Pagination.PAGINATION, pagination);

context.renderJSON(new JSONObject()
.put(Keys.CODE, StatusCodes.SUCC)
.put(Keys.MSG, "")
.put(Common.DATA, data));
}

private int getPositiveIntParam(final RequestContext context, final String key, final int defaultValue) {
final String value = StringUtils.trim(context.param(key));
if (StringUtils.isBlank(value)) {
return defaultValue;
}

try {
final int ret = Integer.parseInt(value);
return ret > 0 ? ret : defaultValue;
} catch (final NumberFormatException e) {
return defaultValue;
}
}

private void renderUserPointRecordsError(final RequestContext context, final String msg) {
context.renderJSON(new JSONObject()
.put(Keys.CODE, StatusCodes.ERR)
.put(Keys.MSG, msg)
.put(Common.DATA, new JSONObject()));
}

/**
* List usernames.
*
Expand Down
Loading