创建会议修正

This commit is contained in:
2025-12-27 19:23:33 +08:00
parent 50df8495c7
commit 750c112eac
12 changed files with 448 additions and 343 deletions

View File

@@ -0,0 +1,122 @@
package org.xyzh.workcase.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @description Jitsi Meet 配置属性类
* @filename JitsiProperties.java
* @author claude
* @copyright xyzh
* @since 2025-12-27
*/
@Configuration
@ConfigurationProperties(prefix = "jitsi")
public class JitsiProperties {
/**
* 应用配置
*/
private App app = new App();
/**
* 服务器配置
*/
private Server server = new Server();
/**
* Token配置
*/
private Token token = new Token();
public App getApp() {
return app;
}
public void setApp(App app) {
this.app = app;
}
public Server getServer() {
return server;
}
public void setServer(Server server) {
this.server = server;
}
public Token getToken() {
return token;
}
public void setToken(Token token) {
this.token = token;
}
/**
* 应用配置
*/
public static class App {
/**
* 应用ID必须与Docker配置中的JWT_APP_ID一致
*/
private String id = "urbanLifeline";
/**
* JWT密钥必须与Docker配置中的JWT_APP_SECRET一致
*/
private String secret = "your-secret-key-change-in-production";
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
}
/**
* 服务器配置
*/
public static class Server {
/**
* Jitsi Meet服务器地址
*/
private String url = "https://meet.jit.si";
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
/**
* Token配置
*/
public static class Token {
/**
* JWT Token有效期毫秒- 默认2小时
*/
private Long expiration = 7200000L;
public Long getExpiration() {
return expiration;
}
public void setExpiration(Long expiration) {
this.expiration = expiration;
}
}
}

View File

@@ -7,8 +7,9 @@ import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.annotation.Autowired;
import org.xyzh.api.workcase.service.JitsiTokenService;
import org.xyzh.workcase.config.JitsiProperties;
import java.util.Date;
import java.util.HashMap;
@@ -25,17 +26,8 @@ import java.util.Map;
public class JitsiTokenServiceImpl implements JitsiTokenService {
private static final Logger logger = LoggerFactory.getLogger(JitsiTokenServiceImpl.class);
@Value("${jitsi.app.id:urbanLifeline}")
private String jitsiAppId;
@Value("${jitsi.app.secret:your-secret-key-change-in-production}")
private String jitsiAppSecret;
@Value("${jitsi.server.url:https://meet.jit.si}")
private String jitsiServerUrl;
@Value("${jitsi.token.expiration:7200000}")
private Long tokenExpiration; // 默认2小时
@Autowired
private JitsiProperties jitsiProperties;
@Override
public String generateJwtToken(String roomName, String userId, String userName, boolean isModerator) {
@@ -44,7 +36,7 @@ public class JitsiTokenServiceImpl implements JitsiTokenService {
try {
long now = System.currentTimeMillis();
long exp = now + tokenExpiration;
long exp = now + jitsiProperties.getToken().getExpiration();
// 构建用户上下文
Map<String, Object> userContext = new HashMap<>();
@@ -56,9 +48,9 @@ public class JitsiTokenServiceImpl implements JitsiTokenService {
Map<String, Object> claims = new HashMap<>();
claims.put("context", Map.of("user", userContext));
claims.put("room", roomName);
claims.put("iss", jitsiAppId);
claims.put("iss", jitsiProperties.getApp().getId());
claims.put("aud", "jitsi");
claims.put("sub", jitsiServerUrl);
claims.put("sub", jitsiProperties.getServer().getUrl());
claims.put("exp", exp / 1000); // 秒级时间戳
claims.put("nbf", now / 1000);
@@ -73,7 +65,7 @@ public class JitsiTokenServiceImpl implements JitsiTokenService {
.setClaims(claims)
.setIssuedAt(new Date(now))
.setExpiration(new Date(exp))
.signWith(SignatureAlgorithm.HS256, jitsiAppSecret.getBytes())
.signWith(SignatureAlgorithm.HS256, jitsiProperties.getApp().getSecret().getBytes())
.compact();
logger.info("JWT Token生成成功: roomName={}", roomName);
@@ -88,7 +80,7 @@ public class JitsiTokenServiceImpl implements JitsiTokenService {
public boolean validateJwtToken(String token) {
try {
Claims claims = Jwts.parser()
.setSigningKey(jitsiAppSecret.getBytes())
.setSigningKey(jitsiProperties.getApp().getSecret().getBytes())
.parseClaimsJws(token)
.getBody();
@@ -106,7 +98,7 @@ public class JitsiTokenServiceImpl implements JitsiTokenService {
logger.info("构建Jitsi iframe URL: roomName={}", roomName);
StringBuilder url = new StringBuilder();
url.append(jitsiServerUrl).append("/").append(roomName);
url.append(jitsiProperties.getServer().getUrl()).append("/").append(roomName);
// 添加JWT Token
url.append("?jwt=").append(jwtToken);

View File

@@ -21,6 +21,7 @@ import org.xyzh.common.auth.utils.LoginUtil;
import org.xyzh.common.core.domain.LoginDomain;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.utils.id.IdUtil;
import org.xyzh.workcase.config.JitsiProperties;
import org.xyzh.workcase.mapper.TbChatRoomMemberMapper;
import org.xyzh.workcase.mapper.TbVideoMeetingMapper;
@@ -53,6 +54,9 @@ public class VideoMeetingServiceImpl implements VideoMeetingService {
@Autowired
private ChatRoomService chatRoomService;
@Autowired
private JitsiProperties jitsiProperties;
@DubboReference(version = "1.0.0", group = "auth", timeout = 30000, retries = 0)
private AuthService authService;
@@ -132,7 +136,7 @@ public class VideoMeetingServiceImpl implements VideoMeetingService {
if (meetingDTO.getAdvance() == null) {
meetingDTO.setAdvance(5); // 默认提前5分钟可入会
}
meetingDTO.setJitsiServerUrl(jitsiProperties.getServer().getUrl());
// 6. 插入数据库
int rows = videoMeetingMapper.insertVideoMeeting(meetingDTO);
if (rows > 0) {