“mitao”
2026-04-15 5ad8d714d43ecf06aa9d900a69e7b22018ce7ed6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package com.tcm.training.admin.app.points.service;
 
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tcm.training.admin.app.auth.service.AppAuthSessionService;
import com.tcm.training.admin.app.points.vo.AppPointsLedgerItemVO;
import com.tcm.training.admin.common.PageResponse;
import com.tcm.training.admin.points.row.PointsLedgerRow;
import com.tcm.training.admin.points.service.PointsLedgerAppService;
import com.tcm.training.admin.points.mapper.PointsLedgerMapper;
import org.springframework.stereotype.Service;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * APP 积分明细服务。
 */
@Service
public class AppPointsLedgerService {
 
    private final AppAuthSessionService appAuthSessionService;
    private final PointsLedgerMapper pointsLedgerMapper;
    private final PointsLedgerAppService pointsLedgerAppService;
 
    /**
     * 注入 APP 积分明细所需依赖。
     */
    public AppPointsLedgerService(AppAuthSessionService appAuthSessionService,
                                  PointsLedgerMapper pointsLedgerMapper,
                                  PointsLedgerAppService pointsLedgerAppService) {
        this.appAuthSessionService = appAuthSessionService;
        this.pointsLedgerMapper = pointsLedgerMapper;
        this.pointsLedgerAppService = pointsLedgerAppService;
    }
 
    /**
     * 分页查询当前登录用户的积分明细。
     */
    public PageResponse<AppPointsLedgerItemVO> page(int page, int pageSize, String incomeExpenseType) {
        Long userId = appAuthSessionService.requireLoginUserId();
        int normalizedPage = page <= 0 ? 1 : page;
        int normalizedPageSize = pageSize <= 0 ? 20 : pageSize;
        pointsLedgerAppService.syncLedger();
        IPage<PointsLedgerRow> result = pointsLedgerMapper.selectAppLedgerPage(
                new Page<PointsLedgerRow>(normalizedPage, normalizedPageSize),
                userId,
                trimToNull(incomeExpenseType)
        );
        return PageResponse.of(
                toItems(result.getRecords()),
                result.getTotal(),
                result.getCurrent(),
                result.getSize()
        );
    }
 
    /**
     * 将积分流水行转换为 APP 页面需要的列表结构。
     */
    private List<AppPointsLedgerItemVO> toItems(List<PointsLedgerRow> rows) {
        List<AppPointsLedgerItemVO> list = new ArrayList<AppPointsLedgerItemVO>();
        if (rows == null) {
            return list;
        }
        for (PointsLedgerRow row : rows) {
            AppPointsLedgerItemVO item = new AppPointsLedgerItemVO();
            item.setId(row.getId());
            item.setTitle(buildTitle(row));
            item.setIncomeExpenseType(trimToEmpty(row.getIncomeExpenseType()));
            item.setPointsDelta(row.getPointsDelta() == null ? 0 : row.getPointsDelta());
            item.setOperatedAt(row.getOperatedAt());
            list.add(item);
        }
        return list;
    }
 
    /**
     * 构建 APP 积分明细标题,保持与静态稿一致的业务文案。
     */
    private String buildTitle(PointsLedgerRow row) {
        String contentName = trimToEmpty(row == null ? null : row.getContentName());
        if (contentName.isEmpty()) {
            contentName = "-";
        }
        String businessType = trimToEmpty(row == null ? null : row.getBusinessType());
        if (PointsLedgerAppService.BUSINESS_LIVE_WATCH.equals(businessType)) {
            return "观看课程【" + contentName + "】";
        }
        if (PointsLedgerAppService.BUSINESS_POINTS_EXCHANGE.equals(businessType)) {
            return "兑换礼品【" + contentName + "】";
        }
        return "积分变动【" + contentName + "】";
    }
 
    /**
     * 将可空文本归一化为空字符串。
     */
    private String trimToEmpty(String value) {
        if (value == null) {
            return "";
        }
        return value.trim();
    }
 
    /**
     * 将空白筛选值归一化为 null,便于 MyBatis 条件判断。
     */
    private String trimToNull(String value) {
        String text = trimToEmpty(value);
        return text.isEmpty() ? null : text;
    }
}