hejianhao
2026-08-20 419b25feff8eac325c154efc8f3f6e4b11700483
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
package com.tcm.training.admin.app.home.service;
 
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.tcm.training.admin.agent.entity.ProvincialAgent;
import com.tcm.training.admin.agent.mapper.ProvincialAgentMapper;
import com.tcm.training.admin.app.home.vo.AppVzanLiveEntryVO;
import com.tcm.training.admin.app.user.service.AppUserCenterService;
import com.tcm.training.admin.app.user.vo.AppUserCenterVO;
import com.tcm.training.admin.live.entity.Clinic;
import com.tcm.training.admin.live.mapper.ClinicMapper;
import com.tcm.training.admin.live.service.LiveRoomSettingService;
import com.tcm.training.admin.live.vo.LiveRoomSettingVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;
 
import java.net.URI;
import java.nio.charset.StandardCharsets;
 
@Slf4j
@Service
public class AppVzanLiveEntryService {
    private static final String VZAN_AUTH_SECRET = "2b4fefe91d8cba50";
 
    private final LiveRoomSettingService liveRoomSettingService;
    private final AppUserCenterService appUserCenterService;
    private final ClinicMapper clinicMapper;
    private final ProvincialAgentMapper provincialAgentMapper;
 
    public AppVzanLiveEntryService(LiveRoomSettingService liveRoomSettingService,
                                   AppUserCenterService appUserCenterService,
                                   ClinicMapper clinicMapper,
                                   ProvincialAgentMapper provincialAgentMapper) {
        this.liveRoomSettingService = liveRoomSettingService;
        this.appUserCenterService = appUserCenterService;
        this.clinicMapper = clinicMapper;
        this.provincialAgentMapper = provincialAgentMapper;
    }
 
    public AppVzanLiveEntryVO createEntry() {
        LiveRoomSettingVO setting = liveRoomSettingService.current();
        String liveRoomUrl = setting == null ? null : StrUtil.trim(setting.getLiveRoomUrl());
        validateLiveRoomUrl(liveRoomUrl);
 
        AppUserCenterVO user = appUserCenterService.getCurrentUserCenter();
        String followPhone = resolveFollowPhone(user.getClinicId());
        JSONObject payload = new JSONObject();
        payload.set("tuid", user.getId());
        payload.set("followPhone", followPhone);
        payload.set("third_ts", System.currentTimeMillis());
        payload.set("avatar", StrUtil.trim(user.getAvatar()));
        log.info("微赞入口参数已生成,tuid={}, third_ts={}", user.getId(), payload.get("third_ts"));
 
        SymmetricCrypto sm4 = SmUtil.sm4(VZAN_AUTH_SECRET.getBytes(StandardCharsets.UTF_8));
        String encryptedData = sm4.encryptBase64(payload.toString(), StandardCharsets.UTF_8);
        String entryUrl = UriComponentsBuilder.fromHttpUrl(liveRoomUrl)
                .replaceQueryParam("data", encryptedData)
                .build()
                .encode(StandardCharsets.UTF_8)
                .toUriString();
        log.info("微赞直播生成URL: {}", entryUrl);
        return new AppVzanLiveEntryVO(entryUrl);
    }
 
    private String resolveFollowPhone(Long clinicId) {
        if (clinicId == null) {
            throw new IllegalArgumentException("当前用户未绑定诊所");
        }
        Clinic clinic = clinicMapper.selectById(clinicId);
        if (clinic == null || clinic.getAgentId() == null) {
            throw new IllegalArgumentException("当前诊所未绑定代理");
        }
        ProvincialAgent agent = provincialAgentMapper.selectById(clinic.getAgentId());
        String contactInfo = agent == null ? null : StrUtil.trim(agent.getContactInfo());
        if (StrUtil.isBlank(contactInfo)) {
            throw new IllegalArgumentException("所属代理未配置联系电话");
        }
        return contactInfo;
    }
 
    private void validateLiveRoomUrl(String liveRoomUrl) {
        if (StrUtil.isBlank(liveRoomUrl)) {
            throw new IllegalArgumentException("直播间地址暂未配置");
        }
        try {
            URI uri = URI.create(liveRoomUrl);
            if (!"https".equalsIgnoreCase(uri.getScheme()) || StrUtil.isBlank(uri.getHost())) {
                throw new IllegalArgumentException("直播间地址必须为有效的HTTPS地址");
            }
        } catch (IllegalArgumentException ex) {
            throw new IllegalArgumentException("直播间地址必须为有效的HTTPS地址", ex);
        }
    }
}