创建会议修正
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user