mirror of
https://github.com/tl-open-source/tl-rtc-file.git
synced 2025-09-26 19:41:16 +08:00
feat: email subscribe
feat: content copy feat: localnetroom perf feat: user table add flag field feat: language perf feat: token api resopnse perf feat: icon perf feat: doc update
This commit is contained in:
1
doc/gitbook/FEATURE_LIST.md
Normal file
1
doc/gitbook/FEATURE_LIST.md
Normal file
@@ -0,0 +1 @@
|
||||
# 待完善补充...
|
@@ -40,6 +40,10 @@ chatgpt聊天框的对话上下文的简单处理。
|
||||
|
||||
开启设置后,你创建的房间,同一个局域网用户进入网页后将看到你创建的房间。
|
||||
|
||||
### 系统通知 (开发中) 【此设置刷新网页后有效,长久保存】
|
||||
|
||||
开启设置后,当收到消息或者提示时,会使用浏览器自带的桌面消息提示,进行及时的音效,横幅提示
|
||||
|
||||
### 文件分片传输大小 【此开关刷新网页后失效,需重新设置】
|
||||
|
||||
由于网站的文件传输是分片传输,但是由于webrtc的数据传输通道有限制,所以项目提供了一个合理范围的可选项,用于自定义控制每次webrtc的数据通道发送数据时的分片大小。默认是 16KB,最大可调整到64KB(不同浏览器实现可能不同,16~64是我认为比较合适的可选范围)
|
||||
|
@@ -22,50 +22,150 @@
|
||||
|
||||
* [配置简要说明](ENV_SETTING.md)
|
||||
|
||||
* [主要功能](FEATURE_LIST.md)
|
||||
|
||||
* [发送文字](FEATURE_LIST.md)
|
||||
|
||||
* [公共聊天](FEATURE_LIST.md)
|
||||
|
||||
* [群聊](FEATURE_LIST.md)
|
||||
|
||||
* [私聊](FEATURE_LIST.md)
|
||||
|
||||
* [文字复制](FEATURE_LIST.md)
|
||||
|
||||
* [富文本](FEATURE_LIST.md)
|
||||
|
||||
* [图片](FEATURE_LIST.md)
|
||||
|
||||
* [表情](FEATURE_LIST.md)
|
||||
|
||||
* [发送文件](FEATURE_LIST.md)
|
||||
|
||||
* [群发](FEATURE_LIST.md)
|
||||
|
||||
* [私发](FEATURE_LIST.md)
|
||||
|
||||
* [排队发](FEATURE_LIST.md)
|
||||
|
||||
* [同时发](FEATURE_LIST.md)
|
||||
|
||||
* [多文件拖拽](FEATURE_LIST.md)
|
||||
|
||||
* [indexedDb存储](FEATURE_LIST.md)
|
||||
|
||||
* [在线文件预览](FEATURE_LIST.md)
|
||||
|
||||
* [文件暂存](FEATURE_LIST.md)
|
||||
|
||||
* [自定义文件分片大小](FEATURE_LIST.md)
|
||||
|
||||
* [自定义文件预览大小](FEATURE_LIST.md)
|
||||
|
||||
* [屏幕共享](FEATURE_LIST.md)
|
||||
|
||||
* [多人共享](FEATURE_LIST.md)
|
||||
|
||||
* [屏幕开关](FEATURE_LIST.md)
|
||||
|
||||
* [音频开关](FEATURE_LIST.md)
|
||||
|
||||
* [视频通话](FEATURE_LIST.md)
|
||||
|
||||
* [多人视频](FEATURE_LIST.md)
|
||||
|
||||
* [视频开关](FEATURE_LIST.md)
|
||||
|
||||
* [摄像头切换](FEATURE_LIST.md)
|
||||
|
||||
* [音频开关](FEATURE_LIST.md)
|
||||
|
||||
* [开始直播](FEATURE_LIST.md)
|
||||
|
||||
* [视频直播](FEATURE_LIST.md)
|
||||
|
||||
* [屏幕直播](FEATURE_LIST.md)
|
||||
|
||||
* [视频开关](FEATURE_LIST.md)
|
||||
|
||||
* [摄像头切换](FEATURE_LIST.md)
|
||||
|
||||
* [音频开关](FEATURE_LIST.md)
|
||||
|
||||
* [开播端](FEATURE_LIST.md)
|
||||
|
||||
* [观众端](FEATURE_LIST.md)
|
||||
|
||||
* [语音连麦](FEATURE_LIST.md)
|
||||
|
||||
* [音频开关](FEATURE_LIST.md)
|
||||
|
||||
* [取件号码](FEATURE_LIST.md)
|
||||
|
||||
* [文件下载](FEATURE_LIST.md)
|
||||
|
||||
* [远程画笔](FEATURE_LIST.md)
|
||||
|
||||
* [多人画笔同步](FEATURE_LIST.md)
|
||||
|
||||
* [密码房间](FEATURE_LIST.md)
|
||||
|
||||
* [自定义密码](FEATURE_LIST.md)
|
||||
|
||||
* [屏幕录制](FEATURE_LIST.md)
|
||||
|
||||
* [录制文件下载](FEATURE_LIST.md)
|
||||
|
||||
* [chatGPT](FEATURE_LIST.md)
|
||||
|
||||
* [次要功能](FEATURE_LIST.md)
|
||||
|
||||
* [多语言版本](FEATURE_LIST.md)
|
||||
|
||||
* [微信扫码登录](FEATURE_LIST.md)
|
||||
|
||||
* [分享房间](FEATURE_LIST.md)
|
||||
|
||||
* [网站通知](FEATURE_LIST.md)
|
||||
|
||||
* [日志记录](FEATURE_LIST.md)
|
||||
|
||||
* [自定义日志数量限制](FEATURE_LIST.md)
|
||||
|
||||
* [中继设置](FEATURE_LIST.md)
|
||||
|
||||
* [自定义昵称](FEATURE_LIST.md)
|
||||
|
||||
* [在线人数统计](FEATURE_LIST.md)
|
||||
|
||||
* [消息红点开关](FEATURE_LIST.md)
|
||||
|
||||
* [固定房间号](FEATURE_LIST.md)
|
||||
|
||||
* [局域网房间扫描](FEATURE_LIST.md)
|
||||
|
||||
* [自定义socket地址](FEATURE_LIST.md)
|
||||
|
||||
* [后台管理统计](FEATURE_LIST.md)
|
||||
|
||||
* [后台开关设置](FEATURE_LIST.md)
|
||||
|
||||
* [敏感词过滤](FEATURE_LIST.md)
|
||||
|
||||
* [心跳检测](FEATURE_LIST.md)
|
||||
|
||||
* [webrtc连接展示](FEATURE_LIST.md)
|
||||
|
||||
|
||||
|
||||
* [tl-rtc-file-开发手册](README_DEV.md)
|
||||
|
||||
* [设计简介](dev/INTRO.md)
|
||||
|
||||
* [客户端](dev/client/CLIENT.md)
|
||||
|
||||
* [文字聊天](dev/client/CHAT.md)
|
||||
|
||||
* [文件传输](dev/client/FILE.md)
|
||||
|
||||
* [多人音视频](dev/client/VIDEO.md)
|
||||
|
||||
* [多人屏幕共享](dev/client/SCREEN.md)
|
||||
|
||||
* [单人直播](dev/client/LIVE.md)
|
||||
|
||||
* [多人语音](dev/client/AUDIO.md)
|
||||
|
||||
* [文件暂存/取件码](dev/client/FILE_CODE.md)
|
||||
|
||||
* [多人画笔](dev/client/DRAW.md)
|
||||
|
||||
* [屏幕录制](dev/client/RECODE.md)
|
||||
* [客户端](dev/CLIENT.md)
|
||||
|
||||
* [服务端](dev/SVR.md)
|
||||
|
||||
* [文字聊天](dev/svr/CHAT.md)
|
||||
|
||||
* [文件传输](dev/svr/FILE.md)
|
||||
|
||||
* [多人音视频](dev/svr/VIDEO.md)
|
||||
|
||||
* [多人屏幕共享](dev/svr/SCREEN.md)
|
||||
|
||||
* [单人直播](dev/svr/LIVE.md)
|
||||
|
||||
* [多人语音](dev/svr/AUDIO.md)
|
||||
|
||||
* [文件暂存/取件码](dev/svr/FILE_CODE.md)
|
||||
|
||||
* [多人画笔](dev/svr/DRAW.md)
|
||||
|
||||
* [屏幕录制](dev/svr/RECODE.md)
|
||||
|
||||
* [tl-rtc-file-设置选项说明](SETTING.md)
|
||||
|
||||
* [tl-rtc-file-常见问题列表](FAQ.md)
|
||||
|
@@ -1 +1,2 @@
|
||||
# 项目设计简介
|
||||
# 项目简介
|
||||
|
||||
|
@@ -1 +0,0 @@
|
||||
# 多人语音
|
@@ -1 +0,0 @@
|
||||
# 文字聊天
|
@@ -1 +0,0 @@
|
||||
# 多人画笔
|
@@ -1 +0,0 @@
|
||||
# 文件传输
|
@@ -1 +0,0 @@
|
||||
# 文件暂存/取件码
|
@@ -1 +0,0 @@
|
||||
# 单人直播
|
@@ -1 +0,0 @@
|
||||
# 屏幕录制
|
@@ -1 +0,0 @@
|
||||
# 多人屏幕共享
|
@@ -1 +0,0 @@
|
||||
# 多人音视频
|
@@ -1 +0,0 @@
|
||||
# 多人语音
|
@@ -1 +0,0 @@
|
||||
# 文字聊天
|
@@ -1 +0,0 @@
|
||||
# 多人画笔
|
@@ -1 +0,0 @@
|
||||
# 文件传输
|
@@ -1 +0,0 @@
|
||||
# 文件暂存/取件码
|
@@ -1 +0,0 @@
|
||||
# 单人直播
|
@@ -1 +0,0 @@
|
||||
# 屏幕录制
|
@@ -1 +0,0 @@
|
||||
# 多人屏幕共享
|
@@ -1 +0,0 @@
|
||||
# 多人音视频
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "10.5.0",
|
||||
"version": "10.5.1",
|
||||
"socket": {
|
||||
"port": "请到 tlrtcfile.env 中进行配置",
|
||||
"host": "请到 tlrtcfile.env 中进行配置"
|
||||
|
@@ -5,6 +5,7 @@ const bussinessNotify = require("./../../bussiness/notify/notifyHandler")
|
||||
const wxapi = require("./../../bussiness/wxapi/wxapi")
|
||||
const { CookieKey } = require("./../../bussiness/cache/key")
|
||||
const scanCache = require("./../../bussiness/cache/scan/scanCache")
|
||||
const utils = require("../../utils/utils");
|
||||
const uuid = require("uuid")
|
||||
|
||||
// 扫码状态
|
||||
@@ -39,13 +40,14 @@ async function loginWechat(req, res) {
|
||||
|
||||
const { session_key, openid, unionid } = openIdInfo;
|
||||
|
||||
const userId = await user.addWxUser({
|
||||
const { userId, flag } = await user.addWxUser({
|
||||
openid: openid,
|
||||
avatar: userInfo.avatarUrl,
|
||||
uname: userInfo.nickName,
|
||||
pwd: '',
|
||||
solt: '',
|
||||
role: 'user',
|
||||
flag : 0,
|
||||
}, tables, dbClient);
|
||||
|
||||
//设置登录信息缓存
|
||||
@@ -55,6 +57,7 @@ async function loginWechat(req, res) {
|
||||
userId : userId,
|
||||
avatar : userInfo.avatarUrl,
|
||||
nickName : userInfo.nickName,
|
||||
flag : flag,
|
||||
loginTime : Date.now(),
|
||||
});
|
||||
|
||||
@@ -226,10 +229,15 @@ async function getTokenState(req, res){
|
||||
const loginInfo = scanCache.getLoginInfo(token);
|
||||
|
||||
const avatar = loginInfo.avatar || "/image/44826979.png";
|
||||
const username = loginInfo.nickName || "";
|
||||
const username = loginInfo.nickName || " -- ";
|
||||
const flag = loginInfo.flag || 0;
|
||||
const subscribeNotify = utils.checkBit(flag, req.ctx.tables.UserOther.Flag.IS_SUBSCRIBE_WEBSITE_NOTIFY)
|
||||
|
||||
if(Object.keys(loginInfo).length > 0){
|
||||
res.json({ code: 200, login: true, token, avatar, username });
|
||||
res.json({
|
||||
code: 200, login: true, loginInfo,
|
||||
token, avatar, username, subscribeNotify
|
||||
});
|
||||
}else{
|
||||
res.json({ code: 200, login: false });
|
||||
}
|
||||
@@ -276,7 +284,10 @@ async function getLoginInfo(req, res){
|
||||
|
||||
const loginInfo = scanCache.getLoginInfo(token);
|
||||
|
||||
res.json({ code: 200, userId : loginInfo.userId });
|
||||
res.json({ code: 200, userInfo :{
|
||||
userId : loginInfo.userId,
|
||||
flag : loginInfo.flag,
|
||||
}});
|
||||
}
|
||||
|
||||
|
||||
|
@@ -39,14 +39,14 @@ async function addWxUser(params, tables, dbClient) {
|
||||
role: params.role,
|
||||
});
|
||||
|
||||
return data && data.dataValues ? data.dataValues.id : 0;
|
||||
return data && data.dataValues ? dataValues : { id : 0 };
|
||||
}
|
||||
|
||||
if(users && users.length === 1){
|
||||
return users[0].dataValues.id;
|
||||
return users[0].dataValues;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return { id : 0 };
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
return {};
|
||||
@@ -54,11 +54,46 @@ async function addWxUser(params, tables, dbClient) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新用户标识
|
||||
* @param {*} params
|
||||
* @param {*} tables
|
||||
* @param {*} dbClient
|
||||
*/
|
||||
async function updateUserFlag(params, tables, dbClient){
|
||||
if(!tables || !dbClient){
|
||||
return {};
|
||||
}
|
||||
|
||||
if(!params){
|
||||
params = {};
|
||||
}
|
||||
|
||||
if(!params.id){
|
||||
return {};
|
||||
}
|
||||
|
||||
let data = await tables.User.update({
|
||||
flag: params.flag,
|
||||
}, {
|
||||
where: {
|
||||
id: params.id
|
||||
}
|
||||
});
|
||||
|
||||
utils.tlConsole("更新用户标识 : ", params, data)
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
module.exports = dbOpen ? {
|
||||
addWxUser
|
||||
addWxUser, updateUserFlag
|
||||
} : {
|
||||
addWxUser : function(){
|
||||
return {}
|
||||
},
|
||||
updateUserFlag : function(){
|
||||
return {}
|
||||
}
|
||||
}
|
@@ -20,6 +20,7 @@ const rtcHeartbeat = require("./rtcHeartbeat/heartbeat");
|
||||
const rtcAddCodeFile = require("./rtcCodeFile/addCodeFile");
|
||||
const rtcGetCodeFile = require("./rtcCodeFile/getCodeFile");
|
||||
const rtcLocalNetRoom = require("./rtcLocalNetRoom/localNetRoom");
|
||||
const rtcSubscribe = require("./rtcSubscribe/subscribe");
|
||||
const rtcServerEvent = require("./rtcConstant").rtcServerEvent
|
||||
const rtcToken = require("./rtcToken/token")
|
||||
|
||||
@@ -32,11 +33,6 @@ module.exports = (io, socket, tables, dbClient) => {
|
||||
// 在线人数统计
|
||||
rtcCount.count(io, socket, tables, dbClient, {})
|
||||
|
||||
// 局域网房间发现列表
|
||||
rtcLocalNetRoom.localNetRoom(io, socket, tables, dbClient, {
|
||||
toCurrentSocket : true
|
||||
})
|
||||
|
||||
// 断开连接
|
||||
socket.on(rtcServerEvent.disconnect, (data)=>{
|
||||
rtcDisConnect.disconnect(io, socket, tables, dbClient, data)
|
||||
@@ -141,4 +137,14 @@ module.exports = (io, socket, tables, dbClient) => {
|
||||
socket.on(rtcServerEvent.changeNickName, (data) => {
|
||||
rtcChangeNickName.changeNickName(io, socket, tables, dbClient, data)
|
||||
});
|
||||
|
||||
// 订阅网站通知
|
||||
socket.on(rtcServerEvent.subscribeNofity, (data) => {
|
||||
rtcSubscribe.subscribeNofity(io, socket, tables, dbClient, data)
|
||||
});
|
||||
|
||||
// 局域网房间发现列表
|
||||
socket.on(rtcServerEvent.localNetRoom, (data)=>{
|
||||
rtcLocalNetRoom.localNetRoomForConnect(io, socket, tables, dbClient, data)
|
||||
});
|
||||
}
|
@@ -48,6 +48,10 @@ const rtcServerEvent = {
|
||||
heartbeat : "heartbeat",
|
||||
//修改昵称
|
||||
changeNickName : "changeNickName",
|
||||
//订阅网站通知
|
||||
subscribeNofity : "subscribeNofity",
|
||||
//局域网房间发现列表
|
||||
localNetRoom : "localNetRoom",
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +88,7 @@ let rtcServerMessageEvent = {
|
||||
//开始远程画笔
|
||||
startRemoteDraw : "startRemoteDraw",
|
||||
//结束远程画笔
|
||||
stopRemoteDraw : "stopRemoteDraw",
|
||||
stopRemoteDraw : "stopRemoteDraw"
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,6 +138,8 @@ let rtcClientEvent = {
|
||||
changeNickName : "changeNickName",
|
||||
//局域网房间发现列表
|
||||
localNetRoom : "localNetRoom",
|
||||
//订阅网站通知
|
||||
subscribeNofity : "subscribeNofity"
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,7 +1,6 @@
|
||||
const rtcConstant = require("../rtcConstant");
|
||||
const rtcClientEvent = rtcConstant.rtcClientEvent
|
||||
const utils = require("../../../src/utils/utils");
|
||||
const rtcLocalNetRoom = require("../rtcLocalNetRoom/localNetRoom");
|
||||
|
||||
/**
|
||||
* 在线人数统计广播
|
||||
@@ -18,11 +17,6 @@ async function count(io, socket, tables, dbClient, data){
|
||||
io.sockets.emit(rtcClientEvent.count, {
|
||||
mc : allManCount
|
||||
})
|
||||
|
||||
rtcLocalNetRoom.localNetRoom(io, socket, tables, dbClient, {
|
||||
toAll : true
|
||||
});
|
||||
|
||||
}catch(e){
|
||||
utils.tlConsole(e)
|
||||
}
|
||||
|
@@ -21,12 +21,12 @@ const rtcLocalNetRoom = require("../rtcLocalNetRoom/localNetRoom");
|
||||
* @returns
|
||||
*/
|
||||
async function userCreateAndJoin(io, socket, tables, dbClient, data){
|
||||
let {handshake, userAgent, ip, address} = utils.getSocketClientInfo(socket);
|
||||
let { handshake, userAgent, ip, address } = utils.getSocketClientInfo(socket);
|
||||
|
||||
let {
|
||||
room = '', type = 'file', nickName = '', password = '',
|
||||
langMode = 'zh', ua = '', network = '', liveShareRole = '',
|
||||
localNetRoom = false
|
||||
localNetRoom = false, ips = []
|
||||
} = data;
|
||||
|
||||
if (room && room.length > 15) {
|
||||
@@ -66,7 +66,7 @@ async function userCreateAndJoin(io, socket, tables, dbClient, data){
|
||||
io.sockets.connected[socket.id].langMode = langMode;
|
||||
io.sockets.connected[socket.id].ua = ua;
|
||||
io.sockets.connected[socket.id].network = network;
|
||||
io.sockets.connected[socket.id].ip = ip;
|
||||
io.sockets.connected[socket.id].ips = ips;
|
||||
const joinTime = utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")
|
||||
io.sockets.connected[socket.id].joinTime = joinTime;
|
||||
io.sockets.connected[socket.id].userAgent = userAgent;
|
||||
@@ -120,26 +120,25 @@ async function userCreateAndJoin(io, socket, tables, dbClient, data){
|
||||
});
|
||||
//设置为房主
|
||||
io.sockets.connected[socket.id].owner = true;
|
||||
io.sockets.adapter.rooms[room].owner = socket.id;
|
||||
|
||||
//设置房主ip为房间号ip, address
|
||||
io.sockets.adapter.rooms[room].ip = ip;
|
||||
io.sockets.adapter.rooms[room].address = address;
|
||||
|
||||
//房间是否可以被局域网发现
|
||||
io.sockets.adapter.rooms[room].localNetRoom = localNetRoom;
|
||||
if(localNetRoom){
|
||||
rtcLocalNetRoom.localNetRoom(io, socket, tables, dbClient, {
|
||||
toAll : true
|
||||
});
|
||||
}
|
||||
//设置房主上报的ip为房间号ip
|
||||
io.sockets.adapter.rooms[room].ips = ips;
|
||||
|
||||
//设置房间类型
|
||||
io.sockets.adapter.rooms[room].type = type;
|
||||
|
||||
//房间是否可以被局域网发现
|
||||
io.sockets.adapter.rooms[room].localNetRoom = localNetRoom;
|
||||
|
||||
//密码房间设置密码
|
||||
if(type === 'password'){
|
||||
io.sockets.adapter.rooms[room].password = password
|
||||
}
|
||||
|
||||
//房间创建时间
|
||||
io.sockets.adapter.rooms[room].createTime = utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss");
|
||||
|
||||
}else {
|
||||
//加入时,房间类型不匹配,提示并退出
|
||||
const createdRoomType = io.sockets.adapter.rooms[room].type;
|
||||
@@ -244,9 +243,11 @@ async function userCreateAndJoin(io, socket, tables, dbClient, data){
|
||||
});
|
||||
}
|
||||
|
||||
//人数变更通知
|
||||
rtcCount.count(io, socket, tables, dbClient, data);
|
||||
|
||||
io.sockets.adapter.rooms[room].createTime = utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")
|
||||
//局域网房间变动通知
|
||||
rtcLocalNetRoom.localNetRoomForJoin(io, socket, tables, dbClient, { room });
|
||||
|
||||
if(password && password.length > 0){
|
||||
bussinessNotify.sendCreateJoinPasswordRoomNotify({
|
||||
|
@@ -1,7 +1,8 @@
|
||||
const daoRoom = require("./../../dao/room/room")
|
||||
const rtcCount = require("./../rtcCount/count");
|
||||
const rtcConstant = require("../rtcConstant");
|
||||
const rtcClientEvent = rtcConstant.rtcClientEvent
|
||||
const rtcClientEvent = rtcConstant.rtcClientEvent;
|
||||
const rtcLocalNetRoom = require("../rtcLocalNetRoom/localNetRoom");
|
||||
|
||||
/**
|
||||
* 断开连接的操作
|
||||
@@ -18,7 +19,7 @@ async function disconnect(io, socket, tables, dbClient, data){
|
||||
|
||||
await daoRoom.exitRoomBySid({ socket_id: socket.id }, tables, dbClient);
|
||||
|
||||
rtcCount.count(io, socket, tables, dbClient, data)
|
||||
rtcCount.count(io, socket, tables, dbClient, data);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
@@ -3,8 +3,8 @@ const bussinessNotify = require("./../../bussiness/notify/notifyHandler")
|
||||
const rtcCount = require("./../rtcCount/count");
|
||||
const utils = require("./../../utils/utils");
|
||||
const rtcConstant = require("../rtcConstant");
|
||||
const rtcClientEvent = rtcConstant.rtcClientEvent
|
||||
|
||||
const rtcClientEvent = rtcConstant.rtcClientEvent;
|
||||
const rtcLocalNetRoom = require("../rtcLocalNetRoom/localNetRoom");
|
||||
|
||||
/**
|
||||
* 退出房间
|
||||
@@ -48,6 +48,9 @@ async function exit(io, socket, tables, dbClient, data){
|
||||
|
||||
rtcCount.count(io, socket, tables, dbClient, data);
|
||||
|
||||
//局域网房间变动通知
|
||||
rtcLocalNetRoom.localNetRoomForExit(io, socket, tables, dbClient, { room });
|
||||
|
||||
} catch (e) {
|
||||
socket.emit(rtcClientEvent.tips, {
|
||||
room: data.room,
|
||||
|
@@ -2,134 +2,46 @@ const rtcConstant = require("../rtcConstant");
|
||||
const rtcClientEvent = rtcConstant.rtcClientEvent
|
||||
const bussinessNotify = require("../../bussiness/notify/notifyHandler")
|
||||
const utils = require("../../../src/utils/utils");
|
||||
const os = require('os');
|
||||
|
||||
/**
|
||||
* 局域网房间发现列表
|
||||
*
|
||||
* @param {*} io socketio对象
|
||||
* @param {*} socket 单个socket连接
|
||||
* @param {*} tables 数据表对象
|
||||
* @param {*} dbClient sequelize-orm对象
|
||||
* @param {*} data event参数
|
||||
* 服务器网络列表
|
||||
*/
|
||||
let serverNetworkList = null;
|
||||
(() => {
|
||||
if (!serverNetworkList) {
|
||||
serverNetworkList = [];
|
||||
let ifaces = os.networkInterfaces();
|
||||
for (let iface in ifaces) {
|
||||
for (let i = 0, len = ifaces[iface].length; i < len; ++i) {
|
||||
const item = ifaces[iface][i];
|
||||
if (item.family === 'IPv4') {
|
||||
serverNetworkList.push(ifaces[iface][i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
console.log(serverNetworkList)
|
||||
|
||||
|
||||
/**
|
||||
* 通过ip获取子网掩码
|
||||
* @param {*} ip
|
||||
* @returns
|
||||
*/
|
||||
async function localNetRoom(io, socket, tables, dbClient, data){
|
||||
try{
|
||||
const { toCurrentSocket = false, toAll = false } = data;
|
||||
|
||||
let { ip, address } = utils.getSocketClientInfo(socket);
|
||||
|
||||
let roomList = [];
|
||||
let rooms = io.sockets.adapter.rooms;
|
||||
|
||||
for(let roomId in rooms){
|
||||
if(roomId.length > 15){
|
||||
continue;
|
||||
}
|
||||
|
||||
//最多返回10个房间
|
||||
if(roomList.length > 10){
|
||||
break;
|
||||
}
|
||||
|
||||
// 是否开启局域网房间
|
||||
const localNetRoom = rooms[roomId].localNetRoom || false;
|
||||
if(!localNetRoom){
|
||||
continue;
|
||||
}
|
||||
|
||||
// 房间ip
|
||||
const roomIp = rooms[roomId].ip || "";
|
||||
// 房间address/ip
|
||||
const roomAddress = rooms[roomId].address || "";
|
||||
|
||||
if(roomIp){
|
||||
// 本地请求
|
||||
if(
|
||||
(roomIp.indexOf("127.0.0.1") > -1 && ip.indexOf("127.0.0.1") > -1)
|
||||
||
|
||||
(roomIp.indexOf("localhost") > -1 && ip.indexOf("localhost") > -1)
|
||||
){
|
||||
roomList = addFilterRoomListData(roomList, {
|
||||
room : roomId,
|
||||
type : 'file',
|
||||
ips : [roomIp],
|
||||
count : rooms[roomId].length
|
||||
})
|
||||
}else{
|
||||
// 在同一个网段
|
||||
if(utils.isSameSubnet(roomIp, ip, "255.255.255.255")){
|
||||
roomList = addFilterRoomListData(roomList, {
|
||||
room : roomId,
|
||||
type : 'file',
|
||||
ips : [roomIp],
|
||||
count : rooms[roomId].length
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(roomAddress){
|
||||
// 本地请求
|
||||
if(
|
||||
(roomAddress.indexOf("127.0.0.1") > -1 && address.indexOf("127.0.0.1") > -1)
|
||||
||
|
||||
(roomAddress.indexOf("localhost") > -1 && address.indexOf("localhost") > -1)
|
||||
){
|
||||
roomList = addFilterRoomListData(roomList, {
|
||||
room : roomId,
|
||||
type : 'file',
|
||||
ips : [roomAddress],
|
||||
count : rooms[roomId].length
|
||||
})
|
||||
}else{
|
||||
// 在同一个网段
|
||||
if(utils.isSameSubnet(roomAddress, address, "255.255.255.255")){
|
||||
roomList = addFilterRoomListData(roomList, {
|
||||
room : roomId,
|
||||
type : 'file',
|
||||
ips : [roomAddress],
|
||||
count : rooms[roomId].length
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
roomList.map(item=>{
|
||||
item.room = item.room.toString().substring(0,1) + "***";
|
||||
})
|
||||
|
||||
// 通知当前用户
|
||||
if(toCurrentSocket){
|
||||
socket.emit(rtcClientEvent.localNetRoom, {
|
||||
list : roomList
|
||||
})
|
||||
}
|
||||
|
||||
// 通知全部用户
|
||||
if(toAll){
|
||||
io.sockets.emit(rtcClientEvent.localNetRoom, {
|
||||
list : roomList
|
||||
});
|
||||
}
|
||||
|
||||
}catch(e){
|
||||
utils.tlConsole(e)
|
||||
bussinessNotify.sendSystemErrorMsg({
|
||||
title: "socket-localNetRoom",
|
||||
data: JSON.stringify(data),
|
||||
room: "",
|
||||
from : socket.id,
|
||||
msg : JSON.stringify({
|
||||
message: e.message,
|
||||
fileName: e.fileName,
|
||||
lineNumber: e.lineNumber,
|
||||
stack: e.stack,
|
||||
name: e.name
|
||||
}, null, '\t')
|
||||
})
|
||||
function getNetMaskByIp(ip) {
|
||||
if (!serverNetworkList) {
|
||||
return "255.255.255.255";
|
||||
}
|
||||
const filterList = serverNetworkList.filter(item => {
|
||||
return item.address === ip;
|
||||
})
|
||||
if (!filterList || filterList.length === 0) {
|
||||
return "255.255.255.255";
|
||||
}
|
||||
return filterList[0].netmask;
|
||||
}
|
||||
|
||||
|
||||
@@ -138,15 +50,15 @@ async function localNetRoom(io, socket, tables, dbClient, data){
|
||||
* @param {*} list
|
||||
* @returns
|
||||
*/
|
||||
function addFilterRoomListData(list, obj){
|
||||
function addFilterRoomListData(list, obj) {
|
||||
let exist = list.filter(item => item.room === obj.room).length > 0;
|
||||
if(!exist){
|
||||
if (!exist) {
|
||||
list.push(obj)
|
||||
return list
|
||||
}
|
||||
|
||||
for(let i = 0; i < list.length; i++){
|
||||
if(list[i].room === obj.room){
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
if (list[i].room === obj.room) {
|
||||
let oldIps = list[i].ips;
|
||||
oldIps.push(obj.ips[0])
|
||||
list[i].ips = oldIps;
|
||||
@@ -156,6 +68,245 @@ function addFilterRoomListData(list, obj){
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 局域网房间发现列表
|
||||
* 连接类型广播
|
||||
*
|
||||
* @param {*} io socketio对象
|
||||
* @param {*} socket 单个socket连接
|
||||
* @param {*} tables 数据表对象
|
||||
* @param {*} dbClient sequelize-orm对象
|
||||
* @param {*} data event参数
|
||||
* @returns
|
||||
*/
|
||||
function localNetRoom(io, socket, tables, dbClient, data) {
|
||||
const { ips : currentIps = [] } = data;
|
||||
|
||||
let filterRoomList = [];
|
||||
|
||||
//所有正常的房间列表ip统计
|
||||
let rooms = io.sockets.adapter.rooms;
|
||||
let roomIpsList = [];
|
||||
for (let roomId in rooms) {
|
||||
let roomIps = rooms[roomId].ips;
|
||||
if (
|
||||
roomId.length > 15 || // 非法房间号
|
||||
!rooms[roomId] || // 房间不存在
|
||||
!roomIps || // 房间没有上报ip
|
||||
roomIps.length === 0 || // 房间没有上报ip
|
||||
rooms[roomId].length === 0 || // 房间没有人
|
||||
!rooms[roomId].localNetRoom // 房间没有开启局域网
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//最多处理返回10个局域网房间
|
||||
if (roomIpsList.length > 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
roomIpsList.push(...roomIps.map(item => {
|
||||
item.room = roomId;
|
||||
item.count = rooms[roomId] ? Object.keys(rooms[roomId].sockets).length : 0,
|
||||
item.owner = rooms[roomId].owner;
|
||||
item.roomType = rooms[roomId].type;
|
||||
return item;
|
||||
}))
|
||||
}
|
||||
|
||||
//根据当前socket连接的ip信息,筛选出和ip在同一个局域网的房间列表
|
||||
currentIps.forEach(currentIpInfo => {
|
||||
const { ipType: currentIpType, address: currentAddress } = currentIpInfo;
|
||||
|
||||
roomIpsList.forEach(otherIpInfo => {
|
||||
const { ipType: otherIpType, address: otherAddress, room, count, owner, roomType } = otherIpInfo;
|
||||
|
||||
if (otherIpType === "srflx" && currentIpType === 'srflx') { //公网ip
|
||||
if (utils.isSameSubnet(currentAddress, otherAddress, getNetMaskByIp(currentAddress))) {
|
||||
filterRoomList = addFilterRoomListData(filterRoomList, {
|
||||
room, roomType, count, owner, ips: [otherAddress]
|
||||
})
|
||||
}
|
||||
} else if (otherIpType === 'host' && currentIpType === 'host') { //内网ip
|
||||
if (utils.isSameSubnet(currentAddress, otherAddress, getNetMaskByIp(currentAddress))) {
|
||||
filterRoomList = addFilterRoomListData(filterRoomList, {
|
||||
room, roomType, count, owner, ips: [otherAddress]
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// filterRoomList.map(item => {
|
||||
// item.room = item.room.toString().substring(0, 1) + "***";
|
||||
// })
|
||||
|
||||
return filterRoomList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 局域网房间发现列表
|
||||
* socket用户连接之后广播
|
||||
* @param {*} io socketio对象
|
||||
* @param {*} socket 单个socket连接
|
||||
* @param {*} tables 数据表对象
|
||||
* @param {*} dbClient sequelize-orm对象
|
||||
* @param {*} data event参数
|
||||
* @returns
|
||||
*/
|
||||
function localNetRoomForConnect(io, socket, tables, dbClient, data) {
|
||||
try {
|
||||
let filterRoomList = localNetRoom(io, socket, tables, dbClient, data);
|
||||
|
||||
socket.emit(rtcClientEvent.localNetRoom, {
|
||||
list: filterRoomList,
|
||||
mode : 'connect'
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
utils.tlConsole(e)
|
||||
bussinessNotify.sendSystemErrorMsg({
|
||||
title: "socket-localNetRoomForConnect",
|
||||
data: JSON.stringify(data),
|
||||
room: "",
|
||||
from: socket.id,
|
||||
msg: JSON.stringify({
|
||||
message: e.message,
|
||||
fileName: e.fileName,
|
||||
lineNumber: e.lineNumber,
|
||||
stack: e.stack,
|
||||
name: e.name
|
||||
}, null, '\t')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 局域网房间发现列表
|
||||
* socket用户加入房间之后广播
|
||||
* @param {*} io socketio对象
|
||||
* @param {*} socket 单个socket连接
|
||||
* @param {*} tables 数据表对象
|
||||
* @param {*} dbClient sequelize-orm对象
|
||||
* @param {*} data event参数
|
||||
* @returns
|
||||
*/
|
||||
function localNetRoomForJoin(io, socket, tables, dbClient, data) {
|
||||
try {
|
||||
const { room } = data;
|
||||
const socketRoomInfo = io.sockets.adapter.rooms[room];
|
||||
const ips = socketRoomInfo ? socketRoomInfo.ips : [];
|
||||
const owner = socketRoomInfo ? socketRoomInfo.owner : socket.id;
|
||||
const count = socketRoomInfo ? Object.keys(socketRoomInfo.sockets).length : 0;
|
||||
const roomType = socketRoomInfo ? socketRoomInfo.type : "file";
|
||||
|
||||
io.sockets.emit(rtcClientEvent.localNetRoom, {
|
||||
list : [{ room, roomType, count, owner, ips : ips.map(item => item.address) }],
|
||||
mode : 'join'
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
utils.tlConsole(e)
|
||||
bussinessNotify.sendSystemErrorMsg({
|
||||
title: "socket-localNetRoomForJoin",
|
||||
data: JSON.stringify(data),
|
||||
room: "",
|
||||
from: socket.id,
|
||||
msg: JSON.stringify({
|
||||
message: e.message,
|
||||
fileName: e.fileName,
|
||||
lineNumber: e.lineNumber,
|
||||
stack: e.stack,
|
||||
name: e.name
|
||||
}, null, '\t')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 局域网房间发现列表
|
||||
* socket用户退出房间之后广播
|
||||
* @param {*} io socketio对象
|
||||
* @param {*} socket 单个socket连接
|
||||
* @param {*} tables 数据表对象
|
||||
* @param {*} dbClient sequelize-orm对象
|
||||
* @param {*} data event参数
|
||||
* @returns
|
||||
*/
|
||||
function localNetRoomForExit(io, socket, tables, dbClient, data) {
|
||||
try {
|
||||
const { room } = data;
|
||||
const socketRoomInfo = io.sockets.adapter.rooms[room];
|
||||
const ips = socketRoomInfo ? socketRoomInfo.ips : [];
|
||||
const owner = socketRoomInfo ? socketRoomInfo.owner : socket.id;
|
||||
const count = socketRoomInfo ? Object.keys(socketRoomInfo.sockets).length : 0;
|
||||
const roomType = socketRoomInfo ? socketRoomInfo.type : "file";
|
||||
|
||||
io.sockets.emit(rtcClientEvent.localNetRoom, {
|
||||
list : [{ room, roomType, count, owner, ips: ips.map(item => item.address) }],
|
||||
mode : 'exit'
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
utils.tlConsole(e)
|
||||
bussinessNotify.sendSystemErrorMsg({
|
||||
title: "socket-localNetRoomForExit",
|
||||
data: JSON.stringify(data),
|
||||
room: "",
|
||||
from: socket.id,
|
||||
msg: JSON.stringify({
|
||||
message: e.message,
|
||||
fileName: e.fileName,
|
||||
lineNumber: e.lineNumber,
|
||||
stack: e.stack,
|
||||
name: e.name
|
||||
}, null, '\t')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 局域网房间发现列表
|
||||
* socket用户断开连接之后广播
|
||||
* @param {*} io socketio对象
|
||||
* @param {*} socket 单个socket连接
|
||||
* @param {*} tables 数据表对象
|
||||
* @param {*} dbClient sequelize-orm对象
|
||||
* @param {*} data event参数
|
||||
* @returns
|
||||
*/
|
||||
function localNetRoomForDisconnect(io, socket, tables, dbClient, data) {
|
||||
try {
|
||||
io.sockets.emit(rtcClientEvent.localNetRoom, {
|
||||
list : [{ socketId : socket.id }],
|
||||
mode : 'disconnect'
|
||||
});
|
||||
} catch (e) {
|
||||
utils.tlConsole(e)
|
||||
bussinessNotify.sendSystemErrorMsg({
|
||||
title: "socket-localNetRoomForDisconnect",
|
||||
data: JSON.stringify(data),
|
||||
room: "",
|
||||
from: socket.id,
|
||||
msg: JSON.stringify({
|
||||
message: e.message,
|
||||
fileName: e.fileName,
|
||||
lineNumber: e.lineNumber,
|
||||
stack: e.stack,
|
||||
name: e.name
|
||||
}, null, '\t')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
localNetRoom
|
||||
localNetRoomForConnect, localNetRoomForJoin,
|
||||
localNetRoomForExit, localNetRoomForDisconnect
|
||||
}
|
57
svr/src/socket/rtcSubscribe/subscribe.js
Normal file
57
svr/src/socket/rtcSubscribe/subscribe.js
Normal file
@@ -0,0 +1,57 @@
|
||||
const utils = require("./../../utils/utils");
|
||||
const daoDog = require("./../../dao/dog/dog")
|
||||
const daoUser = require("./../../dao/user/user")
|
||||
const rtcConstant = require("../rtcConstant");
|
||||
const rtcClientEvent = rtcConstant.rtcClientEvent
|
||||
const daoRelation = require("../../dao/relation/relation");
|
||||
|
||||
|
||||
/**
|
||||
* 订阅网站通知
|
||||
* @param {*} io socketio对象
|
||||
* @param {*} socket 单个socket连接
|
||||
* @param {*} tables 数据表对象
|
||||
* @param {*} dbClient sequelize-orm对象
|
||||
* @param {*} data event参数
|
||||
* @returns
|
||||
*/
|
||||
async function subscribeNofity(io, socket, tables, dbClient, data){
|
||||
let { roomId = '', email = '' } = data;
|
||||
|
||||
let { handshake, userAgent, ip } = utils.getSocketClientInfo(socket);
|
||||
|
||||
socket.emit(rtcClientEvent.subscribeNofity, data);
|
||||
|
||||
//控制操作事件入库
|
||||
let recoderId = await daoDog.addDogData({
|
||||
name: "订阅网站通知",
|
||||
roomId: roomId,
|
||||
socketId: socket.id,
|
||||
device: userAgent,
|
||||
flag: 0,
|
||||
content: JSON.stringify(data),
|
||||
handshake: JSON.stringify(handshake),
|
||||
ip: ip
|
||||
}, tables, dbClient);
|
||||
|
||||
//更新用户订阅标识
|
||||
const { userId, flag = 0 } = socket.userInfo;
|
||||
if(userId){
|
||||
await daoUser.updateUserFlag({
|
||||
id : userId,
|
||||
flag : utils.setBit(flag, tables.UserOther.Flag.IS_SUBSCRIBE_WEBSITE_NOTIFY)
|
||||
}, tables, dbClient);
|
||||
}
|
||||
|
||||
//添加用户-操作关联记录
|
||||
if(socket.userId){
|
||||
daoRelation.addUserDogRelation({
|
||||
dogId : recoderId,
|
||||
userId : socket.userId,
|
||||
}, tables, dbClient);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
subscribeNofity
|
||||
}
|
@@ -29,7 +29,7 @@ async function token(io, socket, tables, dbClient, data){
|
||||
"content-type": "application/json",
|
||||
},
|
||||
qs: {
|
||||
token, key : "iamtsm-socket"
|
||||
token, key : cfg.login.token.key
|
||||
},
|
||||
}, (err, res, body) => {
|
||||
if(err){
|
||||
@@ -42,9 +42,9 @@ async function token(io, socket, tables, dbClient, data){
|
||||
return;
|
||||
}
|
||||
|
||||
socket.userId = body.userId;
|
||||
socket.userInfo = body.userInfo;
|
||||
|
||||
utils.tlConsole("同步token信息成功 : ", token, body.userId)
|
||||
utils.tlConsole("同步token信息成功 : ", token, body.userInfo)
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,11 @@
|
||||
// user
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
return {
|
||||
UserOther : {
|
||||
Flag : {
|
||||
IS_SUBSCRIBE_WEBSITE_NOTIFY : 0x1, //是否已订阅网站通知
|
||||
}
|
||||
},
|
||||
User: sequelize.define('user', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
@@ -36,6 +41,11 @@ module.exports = (sequelize, DataTypes) => {
|
||||
role: {
|
||||
type: DataTypes.STRING(15),
|
||||
comment: '用户身份'
|
||||
},
|
||||
flag: {
|
||||
type: DataTypes.INTEGER,
|
||||
comment: '标志位',
|
||||
defaultValue: 0,
|
||||
}
|
||||
}, {
|
||||
timestamps: true,
|
||||
|
@@ -49,7 +49,7 @@ function getLocalIP() {
|
||||
function isSameSubnet(ip1, ip2, subnetMask) {
|
||||
// 将IPv4或IPv6地址和子网掩码转换为数字形式
|
||||
function ipToNumber(ip) {
|
||||
if (ip.includes(':')) { // IPv6
|
||||
if (ip.indexOf(':') > -1) { // IPv6
|
||||
const parts = ip.split(':');
|
||||
return parts.map(part => parseInt(part, 16)).join('');
|
||||
} else { // IPv4
|
||||
@@ -374,6 +374,15 @@ function checkBit(flag, bit){
|
||||
return (flag & bit) === bit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据flag和bit设置对应的值
|
||||
* @param {*} flag
|
||||
* @param {*} bit
|
||||
*/
|
||||
function setBit(flag, bit){
|
||||
return flag | bit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
@@ -392,5 +401,6 @@ module.exports = {
|
||||
unescapeStr,
|
||||
escapeStr,
|
||||
isSameSubnet,
|
||||
checkBit
|
||||
checkBit,
|
||||
setBit
|
||||
}
|
@@ -54,6 +54,24 @@
|
||||
<div class="content unicode" style="display: block;">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">通知</div>
|
||||
<div class="code-name">&#xe635;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">群蜂操作记录</div>
|
||||
<div class="code-name">&#xe702;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">订阅</div>
|
||||
<div class="code-name">&#xe6af;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">置顶</div>
|
||||
@@ -738,9 +756,9 @@
|
||||
<pre><code class="language-css"
|
||||
>@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('iconfont.woff2?t=1698150656017') format('woff2'),
|
||||
url('iconfont.woff?t=1698150656017') format('woff'),
|
||||
url('iconfont.ttf?t=1698150656017') format('truetype');
|
||||
src: url('iconfont.woff2?t=1698825191464') format('woff2'),
|
||||
url('iconfont.woff?t=1698825191464') format('woff'),
|
||||
url('iconfont.ttf?t=1698825191464') format('truetype');
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||
@@ -766,6 +784,33 @@
|
||||
<div class="content font-class">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-rtc-file-tongzhi"></span>
|
||||
<div class="name">
|
||||
通知
|
||||
</div>
|
||||
<div class="code-name">.icon-rtc-file-tongzhi
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-rtc-file-qunfengcaozuojilu"></span>
|
||||
<div class="name">
|
||||
群蜂操作记录
|
||||
</div>
|
||||
<div class="code-name">.icon-rtc-file-qunfengcaozuojilu
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-rtc-file-dingyue"></span>
|
||||
<div class="name">
|
||||
订阅
|
||||
</div>
|
||||
<div class="code-name">.icon-rtc-file-dingyue
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-rtc-file-zhiding"></span>
|
||||
<div class="name">
|
||||
@@ -1792,6 +1837,30 @@
|
||||
<div class="content symbol">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-rtc-file-tongzhi"></use>
|
||||
</svg>
|
||||
<div class="name">通知</div>
|
||||
<div class="code-name">#icon-rtc-file-tongzhi</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-rtc-file-qunfengcaozuojilu"></use>
|
||||
</svg>
|
||||
<div class="name">群蜂操作记录</div>
|
||||
<div class="code-name">#icon-rtc-file-qunfengcaozuojilu</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-rtc-file-dingyue"></use>
|
||||
</svg>
|
||||
<div class="name">订阅</div>
|
||||
<div class="code-name">#icon-rtc-file-dingyue</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-rtc-file-zhiding"></use>
|
||||
|
@@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4147343 */
|
||||
src: url('iconfont.woff2?t=1698150656017') format('woff2'),
|
||||
url('iconfont.woff?t=1698150656017') format('woff'),
|
||||
url('iconfont.ttf?t=1698150656017') format('truetype');
|
||||
src: url('iconfont.woff2?t=1698825191464') format('woff2'),
|
||||
url('iconfont.woff?t=1698825191464') format('woff'),
|
||||
url('iconfont.ttf?t=1698825191464') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@@ -13,6 +13,18 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-rtc-file-tongzhi:before {
|
||||
content: "\e635";
|
||||
}
|
||||
|
||||
.icon-rtc-file-qunfengcaozuojilu:before {
|
||||
content: "\e702";
|
||||
}
|
||||
|
||||
.icon-rtc-file-dingyue:before {
|
||||
content: "\e6af";
|
||||
}
|
||||
|
||||
.icon-rtc-file-zhiding:before {
|
||||
content: "\e604";
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@@ -5,6 +5,27 @@
|
||||
"css_prefix_text": "icon-rtc-file-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "10906513",
|
||||
"name": "通知",
|
||||
"font_class": "tongzhi",
|
||||
"unicode": "e635",
|
||||
"unicode_decimal": 58933
|
||||
},
|
||||
{
|
||||
"icon_id": "423509",
|
||||
"name": "群蜂操作记录",
|
||||
"font_class": "qunfengcaozuojilu",
|
||||
"unicode": "e702",
|
||||
"unicode_decimal": 59138
|
||||
},
|
||||
{
|
||||
"icon_id": "28108444",
|
||||
"name": "订阅",
|
||||
"font_class": "dingyue",
|
||||
"unicode": "e6af",
|
||||
"unicode_decimal": 59055
|
||||
},
|
||||
{
|
||||
"icon_id": "8224818",
|
||||
"name": "置顶",
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -213,7 +213,7 @@ body {
|
||||
border-radius: 15px;
|
||||
color: white;
|
||||
background: #7187e685;
|
||||
transition: font-size 0.3s;
|
||||
transition: all .4s;
|
||||
}
|
||||
|
||||
.tl-rtc-file-tool-list .swiper-slide {
|
||||
@@ -1054,18 +1054,11 @@ body {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.tl-rtc-file-login-user{
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
width: 80%;
|
||||
margin-left: 10%;
|
||||
}
|
||||
|
||||
.tl-rtc-file-login-user-info{
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
width: 80%;
|
||||
margin-left: 10%;
|
||||
.tl-rtc-file-login-user, .tl-rtc-file-login-user-info{
|
||||
margin: 10px;
|
||||
text-align: center;
|
||||
max-height: 250px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tl-rtc-file-login-user-info-avatar{
|
||||
@@ -1075,8 +1068,10 @@ body {
|
||||
}
|
||||
|
||||
.tl-rtc-file-login-user-info-avatar img{
|
||||
width: 100%;
|
||||
width: 50%;
|
||||
border-radius: 50%;
|
||||
box-shadow: #c2b6b63b 0 3px 10px 0px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#tl-rtc-file-user-help{
|
||||
@@ -1096,16 +1091,36 @@ body {
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.tl-rtc-file-logout{
|
||||
width: 60%;
|
||||
margin-left: 10%;
|
||||
bottom: 20px;
|
||||
.tl-rtc-file-login-user-btn{
|
||||
width: 80%;
|
||||
position: absolute;
|
||||
margin-left: 8%;
|
||||
}
|
||||
|
||||
.tl-rtc-file-logout button{
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 8px;
|
||||
background: #79b0e8;
|
||||
}
|
||||
|
||||
.tl-rtc-file-user-oper{
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.tl-rtc-file-user-oper svg{
|
||||
font-size: 32px;
|
||||
margin: 5px;
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
padding: 5px;
|
||||
transition: all .3s;
|
||||
}
|
||||
|
||||
.tl-rtc-file-user-oper svg:hover{
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
.isMediaing{
|
||||
|
@@ -71,11 +71,6 @@
|
||||
<use xlink:href="#icon-rtc-file-gongzhonghao"></use>
|
||||
</svg>
|
||||
</a>
|
||||
<a :title="lang.relay_on" id="useTurn" v-show="switchData.openUseTurnIcon && useTurn" @click="useTurnMsg">
|
||||
<svg class="icon" aria-hidden="true" style="width: 20px;height: 20px;margin-right: 10px;">
|
||||
<use xlink:href="#icon-rtc-file-yunfuwuqi"></use>
|
||||
</svg>
|
||||
</a>
|
||||
<a :title="lang.other_language" id="language">
|
||||
<svg class="icon" aria-hidden="true" style="width: 18px;height: 18px;margin-right: 10px;">
|
||||
<use xlink:href="#icon-rtc-file-duoyuyan"></use>
|
||||
@@ -1082,7 +1077,7 @@
|
||||
<div class="layui-col-sm2" style="width: 100%;">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
{{lang.log}} <b v-show="isCloseLogs" style="color: red;">{{lang.off}}</b> - {{lang.total}}:{{filterLogs.length}}
|
||||
{{lang.log}} <b v-show="!useLogOutput" style="color: red;">{{lang.off}}</b> - {{lang.total}}:{{filterLogs.length}}
|
||||
<i @click="clickLogs" class="layui-icon layui-icon-close"
|
||||
style="cursor: pointer; right: 10px;position: absolute;"></i>
|
||||
</div>
|
||||
|
@@ -48,6 +48,9 @@ window.tlrtcfile = {
|
||||
containSymbol: function (str) {
|
||||
return new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>《》/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]").test(str)
|
||||
},
|
||||
isEmail : function(str){
|
||||
return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
|
||||
},
|
||||
genNickNameRandom: function () {
|
||||
// 获取指定范围内的随机数
|
||||
function randomAccess(min, max) {
|
||||
@@ -435,15 +438,13 @@ window.tlrtcfile = {
|
||||
|
||||
return await getRTCStats(peerConnection);
|
||||
},
|
||||
copyTxt: function (id, content) {
|
||||
copyTxt: function (id, content, callback) {
|
||||
let that = this;
|
||||
document.querySelector("#" + id).setAttribute("data-clipboard-text", content);
|
||||
let clipboard = new ClipboardJS('#' + id);
|
||||
clipboard.on('success', function (e) {
|
||||
e.clearSelection();
|
||||
if (window.layer) {
|
||||
layer.msg("复制内容成功!")
|
||||
}
|
||||
callback && callback();
|
||||
});
|
||||
},
|
||||
getQrCode: function (id, content) {
|
||||
@@ -483,23 +484,23 @@ window.tlrtcfile = {
|
||||
callback("keyup", event)
|
||||
})
|
||||
},
|
||||
getRoomTypeZh: function (type){
|
||||
getRoomType: function (type){
|
||||
if(type === 'file'){
|
||||
return "文件房间"
|
||||
return "file_room_type"
|
||||
}else if(type === 'live'){
|
||||
return "直播房间"
|
||||
return "live_room_type"
|
||||
}else if(type === 'video'){
|
||||
return "音视频房间"
|
||||
return "video_room_type"
|
||||
}else if(type === 'screen'){
|
||||
return "屏幕共享房间"
|
||||
return "screen_room_type"
|
||||
}else if(type === 'password'){
|
||||
return "密码房间"
|
||||
return "password_room_type"
|
||||
}else if(type === 'audio'){
|
||||
return "语音连麦房间"
|
||||
return "audio_room_type"
|
||||
}else if(type === 'system'){
|
||||
return "系统房间"
|
||||
return "system_room_type"
|
||||
}else{
|
||||
return "未知类型房间"
|
||||
return "unknown_room_type"
|
||||
}
|
||||
},
|
||||
scrollToBottom: function (dom, duration, timeout) {
|
||||
@@ -551,8 +552,8 @@ window.tlrtcfile = {
|
||||
animateMargin()
|
||||
}, timeout);
|
||||
},
|
||||
genNickName: function () {
|
||||
let { adjectives, nouns } = this.nameDatabase()
|
||||
genNickName: function (language) {
|
||||
let { adjectives, nouns } = language === 'zh' ? this.nameDatabase() : this.nameDatabaseEn()
|
||||
let adjectiveIndex = Math.floor(Math.random() * adjectives.length);
|
||||
let nounIndex = Math.floor(Math.random() * nouns.length);
|
||||
let adjective = adjectives[adjectiveIndex];
|
||||
@@ -618,6 +619,62 @@ window.tlrtcfile = {
|
||||
]
|
||||
return { adjectives, nouns }
|
||||
},
|
||||
nameDatabaseEn: function () {
|
||||
const adjectives = [
|
||||
"Humorous", "Funny", "Crazy", "Strange", "Quirky", "Boring", "Mysterious", "Magical", "Witty", "Playful",
|
||||
"Clever", "Beautiful", "Cute", "Charming", "Cool", "Adorable", "Stylish", "Majestic", "Fierce", "Radiant",
|
||||
"Clever", "Mischievous", "Tiny", "Delicate", "Tender", "Soft", "Friendly", "Humble", "Reserved", "Proud",
|
||||
"Narcissistic", "Romantic", "Innocent", "Passionate", "Persistent", "Cold", "Spoiled", "Naive", "Passionate", "Mature",
|
||||
"Melancholic", "Neurotic", "Lonely", "Nostalgic", "Fresh", "Elegant", "Elegant", "Aloof", "Sassy", "Rebellious",
|
||||
"Irritable", "Violent", "Alluring", "Crafty", "Confident", "Insecure", "Pessimistic", "Optimistic", "Brave", "Timid", "Joyful",
|
||||
"Painful", "Kind", "Evil", "Profound", "Sacred", "Plump", "Slender", "Obese", "Slender", "Handsome", "Ugly",
|
||||
"Fragrant", "Stinky", "Passionate", "Indifferent", "Vibrant", "Clean", "Dirty", "Carefree", "Moody",
|
||||
"Ordinary", "Extraordinary", "Shy", "Warm-hearted", "Witty", "Agile", "Dull", "Intelligent", "Ignorant", "Sincere", "Hypocritical",
|
||||
"Frank", "Cautious", "Bold", "Humble", "Arrogant", "Serious", "Relaxed", "Anxious", "Hardworking", "Lazy", "Punctual",
|
||||
"Late", "Strong", "Weak", "Intelligent", "Stupid", "Smart", "Clever", "Mischievous", "Naughty", "Lively", "Silent",
|
||||
"Healthy", "Unhealthy", "Tall", "Short", "Long", "Short", "Fat", "Thin", "Happy", "Unhappy", "Sweet", "Bitter",
|
||||
"Astute", "Foolish", "Intelligent", "High IQ", "Resourceful", "Clumsy", "Calm", "Impulsive", "Steady", "Frivolous",
|
||||
"Gentle", "Rough", "Learner", "Hates Learning", "Eater", "Picky Eater", "Patient", "Impatient", "Friendly", "Aloof", "Tolerant",
|
||||
"Stubborn", "Cautious", "Kind", "Malicious", "Calm", "Hysterical", "Opportunistic", "Pessimistic", "Optimistic", "Open-minded", "Narrow-minded",
|
||||
"Loyal", "Untrustworthy", "Charming", "Boring", "Thoughtful", "Boring", "Strategic", "Shortsighted", "Understanding", "Selfish", "Frank",
|
||||
"Curious", "Insensitive", "Social", "Reclusive", "Talkative", "Quiet", "Thoughtful", "Quick-witted", "Emotionally Rich", "Kind-hearted", "Confident",
|
||||
"Innocent", "Pursuing Perfection", "Energetic", "Adventurous", "Creative", "Calm", "Goal-oriented", "Gentle", "Helpful",
|
||||
"Smart and Quick-witted", "Loyal", "Quick-witted", "Generous", "Graceful and Multifaceted", "Fashionable", "Easy-going", "Elegant and Graceful",
|
||||
"Resilient", "Independent", "Outgoing", "Introverted", "Passionate and Focused", "Energetic", "Humerous", "Thoughtful and Kind", "Sacrificing",
|
||||
"Decisive", "Curious", "Warm-hearted", "Enthusiastic", "Lonely and Sad", "Romantic and Passionate", "Smiling", "Unrestrained", "Silly", "Carefree",
|
||||
"Lazy", "Boring", "Low-key", "Sensitive", "Cold", "Focused", "Scornful", "Passionate", "Loyal", "Mysterious", "Proud", "Free", "Artistic",
|
||||
"Fashionable", "Generous", "Talented", "Elegant", "Sunny", "Witty", "Naive and Romantic", "Cheerful", "Reserved and Calm", "Diligent", "Lazy",
|
||||
"Responsible", "Desiring Freedom", "Emotional", "Rational", "Insecure", "Seeking Security", "Emotional", "Optimistic", "Pessimistic", "Realistic", "Idealistic",
|
||||
"Approachable", "Arrogant", "Valuing Family", "Valuing Friendship", "Valuing Love", "Compassionate", "Sense of Justice", "Compassionate", "Childlike", "Confident", "Timid",
|
||||
"Talkative", "Reserved", "Outgoing", "Introverted", "Curious", "Not Understanding Others", "Sociable", "Loves Being Alone", "Self-aware", "Loves Music", "Loves Reading",
|
||||
"Loves Traveling", "Loves Food", "Loves Sports", "Loves Photography", "Loves Collecting", "Loves Shopping", "Hates Going Out", "Picky", "Self-reflective", "Doesn't Judge Others",
|
||||
"Judges Others", "Tasteful", "Unhygienic", "Hygienic", "Loves Cleanliness", "Loves Chaos", "Loves Organization", "Loves Casualness", "Loves Tidiness"
|
||||
];
|
||||
|
||||
const nouns = [
|
||||
'Puppy', 'Kitten', 'Fawn', 'Bear Cub', 'Bunny', 'Lamb', 'Piglet', 'Foal', 'Little Lion', 'Little Tiger',
|
||||
'Little Monkey', 'Little Fish', 'Little Turtle', 'Little Bird', 'Little Ant', 'Little Bee', 'Little Butterfly', 'Little Dragonfly', 'Little Crab', 'Little Octopus',
|
||||
'Little Dolphin', 'Little Shark', 'Little Whale', 'Little Crocodile', 'Little Duck', 'Snowman', 'Little Ball', 'Little Basketball', 'Little Soccer', 'Little Volleyball',
|
||||
'Little Baseball', 'Little Skateboard', 'Little Ice Cream', 'Little Umbrella', 'Little Glove', 'Little Movie', 'Little Blue Sky', 'Little Princess', 'Little Prince', 'Little Toy',
|
||||
'Little Candy', 'Little Chocolate', 'Little Ice Cream', 'Little Cake', 'Little Pizza', 'Little Burger', 'Little Fried Chicken', 'Little Roast Duck', 'Little Fish Ball', 'Little Hot Pot',
|
||||
'Little Skewer', 'Little Pancake', 'Little Deep-Fried Dough Stick', 'Little Rice Porridge', 'Little Yogurt', 'Little Tofu', 'Little Dumpling', 'Little Bun', 'Little Wonton',
|
||||
'Little Noodles', 'Little Beef Noodles', 'Little Glutinous Rice Chicken', 'Little Steamed Dumpling', 'Little Fried Noodles', 'Little Steamed Bun', 'Little Roast Meat', 'Little Skewer', 'Little Peanut', 'Little Sun',
|
||||
'Little Moon', 'Little Star', 'Little Rainbow', 'Little Windmill', 'Little Balloon', 'Little Piano', 'Little Guitar', 'Little Speaker', 'Little Microphone', 'Little Actor',
|
||||
'Little Painter', 'Little Engineer', 'Little Doctor', 'Little Policeman', 'Little Firefighter', 'Little Driver', 'Little Farmer', 'Little Diver', 'Little Pilot', 'Little Basketball',
|
||||
'Little Swimming Champion', 'Little Running Champion', 'Little Martial Arts Expert', 'Little Ballet Dancer', 'Little Sand Painter', 'Little Calligrapher', 'Little Jigsaw Expert', 'Little Toy Collector',
|
||||
'Little Movie Producer', 'Little Space Traveler', 'Superhero', 'Invincible Demon King', 'Ultimate Overlord', 'Supreme Emperor', 'Giant from Heaven', 'Peerless Genius', 'Mythical Gate',
|
||||
'Terrifying Monster', 'Wizard', 'Mysterious Swordsman', 'Immortal Legend', 'Cosmic Tyrant', 'Volcano of Hell', 'Endless Darkness', 'Shining Star', 'Radiant Light', 'Golden Knight',
|
||||
'Doomsday Annihilator', 'Invincible', 'Crushing Everything', 'Peerless Master', 'Extraordinary', 'King of All', 'Dark Knight', 'War God', 'Center of Attention', 'Shocking the World',
|
||||
'Domineering', 'Never Wavering', 'Empire Ruler', 'Unyielding', 'Ruthless King', 'Beyond Limits', 'Infinite Power', 'Shining Brightly', 'Endless Pursuit', 'Dance of the Blade',
|
||||
'Solo World', 'Consuming Everything', 'Eternal Realm', 'Doomsday War God', 'Vast Wealth', 'Mythical Legend', 'Unrivaled', 'Master of a Thousand Swords', 'Bloodthirsty Demon', 'King of the Deep Sea',
|
||||
'Fantasy City', 'Chosen One', 'Immortal Swordsman', 'Eternal Legend', 'Cosmic Overlord', 'Fire Volcano', 'Boundless Darkness', 'Shining Star', 'Infinite Quest', 'Dance of the Blade',
|
||||
'Swallower of All Things', 'Eternal War God', 'Massive Fortune', 'Mythical Legend', 'Only One', 'Myriad Swords Return to the Origin', 'Bloodthirsty Madman', 'King of the Deep Sea', 'Fantasy City', 'Chosen One',
|
||||
'Immortal Swordsman', 'Eternal Legend', 'Cosmic Overlord', 'Fire Volcano', 'Boundless Darkness', 'Shining Star', 'Infinite Quest', 'Dance of the Blade', 'Swallower of All Things', 'Eternal War God',
|
||||
'Massive Fortune', 'Mythical Legend', 'Only One', 'Myriad Swords Return to the Origin', 'Bloodthirsty Madman', 'King of the Deep Sea', 'Fantasy City', 'Chosen One'
|
||||
];
|
||||
|
||||
return { adjectives, nouns }
|
||||
},
|
||||
previewCodeFile: function (options) {
|
||||
let { file, max, callback } = options;
|
||||
|
||||
|
@@ -18,15 +18,18 @@ let useIndexedDb = (window.localStorage.getItem("tl-rtc-file-receive-file-use-in
|
||||
let useFixedRoom = window.localStorage.getItem("tl-rtc-file-use-fixed-room") || "";
|
||||
// 是否开启局域网房间被发现
|
||||
let useLocalNetworkRoomShare = (window.localStorage.getItem("tl-rtc-file-use-local-network-room-share") || "true") === 'true';
|
||||
// 是否关闭消息红点
|
||||
// 是否开启消息红点
|
||||
let useMessageDot = (window.localStorage.getItem("tl-rtc-file-use-message-dot") || "true") === 'true';
|
||||
// 是否开启浏览器系统消息通知
|
||||
let useWebMsgNotify = (window.localStorage.getItem("tl-rtc-file-use-web-msg-notify") || "true") === 'true';
|
||||
|
||||
axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
let { data : {
|
||||
code, login,
|
||||
token : userToken,
|
||||
avatar,
|
||||
username
|
||||
username,
|
||||
subscribeNotify
|
||||
} } = await axios.get("/api/login/state");
|
||||
|
||||
let resData = initData.data;
|
||||
@@ -88,9 +91,10 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
isCameraEnabled : true, //音视频场景下自己的摄像头是否开启
|
||||
isAudioEnabled : true, //音视频场景下自己的麦克风是否开启
|
||||
isLoudspeakerEnabled : true, //音视频场景下自己的扬声器是否开启
|
||||
isCloseLogs : false, //是否关闭日志, 默认开启日志
|
||||
useLogOutput : true, //是否输出日志, 默认输出日志
|
||||
chatCommFilterGood : false, // 是否展示公共聊天频道的精选消息
|
||||
chatCommFilterTop : false, // 是否展示公共聊天频道的置顶消息
|
||||
useWebMsgNotify: useWebMsgNotify, //是否开启网页消息通知
|
||||
useMessageDot : useMessageDot, //是否关闭消息提示红点, 默认开启
|
||||
useFixedRoom: useFixedRoom, //是否使用自定义房间号,持久化,后续自动进入房间
|
||||
useIndexedDb : useIndexedDb, // 是否需要将文件保存到indexedDb
|
||||
@@ -126,7 +130,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
nickName: "", //本人名称
|
||||
socketId: 0, //本人的id
|
||||
roomId: "10086", //房间号
|
||||
roomType : "file", //房间类型 video, live, audio ,file
|
||||
roomType : "file", //房间类型 video, live, audio ,file, password
|
||||
liveShareMode : "video", //直播类型 video, screen
|
||||
liveShareRole : "owner", //直播身份 owner: 主播, viwer:观众
|
||||
codeId: "", //取件码
|
||||
@@ -135,8 +139,9 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
remoteMap: {}, //远程连接map
|
||||
switchData: {}, //配置开关数据
|
||||
chatRoomSingleSocketId : "", //私聊对方的socketId
|
||||
avatar : avatar, //用户登录头像
|
||||
username : username, //用户登录昵称
|
||||
avatar : avatar || "/image/44826979.png", //用户登录头像
|
||||
username : username || " -- ", //用户登录昵称
|
||||
subscribeNotify : subscribeNotify || false, //是否已经订阅过网站
|
||||
|
||||
chunkSize: 16 * 1024, // 一块16kb 最大应该可以设置到64kb
|
||||
currentSendAllSize: 0, // 统计发送文件总大小 (流量统计)
|
||||
@@ -167,7 +172,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
popUpList: [], //消息数据
|
||||
localNetRoomList : [], //局域网房间列表
|
||||
preMouseMove : {}, //上一次鼠标移动的事件
|
||||
ips: [], // 记录ip列表,检测是否支持p2p
|
||||
ips: [], // 记录ip列表
|
||||
popUpMsgDom : [], // 消息弹窗dom
|
||||
videoDeviceList : [], //摄像头设备列表
|
||||
audioDeviceList : [], //麦克风设备列表
|
||||
@@ -249,7 +254,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
}
|
||||
},
|
||||
roomTypeName: function(){
|
||||
return window.tlrtcfile.getRoomTypeZh(this.roomType)
|
||||
return this.lang[window.tlrtcfile.getRoomType(this.roomType)]
|
||||
},
|
||||
canSaveToIndexedDb: function(){
|
||||
return localforage.supports(localforage.INDEXEDDB)
|
||||
@@ -330,6 +335,38 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelector("#tl-rtc-file-user-log").addEventListener('click', async () => {
|
||||
layer.msg(that.lang.load_history_oper_log_succ)
|
||||
});
|
||||
|
||||
document.querySelector("#tl-rtc-file-user-subscribe").addEventListener('click', async () => {
|
||||
if(that.subscribeNotify){
|
||||
layer.msg(that.lang.alreay_subscribe)
|
||||
return
|
||||
}
|
||||
|
||||
layer.prompt({
|
||||
formType: 0,
|
||||
title: that.lang.email_subscribe_website_notify,
|
||||
btn : [that.lang.confirm, that.lang.cancel],
|
||||
value: "",
|
||||
maxlength : 100,
|
||||
}, function (value, index, elem) {
|
||||
if(!tlrtcfile.isEmail(value)){
|
||||
layer.msg(that.lang.email_format_error)
|
||||
return
|
||||
}
|
||||
|
||||
that.socket.emit("subscribeNofity", {
|
||||
room: that.roomId,
|
||||
email : value
|
||||
})
|
||||
|
||||
layer.close(index);
|
||||
return false
|
||||
});
|
||||
});
|
||||
},
|
||||
content: `
|
||||
<div class="tl-rtc-file-login-user">
|
||||
@@ -338,14 +375,26 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
<img src="${that.avatar}" alt="头像">
|
||||
</div>
|
||||
<div class="tl-rtc-file-login-user-info-name">
|
||||
微信昵称: ${that.username}
|
||||
${that.lang.wchat_nickname}: ${that.username}
|
||||
</div>
|
||||
<div class="tl-rtc-file-login-user-info-name">
|
||||
个人昵称: ${that.nickName}
|
||||
${that.lang.website_nickname}: ${that.nickName}
|
||||
</div>
|
||||
<div style="text-align: center;">
|
||||
<div class="tl-rtc-file-user-oper">
|
||||
<svg class="icon" aria-hidden="true" id="tl-rtc-file-user-log">
|
||||
<use xlink:href="#icon-rtc-file-qunfengcaozuojilu"></use>
|
||||
</svg>
|
||||
<svg class="icon" aria-hidden="true" id="tl-rtc-file-user-subscribe">
|
||||
<use xlink:href="#icon-rtc-file-dingyue"></use>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tl-rtc-file-logout">
|
||||
<button id="tl-rtc-file-logout-btn" type="button" class="layui-btn">退出登录</button>
|
||||
<div class="tl-rtc-file-login-user-btn">
|
||||
<div class="tl-rtc-file-logout">
|
||||
<button id="tl-rtc-file-logout-btn" type="button" class="layui-btn">${that.lang.logout}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
@@ -450,6 +499,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
layer.prompt({
|
||||
formType: 0,
|
||||
title: that.lang.changeNickName,
|
||||
btn : [that.lang.confirm, that.lang.cancel],
|
||||
value: "",
|
||||
maxlength : 10,
|
||||
}, function (value, index, elem) {
|
||||
@@ -828,6 +878,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
layer.prompt({
|
||||
formType: 0,
|
||||
title: this.lang.please_enter_code,
|
||||
btn : [that.lang.confirm, that.lang.cancel],
|
||||
value: this.codeId,
|
||||
}, function (value, index, elem) {
|
||||
if(value.length < 30 || tlrtcfile.containSymbol(value) || tlrtcfile.containChinese(value)){
|
||||
@@ -893,6 +944,21 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
that.sendChatingRoomSingle();
|
||||
})
|
||||
|
||||
let remoteRtc = that.getRemoteInfo(that.chatRoomSingleSocketId);
|
||||
let receiveChatRoomSingleList = [];
|
||||
if(remoteRtc && remoteRtc.receiveChatRoomSingleList){
|
||||
receiveChatRoomSingleList = remoteRtc.receiveChatRoomSingleList;
|
||||
}
|
||||
receiveChatRoomSingleList.forEach((item, index) => {
|
||||
const id = "tl-rtc-file-content-copy" + index;
|
||||
if(!document.getElementById(id)) return;
|
||||
document.getElementById(id).addEventListener('click', function () {
|
||||
tlrtcfile.copyTxt(id, item.content, function () {
|
||||
layer.msg(that.lang.copy_success)
|
||||
});
|
||||
that.addUserLogs(that.lang.copy_success);
|
||||
});
|
||||
})
|
||||
},
|
||||
cancel: function (index, layero) {
|
||||
this.chatRoomSingleSocketId = "";
|
||||
@@ -910,6 +976,9 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
<small>${this.lang.user}: <b>{{info.nickName}}</b></small> -
|
||||
<small>id: <b>{{info.socketId}}</b></small> -
|
||||
<small>${this.lang.time}: <b>{{info.timeAgo}}</b></small>
|
||||
<svg class="icon" aria-hidden="true" style="margin-left: 5px;cursor: pointer;" id="tl-rtc-file-content-copy{{index}}">
|
||||
<use xlink:href="#icon-rtc-file-fuzhi"></use>
|
||||
</svg>
|
||||
</div>
|
||||
<div style="margin-top: 5px;word-break: break-all;width: 90%;">
|
||||
<b style="font-weight: bold; font-size: large;">{{- info.content }}</b>
|
||||
@@ -1053,8 +1122,8 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
2 : 1800, // 队列只有两个弹窗排队时, 弹窗悬停时间1800ms
|
||||
5 : 1600,
|
||||
8 : 1300,
|
||||
10 : 900,
|
||||
20 : 700
|
||||
10 : 500,
|
||||
20 : 200
|
||||
};
|
||||
//轮训是否有弹窗排队中
|
||||
if(!data){
|
||||
@@ -1245,7 +1314,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
// 设置昵称
|
||||
setNickName: function(){
|
||||
if(window.tlrtcfile.genNickName){
|
||||
this.nickName = window.tlrtcfile.genNickName();
|
||||
this.nickName = window.tlrtcfile.genNickName(this.langMode);
|
||||
}
|
||||
},
|
||||
// 打开公告
|
||||
@@ -1496,15 +1565,18 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
let that = this;
|
||||
layer.prompt({
|
||||
formType: 0,
|
||||
title: this.lang.please_enter_password
|
||||
title: this.lang.please_enter_password_room_num,
|
||||
btn : [that.lang.confirm, that.lang.cancel],
|
||||
}, function (value, index, elem) {
|
||||
that.roomId = value;
|
||||
layer.close(index);
|
||||
that.isPasswordRoom = !that.isPasswordRoom;
|
||||
that.roomType = "password";
|
||||
|
||||
layer.prompt({
|
||||
formType: 1,
|
||||
title: that.lang.please_enter_password
|
||||
title: that.lang.please_enter_password,
|
||||
btn : [that.lang.confirm, that.lang.cancel],
|
||||
}, function (value, index, elem) {
|
||||
that.createPasswordRoom(value);
|
||||
layer.close(index);
|
||||
@@ -1560,6 +1632,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
}else{
|
||||
layer.prompt({
|
||||
formType: 0,
|
||||
btn : [that.lang.confirm, that.lang.cancel],
|
||||
title: that.lang.please_enter_video_call_room_num
|
||||
}, function (value, index, elem) {
|
||||
that.roomId = value;
|
||||
@@ -1624,6 +1697,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
}else{
|
||||
layer.prompt({
|
||||
formType: 0,
|
||||
btn : [that.lang.confirm, that.lang.cancel],
|
||||
title: this.lang.please_enter_screen_sharing_room_num,
|
||||
}, function (value, index, elem) {
|
||||
that.roomId = value;
|
||||
@@ -1848,6 +1922,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
layer.prompt({
|
||||
formType: 0,
|
||||
title: this.lang.please_enter_audio_sharing_room_num,
|
||||
btn : [that.lang.confirm, that.lang.cancel],
|
||||
}, function (value, index, elem) {
|
||||
that.roomId = value;
|
||||
that.createMediaRoom("audio");
|
||||
@@ -2040,6 +2115,17 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
document.getElementById("tl-sendChatingComm").addEventListener('click',function(){
|
||||
that.sendChatingComm();
|
||||
})
|
||||
|
||||
that.receiveChatCommList.forEach((item, index) => {
|
||||
const id = "tl-rtc-file-content-copy" + index;
|
||||
if(!document.getElementById(id)) return;
|
||||
document.getElementById(id).addEventListener('click', function () {
|
||||
tlrtcfile.copyTxt(id, item.msg, function () {
|
||||
layer.msg(that.lang.copy_success)
|
||||
});
|
||||
that.addUserLogs(that.lang.copy_success);
|
||||
});
|
||||
})
|
||||
},
|
||||
content: `
|
||||
<div class="layui-col-sm12" style="padding: 15px;">
|
||||
@@ -2058,7 +2144,10 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
{{# } }}
|
||||
<small>${this.lang.room}: <b>{{info.room}}</b></small> -
|
||||
<small>${this.lang.user}: <b>{{info.socketId}}</b></small> -
|
||||
<small>${this.lang.time}: <b>{{info.timeAgo}}</b></small>
|
||||
<small>${this.lang.time}: <b>{{info.timeAgo}}</b></small>
|
||||
<svg class="icon" aria-hidden="true" style="margin-left: 5px;cursor: pointer;" id="tl-rtc-file-content-copy{{index}}">
|
||||
<use xlink:href="#icon-rtc-file-fuzhi"></use>
|
||||
</svg>
|
||||
{{# if(info.admin) { }}
|
||||
<svg class="icon" aria-hidden="true" style="width: 24px;height: 24px;color:#1e9fff;">
|
||||
<use xlink:href="#icon-rtc-file-zhuip"></use>
|
||||
@@ -2260,6 +2349,17 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
document.getElementById("tl-sendChatingRoom").addEventListener("click",function(){
|
||||
that.sendChatingRoom();
|
||||
})
|
||||
|
||||
that.receiveChatRoomList.forEach((item, index) => {
|
||||
const id = "tl-rtc-file-content-copy" + index;
|
||||
if(!document.getElementById(id)) return;
|
||||
document.getElementById(id).addEventListener('click', function () {
|
||||
tlrtcfile.copyTxt(id, item.content, function () {
|
||||
layer.msg(that.lang.copy_success)
|
||||
});
|
||||
that.addUserLogs(that.lang.copy_success);
|
||||
});
|
||||
})
|
||||
},
|
||||
content: `
|
||||
<div class="layui-col-sm12" style="padding: 15px;">
|
||||
@@ -2283,6 +2383,9 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
{{# } }}
|
||||
<small>id: <b>{{info.socketId}}</b></small> -
|
||||
<small>${this.lang.time}: <b>{{info.timeAgo}}</b></small>
|
||||
<svg class="icon" aria-hidden="true" style="margin-left: 5px;cursor: pointer;" id="tl-rtc-file-content-copy{{index}}">
|
||||
<use xlink:href="#icon-rtc-file-fuzhi"></use>
|
||||
</svg>
|
||||
</div>
|
||||
<div style="margin-top: 5px;word-break: break-all;width: 90%;">
|
||||
<b style="font-weight: bold; font-size: large;"> {{- info.content}} </b>
|
||||
@@ -2454,7 +2557,8 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
langMode : this.langMode,
|
||||
ua: this.isMobile ? 'mobile' : 'pc',
|
||||
network : this.network,
|
||||
localNetRoom : this.useLocalNetworkRoomShare
|
||||
localNetRoom : this.useLocalNetworkRoomShare,
|
||||
ips : this.ips,
|
||||
});
|
||||
this.isJoined = true;
|
||||
this.addPopup({
|
||||
@@ -2486,7 +2590,8 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
ua: this.isMobile ? 'mobile' : 'pc',
|
||||
network : this.network,
|
||||
liveShareRole : this.liveShareRole,
|
||||
localNetRoom : this.useLocalNetworkRoomShare
|
||||
localNetRoom : this.useLocalNetworkRoomShare,
|
||||
ips : this.ips,
|
||||
});
|
||||
this.isJoined = true;
|
||||
this.roomType = type;
|
||||
@@ -2524,7 +2629,8 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
langMode : this.langMode,
|
||||
ua: this.isMobile ? 'mobile' : 'pc',
|
||||
network : this.network,
|
||||
localNetRoom : this.useLocalNetworkRoomShare
|
||||
localNetRoom : this.useLocalNetworkRoomShare,
|
||||
ips : this.ips,
|
||||
});
|
||||
this.isJoined = true;
|
||||
this.addPopup({
|
||||
@@ -3365,14 +3471,6 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
sdp: event.candidate.candidate
|
||||
};
|
||||
this.socket.emit('candidate', message);
|
||||
|
||||
let ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3})/;
|
||||
let match = ipRegex.exec(event.candidate.candidate);
|
||||
let ipAddress = match && Array.isArray(match) && match.length > 0 ? match[1] : "unknow";
|
||||
if (ipAddress !== 'unknow') {
|
||||
this.ips.push(ipAddress);
|
||||
}
|
||||
this.addSysLogs("IP: " + ipAddress);
|
||||
}
|
||||
},
|
||||
// offer
|
||||
@@ -3418,7 +3516,22 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
let that = this;
|
||||
|
||||
this.socket.on("localNetRoom", data => {
|
||||
that.localNetRoomList = data.list || [];
|
||||
const { mode, list } = data;
|
||||
if(mode === 'connect'){
|
||||
that.localNetRoomList = data.list || [];
|
||||
}else if(mode === 'join'){
|
||||
let newList = that.localNetRoomList.filter(item => { return item.owner !== list[0].owner });
|
||||
newList.push(list[0]);
|
||||
that.localNetRoomList = newList;
|
||||
}else if(mode === 'exit'){
|
||||
let newList = that.localNetRoomList.filter(item => { return item.owner !== list[0].owner });
|
||||
if(list[0].count === 0){ //退出后房间没人了,清理
|
||||
that.localNetRoomList = newList;
|
||||
}else{ // 退出后房间还有人,更新
|
||||
newList.push(list[0]);
|
||||
that.localNetRoomList = newList;
|
||||
}
|
||||
}
|
||||
if(that.localNetRoomList.length === 0 && that.showLocalNetRoom){
|
||||
that.clickLocalNetRooms(true);
|
||||
}
|
||||
@@ -4032,6 +4145,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
layer.prompt({
|
||||
formType: 1,
|
||||
title: that.lang.please_enter,
|
||||
btn : [that.lang.confirm, that.lang.cancel],
|
||||
}, function (value, index, elem) {
|
||||
that.socket.emit('manageConfirm', {
|
||||
room: that.roomId,
|
||||
@@ -4041,6 +4155,11 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
});
|
||||
});
|
||||
|
||||
//关闭音视频
|
||||
this.socket.on('subscribeNofity', function (data) {
|
||||
layer.msg(that.lang.subscribe_website_notify_succ)
|
||||
});
|
||||
|
||||
this.socket.on('manage', function (data) {
|
||||
if (data.socketId !== that.socketId) {
|
||||
layer.msg(that.lang.illegal_event)
|
||||
@@ -4168,8 +4287,8 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
})
|
||||
})
|
||||
|
||||
document.getElementById("closeLogs").addEventListener('click', function(){
|
||||
that.closeLogs();
|
||||
document.getElementById("logOutput").addEventListener('click', function(){
|
||||
that.logOutput();
|
||||
})
|
||||
|
||||
document.getElementById("coffee").addEventListener('click', function(){
|
||||
@@ -4199,6 +4318,10 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
document.getElementById("fileTransferSettingHelp").addEventListener('click', function(){
|
||||
that.settingHelp();
|
||||
})
|
||||
|
||||
document.getElementById("webMsgNotify").addEventListener('click', function(){
|
||||
that.webMsgNotify();
|
||||
})
|
||||
},
|
||||
content: `
|
||||
<div class="setting-main layui-carousel" id="tl-rtc-file-setting-info">
|
||||
@@ -4340,13 +4463,13 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
</li>
|
||||
<li class="layui-col-xs4">
|
||||
<a title="${this.lang.log}">
|
||||
<svg class="icon" aria-hidden="true" id="closeLogs">
|
||||
<svg class="icon" aria-hidden="true" id="logOutput">
|
||||
<use xlink:href="#icon-rtc-file-rizhiguanli"></use>
|
||||
</svg>
|
||||
<svg id="closeLogsOpen" class="icon settingOpenIcon" aria-hidden="true" style="${this.isCloseLogs ? 'display:none;' : ''}">
|
||||
<svg id="logOutputOpen" class="icon settingOpenIcon" aria-hidden="true" style="${this.useLogOutput ? '' : 'display:none;'}">
|
||||
<use xlink:href="#icon-rtc-file-zhengque"></use>
|
||||
</svg>
|
||||
<svg id="closeLogsClose" class="icon settingCloseIcon" aria-hidden="true" style="${!this.isCloseLogs ? 'display:none;' : ''}">
|
||||
<svg id="logOutputClose" class="icon settingCloseIcon" aria-hidden="true" style="${!this.useLogOutput ? '' : 'display:none;'}">
|
||||
<use xlink:href="#icon-rtc-file-cuowu"></use>
|
||||
</svg>
|
||||
<cite>${this.lang.log}</cite>
|
||||
@@ -4394,6 +4517,20 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
<cite>${this.lang.local_network_room_share}</cite>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-col-xs4">
|
||||
<a title="${this.lang.web_msg_notify}">
|
||||
<svg class="icon" aria-hidden="true" id="webMsgNotify">
|
||||
<use xlink:href="#icon-rtc-file-tongzhi"></use>
|
||||
</svg>
|
||||
<svg id="webMsgNotifyOpen" class="icon settingOpenIcon" aria-hidden="true" style="${this.useWebMsgNotify ? '' : 'display:none;'}">
|
||||
<use xlink:href="#icon-rtc-file-zhengque"></use>
|
||||
</svg>
|
||||
<svg id="webMsgNotifyClose" class="icon settingCloseIcon" aria-hidden="true" style="${!this.useWebMsgNotify ? '' : 'display:none;'}">
|
||||
<use xlink:href="#icon-rtc-file-cuowu"></use>
|
||||
</svg>
|
||||
<cite>${this.lang.web_msg_notify}</cite>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -4466,24 +4603,23 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
|
||||
layer.msg(this.lang.auto_join_fixed_room + ": " + this.useFixedRoom)
|
||||
},
|
||||
|
||||
// 是否关闭日志输出
|
||||
closeLogs: function(){
|
||||
this.isCloseLogs = !this.isCloseLogs;
|
||||
logOutput: function(){
|
||||
this.useLogOutput = !this.useLogOutput;
|
||||
|
||||
if (this.isCloseLogs) {
|
||||
layer.msg(`${this.lang.logs_switch}${this.lang.on}`)
|
||||
$("#closeLogsOpen").css("display", "inline");
|
||||
$("#closeLogsClose").css("display", "none");
|
||||
if (this.useLogOutput) {
|
||||
$("#logOutputOpen").css("display", "inline");
|
||||
$("#logOutputClose").css("display", "none");
|
||||
} else {
|
||||
layer.msg(`${this.lang.logs_switch}${this.lang.off}`)
|
||||
$("#closeLogsOpen").css("display", "none");
|
||||
$("#closeLogsClose").css("display", "inline");
|
||||
$("#logOutputOpen").css("display", "none");
|
||||
$("#logOutputClose").css("display", "inline");
|
||||
}
|
||||
|
||||
$("#closeLogs").removeClass("layui-anim-rotate")
|
||||
layer.msg(`${this.lang.logs_switch}${this.useLogOutput ? this.lang.on : this.lang.off}`)
|
||||
|
||||
$("#logOutput").removeClass("layui-anim-rotate")
|
||||
setTimeout(() => {
|
||||
$("#closeLogs").addClass("layui-anim-rotate")
|
||||
$("#logOutput").addClass("layui-anim-rotate")
|
||||
}, 50)
|
||||
},
|
||||
// ai对话上下文开关
|
||||
@@ -4507,43 +4643,64 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
$("#aiContext").addClass("layui-anim-rotate")
|
||||
}, 50)
|
||||
},
|
||||
// 是否关闭消息红点提示
|
||||
// 是否开启消息红点提示
|
||||
messageDot : function(){
|
||||
this.useMessageDot = !this.useMessageDot;
|
||||
|
||||
if (this.useMessageDot) {
|
||||
window.localStorage.setItem("tl-rtc-file-use-message-dot", false)
|
||||
layer.msg(`${this.lang.messgae_dot_switch}${this.lang.off}`)
|
||||
$("#messageDotOpen").css("display", "none");
|
||||
$("#messageDotClose").css("display", "inline");
|
||||
} else {
|
||||
window.localStorage.setItem("tl-rtc-file-use-message-dot", true)
|
||||
layer.msg(`${this.lang.messgae_dot_switch}${this.lang.on}`)
|
||||
$("#messageDotOpen").css("display", "inline");
|
||||
$("#messageDotClose").css("display", "none");
|
||||
} else {
|
||||
window.localStorage.setItem("tl-rtc-file-use-message-dot", false)
|
||||
$("#messageDotOpen").css("display", "none");
|
||||
$("#messageDotClose").css("display", "inline");
|
||||
}
|
||||
|
||||
this.useMessageDot = !this.useMessageDot;
|
||||
layer.msg(`${this.lang.messgae_dot_switch}${this.useMessageDot ? this.lang.on : this.lang.off}`)
|
||||
|
||||
$("#messageDot").removeClass("layui-anim-rotate")
|
||||
setTimeout(() => {
|
||||
$("#messageDot").addClass("layui-anim-rotate")
|
||||
}, 50)
|
||||
},
|
||||
// 是否开启局域网房间分享
|
||||
localNetworkRoomShare : function(){
|
||||
if(this.useLocalNetworkRoomShare){
|
||||
window.localStorage.setItem("tl-rtc-file-use-local-network-room-share", false)
|
||||
layer.msg(`${this.lang.local_network_room_share}${this.lang.off}`)
|
||||
$("#localNetworkRoomShareOpen").css("display", "none");
|
||||
$("#localNetworkRoomShareClose").css("display", "inline");
|
||||
}else{
|
||||
window.localStorage.setItem("tl-rtc-file-use-local-network-room-share", true)
|
||||
layer.msg(`${this.lang.local_network_room_share}${this.lang.on}`)
|
||||
$("#localNetworkRoomShareOpen").css("display", "inline");
|
||||
$("#localNetworkRoomShareClose").css("display", "none");
|
||||
// 开启系统消息提示弹窗
|
||||
webMsgNotify: function(){
|
||||
this.useWebMsgNotify = !this.useWebMsgNotify;
|
||||
|
||||
if (this.useWebMsgNotify) {
|
||||
window.localStorage.setItem("tl-rtc-file-use-web-message-notify", true)
|
||||
$("#webMsgNotifyOpen").css("display", "inline");
|
||||
$("#webMsgNotifyClose").css("display", "none");
|
||||
} else {
|
||||
window.localStorage.setItem("tl-rtc-file-use-web-message-notify", false)
|
||||
$("#webMsgNotifyOpen").css("display", "none");
|
||||
$("#webMsgNotifyClose").css("display", "inline");
|
||||
}
|
||||
|
||||
layer.msg(`${this.lang.web_msg_notify}${this.useWebMsgNotify ? this.lang.on : this.lang.off}`)
|
||||
|
||||
$("#webMsgNotify").removeClass("layui-anim-rotate")
|
||||
setTimeout(() => {
|
||||
$("#webMsgNotify").addClass("layui-anim-rotate")
|
||||
}, 50)
|
||||
},
|
||||
// 是否开启局域网房间分享
|
||||
localNetworkRoomShare : function(){
|
||||
this.useLocalNetworkRoomShare = !this.useLocalNetworkRoomShare;
|
||||
|
||||
if(this.useLocalNetworkRoomShare){
|
||||
window.localStorage.setItem("tl-rtc-file-use-local-network-room-share", true)
|
||||
$("#localNetworkRoomShareOpen").css("display", "inline");
|
||||
$("#localNetworkRoomShareClose").css("display", "none");
|
||||
}else{
|
||||
window.localStorage.setItem("tl-rtc-file-use-local-network-room-share", false)
|
||||
$("#localNetworkRoomShareOpen").css("display", "none");
|
||||
$("#localNetworkRoomShareClose").css("display", "inline");
|
||||
}
|
||||
|
||||
layer.msg(`${this.lang.local_network_room_share}${this.useLocalNetworkRoomShare ? this.lang.on : this.lang.off}`)
|
||||
|
||||
$("#localNetworkRoomShare").removeClass("layui-anim-rotate")
|
||||
setTimeout(() => {
|
||||
$("#localNetworkRoomShare").addClass("layui-anim-rotate")
|
||||
@@ -4567,6 +4724,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
formType: 0,
|
||||
value: '',
|
||||
title: that.lang.fixed_room,
|
||||
btn : [that.lang.confirm, that.lang.cancel],
|
||||
}, function (value, index, elem) {
|
||||
if (!that.switchData.allowChinese && window.tlrtcfile.containChinese(value)) {
|
||||
layer.msg(that.lang.room_num_no_zh)
|
||||
@@ -4642,6 +4800,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
formType: 0,
|
||||
value: 'wss://',
|
||||
title: that.lang.input_custom_ws_url,
|
||||
btn : [that.lang.confirm, that.lang.cancel],
|
||||
}, function (value, index, elem) {
|
||||
if(!/^wss?:\/\/[^\s/$.?#].[^\s]*$/.test(value)){
|
||||
layer.msg(that.lang.ws_url_error)
|
||||
@@ -4685,11 +4844,6 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
window.location.reload()
|
||||
}, 300);
|
||||
},
|
||||
// 中继信息提示
|
||||
useTurnMsg: function () {
|
||||
layer.msg(this.lang.relay_on)
|
||||
this.addUserLogs(this.lang.relay_on)
|
||||
},
|
||||
// 当前网络状态
|
||||
networkMsg: function () {
|
||||
layer.msg(this.lang.current_network + (this.network !== 'wifi' ? this.lang.mobile_data : this.network))
|
||||
@@ -4712,7 +4866,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
},
|
||||
// 记录日志
|
||||
addLogs: function (msg, type) {
|
||||
if(this.isCloseLogs){
|
||||
if(!this.useLogOutput){
|
||||
return
|
||||
}
|
||||
if (this.logs.length > this.maxLogCount) {
|
||||
@@ -4792,13 +4946,8 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
tlrtcfile.getQrCode("tl-rtc-file-room-share-image", content)
|
||||
}
|
||||
|
||||
document.querySelector("#shareUrl").setAttribute("data-clipboard-text", content);
|
||||
let clipboard = new ClipboardJS('#shareUrl');
|
||||
clipboard.on('success', function (e) {
|
||||
e.clearSelection();
|
||||
setTimeout(() => {
|
||||
layer.msg(that.lang.copy_room_link)
|
||||
}, 500);
|
||||
tlrtcfile.copyTxt("shareUrl", content, function () {
|
||||
layer.msg(that.lang.copy_room_link)
|
||||
});
|
||||
that.addUserLogs(that.lang.copy_room_link);
|
||||
},
|
||||
@@ -5274,6 +5423,37 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
}, 50)
|
||||
}
|
||||
},
|
||||
// 局域网房间功能开启进行的的ip上报
|
||||
localNetRoomIpReport: async function () {
|
||||
let that = this;
|
||||
await new Promise((resolve, reject) => {
|
||||
const pc = new RTCPeerConnection(that.config);
|
||||
pc.createDataChannel('report');
|
||||
pc.createOffer().then(offer => pc.setLocalDescription(offer)).catch(reject);
|
||||
pc.addEventListener("icegatheringstatechange", (ev) => {
|
||||
if(pc.iceGatheringState === 'complete'){
|
||||
resolve(true)
|
||||
}
|
||||
});
|
||||
pc.onicecandidate = (e) => {
|
||||
if (e.candidate) {
|
||||
if(e.candidate.type !== 'relay'){
|
||||
let alreadyHas = that.ips.filter(item=>{
|
||||
return item.address === e.candidate.address;
|
||||
}).length > 0;
|
||||
if(!alreadyHas){
|
||||
that.ips.push({
|
||||
ipType : e.candidate.type,
|
||||
address : e.candidate.address,
|
||||
protocol : e.candidate.protocol,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
this.socket.emit("localNetRoom", { ips : this.ips })
|
||||
},
|
||||
// 自动监听窗口变化,更新css
|
||||
reCaculateWindowSize: function () {
|
||||
this.clientWidth = document.body.clientWidth;
|
||||
@@ -5614,6 +5794,10 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then(async (initData) => {
|
||||
this.loadVConsoleJs();
|
||||
this.addSysLogs(this.lang.debug_init_done);
|
||||
|
||||
this.addSysLogs(this.lang.local_network_room_report_init);
|
||||
this.localNetRoomIpReport();
|
||||
this.addSysLogs(this.lang.local_network_room_report_init_done);
|
||||
|
||||
this.addSysLogs(this.lang.current_relay_status + (this.useTurn ? this.lang.on : this.lang.off))
|
||||
}
|
||||
});
|
||||
|
@@ -413,8 +413,51 @@ const local_lang = {
|
||||
"webrtc_ice_state" : "webrtc state",
|
||||
"ip" : "IP",
|
||||
"online_count" : "Online count",
|
||||
"load_history_oper_log_succ" : "Load histroy oper log list successfully",
|
||||
"subscribe_website_notify_succ" : "Subscribe website notify successfully",
|
||||
"wchat_nickname" : "Wxchat nickname",
|
||||
"website_nickname" : "Website nickname",
|
||||
"logout" : "Logout",
|
||||
"email_subscribe" : "Email subscribe",
|
||||
"email_format_error" : "Email format error",
|
||||
"email_subscribe_website_notify" : "Email subscribe website notify",
|
||||
"alreay_subscribe" : "Alreay subscribe website notify",
|
||||
"copy_success" : "Copy success",
|
||||
"web_msg_notify" : "Web msg notify",
|
||||
"please_enter_password_room_num" : "Please enter the password room number",
|
||||
"file_room_type" : "File room type",
|
||||
"live_room_type" : "Live room type",
|
||||
"video_room_type" : "Video room type",
|
||||
"screen_room_type" : "Screen room type",
|
||||
"password_room_type" : "Password room type",
|
||||
"audio_room_type" : "Audio room type",
|
||||
"system_room_type" : "System room type",
|
||||
"unknown_room_type" : "Unknown room type",
|
||||
"local_network_room_report_init" : "Local network room report init",
|
||||
"local_network_room_report_init_done" : "Local network room report init done",
|
||||
},
|
||||
"zh": {
|
||||
"local_network_room_report_init" : "局域网房间上报初始化",
|
||||
"local_network_room_report_init_done" : "局域网房间上报初始化完成",
|
||||
"file_room_type" : "文件房间",
|
||||
"live_room_type" : "直播房间",
|
||||
"video_room_type" : "音视频房间",
|
||||
"screen_room_type" : "屏幕共享房间",
|
||||
"password_room_type" : "密码房间",
|
||||
"audio_room_type" : "语音连麦房间",
|
||||
"system_room_type" : "系统房间",
|
||||
"unknown_room_type" : "未知类型房间",
|
||||
"web_msg_notify" : "系统通知",
|
||||
"copy_success" : "复制成功",
|
||||
"alreay_subscribe" : "您已订阅网站通知",
|
||||
"email_subscribe_website_notify" : "邮件订阅网站通知",
|
||||
"email_format_error" : "邮箱格式错误",
|
||||
"email_subscribe" : "邮件订阅",
|
||||
"logout" : "退出登录",
|
||||
"website_nickname" : "网站昵称",
|
||||
"wchat_nickname" : "微信昵称",
|
||||
"subscribe_website_notify_succ" : "订阅网站通知成功",
|
||||
"load_history_oper_log_succ" : "即将支持加载历史记录",
|
||||
"question_answer" : "问答/建议反馈列表",
|
||||
"ip" : "IP",
|
||||
"online_count" : "在线人数",
|
||||
@@ -680,6 +723,7 @@ const local_lang = {
|
||||
"please_enter_code": "请输入取件码",
|
||||
"please_enter_content": "请输入文本内容",
|
||||
"please_enter_live_room_num": "请输入直播房间号",
|
||||
"please_enter_password_room_num" : "请输入密码房间号",
|
||||
"please_enter_password": "请输入密码房间密码",
|
||||
"please_enter_right_code": "请输入正确的取件码",
|
||||
"please_enter_room_num": "请先填写房间号",
|
||||
|
Reference in New Issue
Block a user