hejianhao
2026-09-01 08d06e795133e5e9b9a02aa5fa9b6ff12013d9a7
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/home/service/AppVzanLiveEntryService.java
@@ -7,6 +7,7 @@
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.auth.service.AppAuthSessionService;
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;
@@ -14,6 +15,8 @@
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 com.tcm.training.admin.member.entity.AppUser;
import com.tcm.training.admin.member.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;
@@ -25,35 +28,45 @@
@Service
public class AppVzanLiveEntryService {
    private static final String VZAN_AUTH_SECRET = "2b4fefe91d8cba50";
    private static final String VZAN_WEB_PAY_UA = "webchatPay/wx074c1f0cf5a0ecf4 InAppPay";
    private static final int USER_STATUS_ENABLED = 1;
    private final LiveRoomSettingService liveRoomSettingService;
    private final AppUserCenterService appUserCenterService;
    private final UserMapper userMapper;
    private final ClinicMapper clinicMapper;
    private final ProvincialAgentMapper provincialAgentMapper;
    private final AppAuthSessionService appAuthSessionService;
    public AppVzanLiveEntryService(LiveRoomSettingService liveRoomSettingService,
                                   AppUserCenterService appUserCenterService,
                                   UserMapper userMapper,
                                   ClinicMapper clinicMapper,
                                   ProvincialAgentMapper provincialAgentMapper) {
                                   ProvincialAgentMapper provincialAgentMapper,
                                   AppAuthSessionService appAuthSessionService) {
        this.liveRoomSettingService = liveRoomSettingService;
        this.appUserCenterService = appUserCenterService;
        this.userMapper = userMapper;
        this.clinicMapper = clinicMapper;
        this.provincialAgentMapper = provincialAgentMapper;
        this.appAuthSessionService = appAuthSessionService;
    }
    public AppVzanLiveEntryVO createEntry() {
    public AppVzanLiveEntryVO createEntry(Long userId) {
        Long sessionUserId = appAuthSessionService.getLoginUserId();
        log.info("微赞直播入口userId对比,请求体userId={},会话userId={},是否一致={}",
                userId, sessionUserId, java.util.Objects.equals(userId, sessionUserId));
        LiveRoomSettingVO setting = liveRoomSettingService.current();
        String liveRoomUrl = setting == null ? null : StrUtil.trim(setting.getLiveRoomUrl());
        validateLiveRoomUrl(liveRoomUrl);
        AppUserCenterVO user = appUserCenterService.getCurrentUserCenter();
        AppUser user = requireEnabledUser(userId);
        String followPhone = resolveFollowPhone(user.getClinicId());
        String avatar = resolveAvatar(user);
        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"));
        payload.set("third_ts", System.currentTimeMillis() + 5000);
        payload.set("avatar", StrUtil.trim(avatar));
        log.info("微赞入口参数已生成,{}", JSONUtil.toJsonStr(payload));
        SymmetricCrypto sm4 = SmUtil.sm4(VZAN_AUTH_SECRET.getBytes(StandardCharsets.UTF_8));
        String encryptedData = sm4.encryptBase64(payload.toString(), StandardCharsets.UTF_8);
@@ -63,7 +76,7 @@
                .encode(StandardCharsets.UTF_8)
                .toUriString();
        log.info("微赞直播生成URL: {}", entryUrl);
        return new AppVzanLiveEntryVO(entryUrl);
        return new AppVzanLiveEntryVO(entryUrl, VZAN_WEB_PAY_UA);
    }
    private String resolveFollowPhone(Long clinicId) {
@@ -71,11 +84,11 @@
            throw new IllegalArgumentException("当前用户未绑定诊所");
        }
        Clinic clinic = clinicMapper.selectById(clinicId);
        if (clinic == null || clinic.getAgentId() == null) {
        if (clinic == null) {
            throw new IllegalArgumentException("当前诊所未绑定代理");
        }
        ProvincialAgent agent = provincialAgentMapper.selectById(clinic.getAgentId());
        String contactInfo = agent == null ? null : StrUtil.trim(agent.getContactInfo());
        String contactInfo = StrUtil.trim(clinic.getContactPhone());
        if (StrUtil.isBlank(contactInfo)) {
            throw new IllegalArgumentException("所属代理未配置联系电话");
        }
@@ -95,4 +108,30 @@
            throw new IllegalArgumentException("直播间地址必须为有效的HTTPS地址", ex);
        }
    }
}
    /**
     * 校验用户存在且可用。
     */
    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;
    }
    /**
     * 优先使用本地头像,没有时回退微信头像。
     */
    private String resolveAvatar(AppUser user) {
        String avatar = user == null ? null : StrUtil.trim(user.getAvatar());
        if (StrUtil.isNotBlank(avatar)) {
            return avatar;
        }
        String wechatAvatar = user == null ? null : StrUtil.trim(user.getWechatAvatar());
        return StrUtil.isNotBlank(wechatAvatar) ? wechatAvatar : "";
    }
}