“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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package com.tcm.training.admin.app.points.service;
 
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tcm.training.admin.app.auth.service.AppAuthSessionService;
import com.tcm.training.admin.app.points.vo.AppPointsOverviewVO;
import com.tcm.training.admin.live.entity.Clinic;
import com.tcm.training.admin.live.mapper.ClinicMapper;
import com.tcm.training.admin.member.entity.AppUser;
import com.tcm.training.admin.member.mapper.UserMapper;
import com.tcm.training.admin.points.entity.PointsConfig;
import com.tcm.training.admin.points.entity.UserPointsAccount;
import com.tcm.training.admin.points.mapper.UserPointsAccountMapper;
import com.tcm.training.admin.points.service.PointsSettingsAppService;
import com.tcm.training.admin.points.vo.PointsConfigVO;
import org.springframework.stereotype.Service;
 
/**
 * APP 我的积分页面聚合服务。
 */
@Service
public class AppPointsOverviewService {
 
    private static final int USER_STATUS_ENABLED = 1;
 
    private final AppAuthSessionService appAuthSessionService;
    private final UserMapper userMapper;
    private final UserPointsAccountMapper userPointsAccountMapper;
    private final ClinicMapper clinicMapper;
    private final PointsSettingsAppService pointsSettingsAppService;
 
    /**
     * 注入 APP 我的积分页面所需依赖。
     */
    public AppPointsOverviewService(AppAuthSessionService appAuthSessionService,
                                    UserMapper userMapper,
                                    UserPointsAccountMapper userPointsAccountMapper,
                                    ClinicMapper clinicMapper,
                                    PointsSettingsAppService pointsSettingsAppService) {
        this.appAuthSessionService = appAuthSessionService;
        this.userMapper = userMapper;
        this.userPointsAccountMapper = userPointsAccountMapper;
        this.clinicMapper = clinicMapper;
        this.pointsSettingsAppService = pointsSettingsAppService;
    }
 
    /**
     * 获取当前登录用户的积分页面聚合数据。
     */
    public AppPointsOverviewVO getCurrentOverview() {
        Long userId = appAuthSessionService.requireLoginUserId();
        AppUser user = requireEnabledUser(userId);
        PointsConfigVO config = pointsSettingsAppService.current();
 
        int pointsBalance = resolvePointsBalance(userId);
        int requiredPoints = config == null || config.getRequiredPoints() == null ? 0 : Math.max(config.getRequiredPoints().intValue(), 0);
 
        AppPointsOverviewVO result = new AppPointsOverviewVO();
        result.setPointsBalance(Integer.valueOf(pointsBalance));
        result.setRequiredPoints(Integer.valueOf(requiredPoints));
        result.setProgressPercent(Integer.valueOf(calculateProgressPercent(pointsBalance, requiredPoints)));
        result.setPointsShortfall(Integer.valueOf(Math.max(requiredPoints - pointsBalance, 0)));
        result.setActivityStartAt(config == null ? null : config.getActivityStartAt());
        result.setActivityEndAt(config == null ? null : config.getActivityEndAt());
        result.setGiftCover(trimToEmpty(config == null ? null : config.getGiftCover()));
        result.setGiftName(trimToEmpty(config == null ? null : config.getGiftName()));
 
        Clinic clinic = resolveBoundClinic(user);
        result.setClinicName(trimToEmpty(clinic == null ? null : clinic.getName()));
        result.setClinicAddress(trimToEmpty(clinic == null ? null : clinic.getAddress()));
        return result;
    }
 
    /**
     * 校验当前登录用户存在且可用。
     */
    private AppUser requireEnabledUser(Long userId) {
        AppUser user = userMapper.selectById(userId);
        if (user == null || user.getDeleted() == null || user.getDeleted().intValue() != 0) {
            throw new IllegalArgumentException("用户不存在");
        }
        if (user.getStatus() == null || user.getStatus().intValue() != USER_STATUS_ENABLED) {
            throw new IllegalArgumentException("用户已禁用");
        }
        return user;
    }
 
    /**
     * 读取当前用户积分余额,没有积分账户时按0返回。
     */
    private int resolvePointsBalance(Long userId) {
        UserPointsAccount account = userPointsAccountMapper.selectOne(new LambdaQueryWrapper<UserPointsAccount>()
                .eq(UserPointsAccount::getAppUserId, userId)
                .eq(UserPointsAccount::getDeleted, 0)
                .orderByDesc(UserPointsAccount::getId)
                .last("LIMIT 1"));
        if (account == null || account.getPointsBalance() == null) {
            return 0;
        }
        return Math.max(account.getPointsBalance().intValue(), 0);
    }
 
    /**
     * 读取当前用户绑定诊所,不存在时返回空。
     */
    private Clinic resolveBoundClinic(AppUser user) {
        if (user == null || user.getClinicId() == null) {
            return null;
        }
        Clinic clinic = clinicMapper.selectById(user.getClinicId());
        if (clinic == null || clinic.getDeleted() == null || clinic.getDeleted().intValue() != 0) {
            return null;
        }
        return clinic;
    }
 
    /**
     * 计算积分进度百分比,避免返回非法值。
     */
    private int calculateProgressPercent(int current, int total) {
        if (total <= 0 || current <= 0) {
            return 0;
        }
        if (current >= total) {
            return 100;
        }
        return Math.max(Math.min((int) Math.round((current * 100.0D) / total), 100), 0);
    }
 
    /**
     * 将可空文本归一化为空字符串。
     */
    private String trimToEmpty(String value) {
        if (value == null) {
            return "";
        }
        return value.trim();
    }
}