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.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;
|
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 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;
|
|
import java.net.URI;
|
import java.nio.charset.StandardCharsets;
|
|
@Slf4j
|
@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 UserMapper userMapper;
|
private final ClinicMapper clinicMapper;
|
private final ProvincialAgentMapper provincialAgentMapper;
|
private final AppAuthSessionService appAuthSessionService;
|
|
public AppVzanLiveEntryService(LiveRoomSettingService liveRoomSettingService,
|
UserMapper userMapper,
|
ClinicMapper clinicMapper,
|
ProvincialAgentMapper provincialAgentMapper,
|
AppAuthSessionService appAuthSessionService) {
|
this.liveRoomSettingService = liveRoomSettingService;
|
this.userMapper = userMapper;
|
this.clinicMapper = clinicMapper;
|
this.provincialAgentMapper = provincialAgentMapper;
|
this.appAuthSessionService = appAuthSessionService;
|
}
|
|
public AppVzanLiveEntryVO createEntry(Long userId) {
|
// APP 发版完成后改为从登录会话获取用户ID,避免客户端指定其他用户。
|
// Long userId = appAuthSessionService.getLoginUserId();
|
LiveRoomSettingVO setting = liveRoomSettingService.current();
|
String liveRoomUrl = setting == null ? null : StrUtil.trim(setting.getLiveRoomUrl());
|
validateLiveRoomUrl(liveRoomUrl);
|
|
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() + 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);
|
String entryUrl = UriComponentsBuilder.fromHttpUrl(liveRoomUrl)
|
.replaceQueryParam("data", encryptedData)
|
.build()
|
.encode(StandardCharsets.UTF_8)
|
.toUriString();
|
log.info("微赞直播生成URL: {}", entryUrl);
|
return new AppVzanLiveEntryVO(entryUrl, VZAN_WEB_PAY_UA);
|
}
|
|
private String resolveFollowPhone(Long clinicId) {
|
if (clinicId == null) {
|
throw new IllegalArgumentException("当前用户未绑定诊所");
|
}
|
Clinic clinic = clinicMapper.selectById(clinicId);
|
if (clinic == null) {
|
throw new IllegalArgumentException("当前诊所未绑定代理");
|
}
|
|
String contactInfo = StrUtil.trim(clinic.getContactPhone());
|
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);
|
}
|
}
|
|
/**
|
* 校验用户存在且可用。
|
*/
|
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 : "";
|
}
|
}
|