@@ -50,8 +46,7 @@ const theme = computed(() => settingsStore.theme)
const isCollapse = computed(() => !appStore.sidebar.opened)
const activeMenu = computed(() => {
- const { meta, path } = route
- // if set path, the sidebar will highlight the path you set
+ const { meta, path } = route
if (meta.activeMenu) {
return meta.activeMenu
}
diff --git a/src/layout/components/index.js b/src/layout/components/index.js
index 8476db0..409558c 100644
--- a/src/layout/components/index.js
+++ b/src/layout/components/index.js
@@ -2,5 +2,4 @@ export { default as AppMain } from './AppMain.vue'
export { default as Navbar } from './Navbar.vue'
export { default as Settings } from './Settings/index.vue'
export { default as TagsView } from './TagsView/index.vue'
-export { default as ResetPwd } from './ResetPwd/index.vue'
-export { default as InviteJoin } from './InviteJoin/index.vue'
\ No newline at end of file
+export { default as ResetPwd } from './ResetPwd/index.vue'
\ No newline at end of file
diff --git a/src/layout/index.vue b/src/layout/index.vue
index 8671c63..2f8398e 100644
--- a/src/layout/index.vue
+++ b/src/layout/index.vue
@@ -2,11 +2,13 @@
-
xSynergy远程协作系统
+
xSynergy远程协作后台管理系统
+
+
{{ nickName }}
@@ -32,12 +34,15 @@
-
-
+
@@ -45,25 +50,23 @@
import { ElMessageBox ,ElMessage} from 'element-plus'
import { useWindowSize } from '@vueuse/core'
import Sidebar from './components/Sidebar/index.vue'
-import { AppMain, TagsView ,ResetPwd,InviteJoin} from './components/index.js'
+import { AppMain, TagsView ,ResetPwd,Navbar} from './components/index.js'
import { useAppStore } from '@/stores/modules/app.js'
import { useSettingsStore } from '@/stores/modules/settings.js'
import { useUserStore } from '@/stores/modules/user.js'
import { removeToken } from '@/utils/auth.js'
-import { onMounted ,ref} from 'vue'
-import { mqttClient } from "@/utils/mqtt.js";
+import { onMounted ,ref} from 'vue'
const settingsStore = useSettingsStore()
const userStore = useUserStore()
const useAppStoreStore = useAppStore()
-const router = useRouter()
-
-const inviteJoinRef = ref(null)
+const router = useRouter()
const theme = computed(() => settingsStore.theme)
const sidebar = computed(() => useAppStoreStore.sidebar)
const device = computed(() => useAppStoreStore.device)
const needTagsView = computed(() => settingsStore.tagsView)
+
const nickName = computed(() => {
// 优先从 userStore 获取
if (userStore.name) {
@@ -80,8 +83,7 @@ const nickName = computed(() => {
console.error('解析 userData 失败:', error)
}
return ''
-})
-
+})
const classObj = computed(() => ({
hideSidebar: !sidebar.value.opened,
@@ -141,17 +143,7 @@ function handleClickOutside() {
useAppStoreStore.closeSideBar({ withoutAnimation: false })
}
-onMounted(async () => {
- await mqttClient.connect(`room${Math.random().toString(16).substr(2, 8)}`);
- const res = await userStore.getInfo()
- const topic = `xSynergy/ROOM/+/rooms/${res.uid}`;
- mqttClient.subscribe(topic, async (shapeData) => {
- if(inviteJoinRef.value){
- inviteJoinRef.value.processingSocket(shapeData.toString())
- }
-
- });
-})
+onMounted(async () => {})
@@ -232,8 +224,8 @@ onMounted(async () => {
-webkit-box-shadow: 2px 0 9px rgba(0, 21, 41, 0.35);
box-shadow: 2px 0 9px rgba(0, 21, 41, 0.35);
padding: 3px 20px;
- // background-color: #8290f0;
- background-color: #434343;
+ background-color: #409EFF;
+ // background-color: #434343;
.nav-left {
display: flex;
align-items: center;
@@ -260,6 +252,11 @@ onMounted(async () => {
cursor: pointer;
align-items: center;
margin-right: 30px;
+ img{
+ width: 35px;
+ height: 35px;
+ border-radius: 50%;
+ }
.user-avatar {
cursor: pointer;
width: 50px;
@@ -312,9 +309,9 @@ onMounted(async () => {
transition: width 0.28s;
}
-.hideSidebar .fixed-header {
- width: calc(100% - 54px);
-}
+// .hideSidebar .fixed-header {
+// width: calc(100% - 54px);
+// }
.sidebarHide .fixed-header {
width: 100%;
diff --git a/src/main.js b/src/main.js
index b1bd3ee..795df68 100644
--- a/src/main.js
+++ b/src/main.js
@@ -4,8 +4,12 @@ import { createPinia } from 'pinia'
import * as Sentry from '@sentry/vue';
import {
- deepClone
- } from '@/utils/ruoyi'
+ deepClone,
+ parseTime,
+} from '@/utils/ruoyi.js'
+
+
+
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
@@ -20,35 +24,41 @@ import router from './router'
const pinia = createPinia()
const app = createApp(App)
-Sentry.init({
- app,
- dsn: 'https://34a0d76174a64db09d31d13a8042560b@sentry.cnsdt.com/2', // 替换为你的 DSN
- integrations: [
- // 浏览器性能追踪集成
- Sentry.browserTracingIntegration({
- router,
- }),
- // 会话回放集成
- Sentry.replayIntegration({
- maskAllText: false,
- blockAllMedia: false,
- }),
- ],
- // 性能监控采样率
- tracesSampleRate: 1.0, // 生产环境建议设置为 0.1-0.2
- // 会话回放采样率
- replaysSessionSampleRate: 0.1,
- replaysOnErrorSampleRate: 1.0,
- // 环境配置
- environment: import.meta.env.MODE,
- // 开发环境下可禁用 Sentry
- enabled: import.meta.env.PROD,
- });
+app.config.globalProperties.parseTime = parseTime;
-for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
+// Sentry.init({
+// app,
+// dsn: 'https://34a0d76174a64db09d31d13a8042560b@sentry.cnsdt.com/2', // 替换为你的 DSN
+// integrations: [
+// // 浏览器性能追踪集成
+// Sentry.browserTracingIntegration({
+// router,
+// }),
+// // 会话回放集成
+// Sentry.replayIntegration({
+// maskAllText: false,
+// blockAllMedia: false,
+// }),
+// ],
+// // 性能监控采样率
+// tracesSampleRate: 1.0, // 生产环境建议设置为 0.1-0.2
+// // 会话回放采样率
+// replaysSessionSampleRate: 0.1,
+// replaysOnErrorSampleRate: 1.0,
+// // 环境配置
+// environment: import.meta.env.MODE,
+// // 开发环境下可禁用 Sentry
+// enabled: import.meta.env.PROD,
+// });
+
+for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
+//全局组件
+import Pagination from '@/components/Pagination/index.vue'
+
+app.component('Pagination', Pagination)
app.use(pinia)
app.use(router)
app.use(ElementPlus, {
diff --git a/src/router/index.js b/src/router/index.js
index 314ed33..7d8206e 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -23,39 +23,148 @@ export const constantRoutes = [
component: () => import("@/views/login.vue"),
meta: { title: "登录" },
hidden: true,
- },
+ },
{
- path: '/whiteboard',
- component: () => import('@/views/custom/tabulaRase/index.vue'),
- meta: { title: "白板" },
- hidden: true,
- },
- {
- path: "/coordinate",
- redirect: "/coordinate/CoordinatePage",
- component: Layout,
+ path: "/userManagement",
+ redirect: "/userManagement/UserManagementPage",
+ component: Layout,
children: [
{
- path: 'CoordinatePage',
- name: "Coordinate",
- component: () => import("@/views/coordinate/personnelList/index.vue"),
- meta: { title: "远程协作", icon: "client", affix: true },
+ path: 'UserManagementPage',
+ name: "UserManagement",
+ component: () => import("@/views/userManagement/index.vue"),
+ meta: { title: "用户管理", icon: "client", affix: true },
}
]
},
- {
- path: "/conferencingRoom",
- // component: Layout,
- hidden: true,
+ {
+ path: "/roleManagement",
+ redirect: "/roleManagement/RoleManagementPage",
+ component: Layout,
children: [
{
- path: '',
- name: "ConferencingRoom",
- component: () => import("@/views/conferencingRoom/index.vue"),
- meta: { title: "会议房间", icon: "client", affix: true },
+ path: 'RoleManagementPage',
+ name: "RoleManagement",
+ component: () => import("@/views/roleManagement/index.vue"),
+ meta: { title: "角色管理", icon: "client", affix: true },
}
]
},
+ {
+ path: "/menuManagement",
+ redirect: "/menuManagement/MenuManagementPage",
+ component: Layout,
+ children: [
+ {
+ path: 'MenuManagementPage',
+ name: "MenuManagement",
+ component: () => import("@/views/menuManagement/index.vue"),
+ meta: { title: "菜单管理", icon: "client", affix: true },
+ },
+
+ ]
+ },
+ {
+ path: "/roomManagement",
+ redirect: "/roomManagement/RoomManagementPage",
+ component: Layout,
+ children: [
+ {
+ path: 'RoomManagementPage',
+ name: "RoomManagement",
+ component: () => import("@/views/roomManagement/index.vue"),
+ meta: { title: "房间管理", icon: "client", affix: true },
+ },
+
+ ]
+ },
+ {
+ path: "/interfaceManagement",
+ redirect: "/interfaceManagement/InterfaceManagementPage",
+ component: Layout,
+ children: [
+ {
+ path: 'InterfaceManagementPage',
+ name: "InterfaceManagement",
+ component: () => import("@/views/interfaceManagement/index.vue"),
+ meta: { title: "接口管理", icon: "client", affix: true },
+ },
+
+ ]
+ },
+ // {
+ // path: "/patrolMission",
+ // redirect: "/patrolMission/PatrolMissionPage",
+ // component: Layout,
+ // children: [
+ // {
+ // path: 'PatrolMissionPage',
+ // name: "PatrolMission",
+ // component: () => import("@/views/patrolMission/index.vue"),
+ // meta: { title: "设备知识库", icon: "client", affix: true },
+ // },
+
+ // ]
+ // },
+ {
+ path: '/room-auth',
+ component: Layout,
+ hidden: true,
+ children: [
+ {
+ path: 'room/:roomId(\\w+)',
+ component: () => import('@/views/roomManagement/authRoom.vue'),
+ name: 'AuthRoom',
+ meta: { title: '参与者信息', activeMenu: '/roomManagement/RoomManagementPage', affix: true, icon: '' }
+ }
+ ]
+ },
+ {
+ path: '/user-auth',
+ component: Layout,
+ hidden: true,
+ children: [
+ {
+ path: 'role/:userId(\\w+)',
+ component: () => import('@/views/userManagement/authRole.vue'),
+ name: 'AuthRole',
+ meta: { title: '分配角色', activeMenu: '/userManagement/UserManagementPage', affix: true, icon: '' }
+ }
+ ]
+ },
+ // {
+ // path: '/role-auth',
+ // component: Layout,
+ // hidden: true,
+ // children: [
+ // {
+ // path: 'menu/:roleId(\\w+)',
+ // component: () => import('@/views/roleManagement/authMenu.vue'),
+ // name: 'AuthUser',
+ // meta: { title: '分配菜单',activeMenu: '/roleManagement/RoleManagementPage', affix: true , icon: '' }
+ // }
+ // ]
+ // },
+ // {
+ // path: "/system",
+ // redirect: "/system/menuManagement",
+ // component: Layout,
+ // meta: { title: "系统管理", icon: "system", affix: true },
+ // children: [
+ // {
+ // path: "menuManagement",
+ // name: "MenuManagement",
+ // component: () => import("@/views/menuManagement/index.vue"),
+ // meta: { title: "菜单管理", icon: "menu", affix: true },
+ // },
+ // {
+ // path: "userManagement",
+ // name: "UserManagement",
+ // component: () => import("@/views/userManagement/index.vue"),
+ // meta: { title: "用户管理", icon: "user", affix: true },
+ // }
+ // ]
+ // },
// 错误页面路由
{
path: "/:pathMatch(.*)*",
@@ -67,73 +176,12 @@ export const constantRoutes = [
component: () => import("@/views/error/401.vue"),
hidden: true,
meta: { title: "401未授权" }
- },
- {
- path: '/assistWx',
- component: () => import('@/views/coordinate/personnelList/components/assistWx/index.vue'),
- meta: { title: "白板" },
- hidden: true,
- },
+ },
]
export const dynamicRoutes = [
]
-
-// const router = createRouter({
-// history: createWebHashHistory(import.meta.env.BASE_URL),
-// routes: [
-// // {
-// // path: '/',
-// // component: () => import("@/views/custom/tabulaRase/index.vue"),
-// // },
-// {
-// path: '/',
-// redirect: '/login', // 这里做重定向
-// },
-// {
-// path: '/whiteboard',
-// component: () => import('@/views/custom/tabulaRase/index.vue'),
-// },
-// {
-// path: "/login",
-// component: () => import("@/views/login.vue"),
-// },
-// {
-// path: "/coordinate",
-// component: Layout,
-// meta: { title: "远程协作", icon: "client", affix: true },
-// children: [
-// {
-// path: '',
-// name: "Coordinate",
-// component: () => import("@/views/coordinate/personnelList/index.vue")
-// }
-// ]
-// },
-// {
-// path: "/conferencingRoom",
-// children: [
-// {
-// path: '',
-// name: "ConferencingRoom",
-// component: () => import("@/views/conferencingRoom/index.vue")
-// }
-// ]
-// },
-
-
-// // 错误页面路由
-// {
-// path: "/:pathMatch(.*)*",
-// component: () => import("@/views/error/404.vue"),
-// },
-// {
-// path: "/401",
-// component: () => import("@/views/error/401.vue"),
-// }
-// ],
-// })
const router = createRouter({
// history: createWebHistory(import.meta.env.VITE_BASE_PATH),
history: createWebHashHistory(import.meta.env.BASE_URL),
diff --git a/src/stores/modules/app.js b/src/stores/modules/app.js
index 0b018e2..4e2b93c 100644
--- a/src/stores/modules/app.js
+++ b/src/stores/modules/app.js
@@ -6,7 +6,7 @@ export const useAppStore = defineStore(
{
state: () => ({
sidebar: {
- opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
+ opened: true,
withoutAnimation: false,
hide: false
},
@@ -14,20 +14,14 @@ export const useAppStore = defineStore(
size: Cookies.get('size') || 'default'
}),
actions: {
- toggleSideBar(withoutAnimation) {
+ toggleSideBar(withoutAnimation) {
if (this.sidebar.hide) {
return false;
}
- this.sidebar.opened = !this.sidebar.opened
- this.sidebar.withoutAnimation = withoutAnimation
- if (this.sidebar.opened) {
- // Cookies.set('sidebarStatus', 1)
- } else {
- // Cookies.set('sidebarStatus', 0)
- }
+ this.sidebar.opened = !this.sidebar.opened
+ this.sidebar.withoutAnimation = withoutAnimation
},
- closeSideBar({ withoutAnimation }) {
- // Cookies.set('sidebarStatus', 0)
+ closeSideBar({ withoutAnimation }) {
this.sidebar.opened = false
this.sidebar.withoutAnimation = withoutAnimation
},
@@ -38,7 +32,7 @@ export const useAppStore = defineStore(
this.size = size;
Cookies.set('size', size)
},
- toggleSideBarHide(status) {
+ toggleSideBarHide(status) {
this.sidebar.hide = status
}
}
diff --git a/src/stores/modules/settings.js b/src/stores/modules/settings.js
index 30c0766..e51aea8 100644
--- a/src/stores/modules/settings.js
+++ b/src/stores/modules/settings.js
@@ -11,7 +11,7 @@ export const useSettingsStore = defineStore(
{
state: () => ({
title: '',
- theme: storageSetting.theme === undefined ? '#434343' : storageSetting.theme,
+ theme: storageSetting.theme === undefined ? '#409EFF' : storageSetting.theme,
sideTheme: storageSetting.sideTheme === undefined ? sideTheme : storageSetting.sideTheme,
showSettings: showSettings,
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
diff --git a/src/stores/modules/user.js b/src/stores/modules/user.js
index bb698e0..995138e 100644
--- a/src/stores/modules/user.js
+++ b/src/stores/modules/user.js
@@ -1,5 +1,5 @@
-import { login, logout, getInfo } from '@/api/login.js'
-import { getToken, setToken, removeToken } from '@/utils/auth.js'
+import { login, logout, getInfo ,getAvatarsApi} from '@/api/login.js'
+import { getToken, setToken, removeToken ,getUserInfo} from '@/utils/auth.js'
import { defineStore } from 'pinia'
import { ElMessage } from 'element-plus'
@@ -10,7 +10,7 @@ export const useUserStore = defineStore(
token: getToken(),
name: '',
avatar: '',
- roles: '',
+ roles: '',
}),
actions: {
// 登录
@@ -23,9 +23,14 @@ export const useUserStore = defineStore(
ElMessage({ message: res.meta?.message || '登录失败', type: 'error' });
return Promise.reject(res);
}
+ if(!res.data.user.is_admin){
+ ElMessage({ message: '暂无权限登录,请联系管理员', type: 'error' });
+ return Promise.reject(res);
+ }
const { token, user } = res.data;
this.name = user.name;
sessionStorage.setItem('userData', JSON.stringify(user));
+ await this.getAvatars();
setToken(token);
this.token = token;
@@ -53,6 +58,18 @@ export const useUserStore = defineStore(
reject(error instanceof Error ? error : new Error('解析用户数据失败'));
}
});
+ },
+ // 获取用户头像
+ async getAvatars() {
+ try {
+ const userData = await getUserInfo()
+ const res = await getAvatarsApi(userData.uid);
+ const url = URL.createObjectURL(res);
+ this.avatar = url;
+ } catch (error) {
+ console.error('获取头像失败:', error);
+ throw error;
+ }
},
// 退出系统
async logOut() {
diff --git a/src/utils/scroll-to.js b/src/utils/scroll-to.js
new file mode 100644
index 0000000..6857b17
--- /dev/null
+++ b/src/utils/scroll-to.js
@@ -0,0 +1,59 @@
+const easeInOutQuad = (t, b, c, d) => {
+ t /= d / 2;
+ if (t < 1) {
+ return (c / 2) * t * t + b;
+ }
+ t--;
+ return (-c / 2) * (t * (t - 2) - 1) + b;
+};
+
+const requestAnimFrame = (function () {
+ return (
+ window.requestAnimationFrame ||
+ (window).webkitRequestAnimationFrame ||
+ (window).mozRequestAnimationFrame ||
+ function (callback) {
+ window.setTimeout(callback, 1000 / 60);
+ }
+ );
+})();
+
+/**
+ *
+ * @param {number} amount
+ */
+const move = (amount) => {
+ document.documentElement.scrollTop = amount;
+ (document.body.parentNode).scrollTop = amount;
+ document.body.scrollTop = amount;
+};
+
+const position = () => {
+ return document.documentElement.scrollTop || (document.body.parentNode).scrollTop || document.body.scrollTop;
+};
+
+/**
+ * @param {number} to
+ * @param {number} duration
+ * @param {Function} callback
+ */
+export const scrollTo = (to, duration, callback) => {
+ const start = position();
+ const change = to - start;
+ const increment = 20;
+ let currentTime = 0;
+ duration = typeof duration === 'undefined' ? 500 : duration;
+ const animateScroll = function () {
+ currentTime += increment;
+ const val = easeInOutQuad(currentTime, start, change, duration);
+ move(val);
+ if (currentTime < duration) {
+ requestAnimFrame(animateScroll);
+ } else {
+ if (callback && typeof callback === 'function') {
+ callback();
+ }
+ }
+ };
+ animateScroll();
+};
diff --git a/src/utils/whiteboardSync.js b/src/utils/whiteboardSync.js
deleted file mode 100644
index 713fbb4..0000000
--- a/src/utils/whiteboardSync.js
+++ /dev/null
@@ -1,99 +0,0 @@
-import { mqttClient } from "./mqtt";
-import { getWhiteboardShapes, getWhiteboardHistory } from "@/views/custom/api";
-import { useMeterStore } from '@/stores/modules/meter';
-import { encode, decode } from '@msgpack/msgpack'
-import { ElMessage } from 'element-plus';
-import { emitter } from "@/utils/bus.js";
-const meterStore = useMeterStore();
-meterStore.initUdid();
-
-let isRemote = false;
-let canvasInstance = null;
-
-// 获取本地缓存 userData
-function getLocalUserData() {
- const dataStr = sessionStorage.getItem('userData');
- if (!dataStr) return null;
- try {
- return JSON.parse(dataStr);
- } catch (e) {
- console.error("解析 userData 失败:", e);
- return null;
- }
-}
-
-export const WhiteboardSync = {
- async init(canvas, roomUid) {
- if (!canvas || !roomUid) return;
- canvasInstance = canvas;
-
- const localUser = getLocalUserData();
- const localUid = localUser?.uid;
- try {
- // 先连接 MQTT
- await mqttClient.connect(meterStore.getSudid());
- // 获取历史数据
- const res = await getWhiteboardHistory({ after_timestamp: 0 }, roomUid);
- if (res.meta.code === 200 && res.data.shapes.length > 0) {
- canvasInstance.addShape(res.data.shapes);
- }else if(res.meta.code === 401){
- emitter.emit('whiteboardFailed',true);
- }
-
- // 订阅当前房间
- const topic = `xSynergy/ROOM/${roomUid}/whiteboard/#`;
- mqttClient.subscribe(topic, async (shapeData) => {
- const shapeDataNew = JSON.parse(shapeData.toString())
- // const shapeDataNew = decode(message);
- try {
- isRemote = true;
- // 如果 shape 来自本地用户,则跳过
- if (shapeDataNew.user_uid === localUid) return;
- const res = await getWhiteboardHistory({ after_timestamp: shapeDataNew.created_at }, roomUid);
- if (res.meta.code === 200) {
- canvasInstance.addShape(res.data.shapes);
- } else {
- ElMessage.error("获取历史数据失败");
- console.error("获取历史数据失败");
- }
- } catch (e) {
- console.error("处理MQTT数据失败:", e);
- } finally {
- isRemote = false;
- }
- });
- } catch (err) {
- console.log("初始化多人同步失败:", err)
- // console.error("❌ 连接或订阅失败:", err);
- }
-
- // 监听画布事件:新增图形
- canvas.on('drawingEnd', async (shape) => {
- // 如果来自远程,或不是需要同步的类型,跳过
- if (isRemote || !['pencil', 'line', 'rectangle', 'circle', 'eraser'].includes(shape.type)) return;
-
- // 如果是本地用户自己的 shape,则不调用接口
- if (shape.user_uid && shape.user_uid === localUid) return;
-
- shape.room_uid = roomUid;
- try {
- await getWhiteboardShapes(shape, roomUid);
- } catch (err) {
- ElMessage.error("提交形状失败");
- console.error("提交形状失败:", err);
- }
- });
-
- // 监听画布事件:清空
- canvas.on('clear', async () => {
- if (!isRemote) {
- try {
- // TODO: 调用接口,后端再发 MQTT
- // await clearWhiteboard(roomUid);
- } catch (err) {
- console.error("提交清空失败:", err);
- }
- }
- });
- },
-};
diff --git a/src/utils/whiteboardSync_old.js b/src/utils/whiteboardSync_old.js
deleted file mode 100644
index 4023814..0000000
--- a/src/utils/whiteboardSync_old.js
+++ /dev/null
@@ -1,103 +0,0 @@
-import { mqttClient } from "./mqtt";
-import { getWhiteboardShapes, getWhiteboardHistory } from "@/views/custom/api";
-import { useMeterStore } from '@/stores/modules/meter';
-import { encode, decode } from '@msgpack/msgpack'
-import { ElMessage } from 'element-plus';
-
-const meterStore = useMeterStore();
-meterStore.initUdid();
-
-let isRemote = false;
-let canvasInstance = null;
-
-// 获取本地缓存 userData
-function getLocalUserData() {
- const dataStr = sessionStorage.getItem('userData');
- if (!dataStr) return null;
- try {
- return JSON.parse(dataStr);
- } catch (e) {
- console.error("解析 userData 失败:", e);
- return null;
- }
-}
-
-export const WhiteboardSync = {
- async init(canvas, roomUid) {
- if (!canvas || !roomUid) return;
- console.log('初始化多人同步:', roomUid);
- canvasInstance = canvas;
-
- const localUser = getLocalUserData();
- const localUid = localUser?.uid;
- try {
- // 先连接 MQTT
- await mqttClient.connect(meterStore.getSudid());
- console.log("✅ MQTT 已连接");
-
- // 获取历史数据
- const res = await getWhiteboardHistory({ after_timestamp: 0 }, roomUid);
- if (res.meta.code === 200 && res.data.shapes.length > 0) {
- canvasInstance.addShape(res.data.shapes);
- }
-
- // 订阅当前房间
- const topic = `xSynergy/ROOM/${roomUid}/whiteboard/#`;
- mqttClient.subscribe(topic, async (shapeData) => {
- const shapeDataNew = JSON.parse(shapeData.toString())
- // const shapeDataNew = decode(message);
- // console.log(shapeDataNew, '格式解码')
- try {
- isRemote = true;
- // 如果 shape 来自本地用户,则跳过
- if (shapeDataNew.user_uid === localUid) return;
- const res = await getWhiteboardHistory({ after_timestamp: shapeDataNew.created_at }, roomUid);
- if (res.meta.code === 200) {
- canvasInstance.addShape(res.data.shapes);
- } else {
- ElMessage.error("获取历史数据失败");
- console.error("获取历史数据失败");
- }
- } catch (e) {
- console.error("处理MQTT数据失败:", e);
- } finally {
- isRemote = false;
- }
- });
-
- console.log("✅ 已订阅:", topic);
- } catch (err) {
- console.log("初始化多人同步失败:", err)
- // console.error("❌ 连接或订阅失败:", err);
- }
-
- // 监听画布事件:新增图形
- canvas.on('drawingEnd', async (shape) => {
- // 如果来自远程,或不是需要同步的类型,跳过
- if (isRemote || !['pencil', 'line', 'rectangle', 'circle', 'eraser'].includes(shape.type)) return;
-
- // 如果是本地用户自己的 shape,则不调用接口
- if (shape.user_uid && shape.user_uid === localUid) return;
-
- shape.room_uid = roomUid;
- try {
- await getWhiteboardShapes(shape, roomUid);
- } catch (err) {
- ElMessage.error("提交形状失败");
- console.error("提交形状失败:", err);
- }
- });
-
- // 监听画布事件:清空
- canvas.on('clear', async () => {
- if (!isRemote) {
- try {
- // TODO: 调用接口,后端再发 MQTT
- // await clearWhiteboard(roomUid);
- } catch (err) {
- console.error("提交清空失败:", err);
- }
- }
- });
- },
-};
diff --git a/src/views/conferencingRoom/business/index.js b/src/views/conferencingRoom/business/index.js
deleted file mode 100644
index 5d39d7a..0000000
--- a/src/views/conferencingRoom/business/index.js
+++ /dev/null
@@ -1,107 +0,0 @@
-import { ElMessage } from 'element-plus';
-export function errorHandling(error,type) {
- switch (error.name) {
- case 'NotAllowedError':
- ElMessage.error(`用户拒绝了权限请求,请允许此网站使用${type}权限`);
- break;
- case 'NotFoundError':
- ElMessage.error(`未检测到可用的${type}设备,请检查${type}是否已正确连接`);
- break;
- case 'NotSupportedError':
- ElMessage.error(`当前浏览器不支持${type}功能,请使用现代浏览器如Chrome、Firefox或Edge`);
- break;
- case 'NotReadableError':
- ElMessage.error(`${type}设备正被其他应用程序占用,请关闭其他使用${type}的应用后重试`);
- break;
- case 'OverconstrainedError':
- ElMessage.error(`${type}配置不兼容,请尝试调整${type}设置`);
- break;
- default:
- ElMessage.error('服务错误,请刷新重试');
- }
-}
-
-// 处理数据接收事件
-export function handleDataReceived(payload, participant, kind) {
- try {
- const decoder = new TextDecoder();
- const strData = decoder.decode(payload);
- ElMessage.info(`收到消息 from ${participant.identity}: ${strData}`);
- } catch (error) {
- console.error('处理接收消息失败:', error);
- }
-}
-
-export function handleReconnected() {
- ElMessage.success('已重新连接到房间');
-}
-
-// 获取设备名称
-export function getDeviceName(devices, deviceId) {
- const device = devices.find(d => d.deviceId === deviceId);
- return device ? (device.label || '未知设备') : '未知设备';
-}
-
-export function handleVideoLoaded(identity, type) {
- // console.log(`视频加载完成: ${identity}的${type}视频`);
-}
-
-export function handleConnectionStateChanged(state) {
- // console.log('连接状态改变:', state);
-}
-
-// 平滑曲线绘制函数
-export function drawSmoothCurve(ctx, path) {
- if (path.length < 3) {
- // 如果点太少,直接绘制直线
- ctx.beginPath();
- ctx.moveTo(path[0].x, path[0].y);
- for (let i = 1; i < path.length; i++) {
- ctx.lineTo(path[i].x, path[i].y);
- }
- return;
- }
-
- ctx.beginPath();
- ctx.moveTo(path[0].x, path[0].y);
-
- const threshold = 5; // 距离阈值,用于控制平滑度
-
- for (let i = 1; i < path.length - 2;) {
- let a = 1;
- // 寻找下一个足够远的点
- while (i + a < path.length - 2 &&
- Math.sqrt(Math.pow(path[i].x - path[i + a].x, 2) +
- Math.pow(path[i].y - path[i + a].y, 2)) < threshold) {
- a++;
- }
-
- const xc = (path[i].x + path[i + a].x) / 2;
- const yc = (path[i].y + path[i + a].y) / 2;
-
- ctx.quadraticCurveTo(path[i].x, path[i].y, xc, yc);
- i += a;
- }
-
- // 连接最后两个点
- ctx.lineTo(path[path.length - 1].x, path[path.length - 1].y);
-}
-
-//计算文件的SHA1值
-export async function calculateFileSHA1(file) {
- const arrayBuffer = await file.arrayBuffer();
- const hashBuffer = await crypto.subtle.digest('SHA-1', arrayBuffer);
- const hashArray = Array.from(new Uint8Array(hashBuffer));
- const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
- return hashHex;
-}
-
-// 用于比较两个对象是否相等
-export function simpleDeepEqual(obj1, obj2) {
- return JSON.stringify(obj1) === JSON.stringify(obj2);
-}
-
-// 生成唯一ID
-export function generateElementId() {
- return `laser_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
-}
\ No newline at end of file
diff --git a/src/views/conferencingRoom/components/InviterJoinRoom/index.vue b/src/views/conferencingRoom/components/InviterJoinRoom/index.vue
deleted file mode 100644
index 1c9cffa..0000000
--- a/src/views/conferencingRoom/components/InviterJoinRoom/index.vue
+++ /dev/null
@@ -1,366 +0,0 @@
-
-
-
- 请选择要加入房间的人员
-
-
-
-
-
-
-
-
-
-
-
-
- {{ user.name }}
-
-
-
-
-
-
-
-
-
-
- 👤
- 📁
- {{ data.name }}
- ({{ data.users_count }})
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/conferencingRoom/components/fileUpload/browseFile.vue b/src/views/conferencingRoom/components/fileUpload/browseFile.vue
deleted file mode 100644
index b6cd4af..0000000
--- a/src/views/conferencingRoom/components/fileUpload/browseFile.vue
+++ /dev/null
@@ -1,871 +0,0 @@
-
-
-
-
-
-
-
-
-
-
{{ loadingText }}
-
-
-
-
-
-
-
-
-
{{ conversionMessage }}
-
-
-
-
-
-
-
-
-
正在下载文件,请稍候...
-
- 下载进度: {{ downloadProgress }}%
-
-
-
-
-
-
-
-
-
文件预览失败
-
{{ errorMessage }}
-
重试
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 上一页
-
-
- {{ currentPage }} / {{ pageCount }}
-
-
- 下一页
-
-
-
-
-
-
-
-
-
-
-
-
-
- 您的浏览器不支持视频播放
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 上一页
-
-
- {{ currentPage }} / {{ pageCount }}
-
-
- 下一页
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
不支持在线预览此文件类型
-
{{ fileName }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/conferencingRoom/components/fileUpload/fileList.vue b/src/views/conferencingRoom/components/fileUpload/fileList.vue
deleted file mode 100644
index 4171201..0000000
--- a/src/views/conferencingRoom/components/fileUpload/fileList.vue
+++ /dev/null
@@ -1,268 +0,0 @@
-
-
-
-
- 文件列表
-
-
-
-
-
-
-
- 上传文件
-
-
-
-
-
-
-
-
-
-
-
-
-
{{ item.file_name }}
-
-
-
-
- 预览
- 下载
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/conferencingRoom/components/fileUpload/pollingBrowseFile.vue b/src/views/conferencingRoom/components/fileUpload/pollingBrowseFile.vue
deleted file mode 100644
index 6b98949..0000000
--- a/src/views/conferencingRoom/components/fileUpload/pollingBrowseFile.vue
+++ /dev/null
@@ -1,726 +0,0 @@
-
-
-
-
-
-
-
-
-
-
{{ loadingText }}
-
-
-
-
-
-
-
-
正在下载文件,请稍候...
-
- 下载进度: {{ downloadProgress }}%
-
-
-
-
-
-
-
-
-
文件预览失败
-
{{ errorMessage }}
-
重试
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 上一页
-
-
- {{ currentPage }} / {{ pageCount }}
-
-
- 下一页
-
-
-
-
-
-
-
-
-
-
-
-
-
- 您的浏览器不支持视频播放
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 上一页
-
-
- {{ currentPage }} / {{ pageCount }}
-
-
- 下一页
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
不支持在线预览此文件类型
-
{{ fileName }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/conferencingRoom/components/fileUpload/upLoadFile.vue b/src/views/conferencingRoom/components/fileUpload/upLoadFile.vue
deleted file mode 100644
index 2d2edbc..0000000
--- a/src/views/conferencingRoom/components/fileUpload/upLoadFile.vue
+++ /dev/null
@@ -1,293 +0,0 @@
-
-
-
-
-
-
- {{ uploadLoading ? '上传中...' : '上传文件' }}
-
-
-
-
- 请上传格式为:
-
- {{ acceptString }}
-
- 的文件
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/conferencingRoom/index.vue b/src/views/conferencingRoom/index.vue
deleted file mode 100644
index ae2c507..0000000
--- a/src/views/conferencingRoom/index.vue
+++ /dev/null
@@ -1,3803 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 暂无视频流
-
-
-
- {{ enlargedParticipant.identity === hostUid ? '我' : enlargedParticipant.identity }}
-
-
-
-
-
-
- 激光笔模式中
-
-
-
-
-
-
-
-
-
-
-
- {{ screenSharingUser }}
-
-
- 激光笔模式中
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ hostUid }}
-
-
-
-
-
-
-
- 摄像头已关闭
-
-
-
-
-
-
-
-
-
-
-
handleVideoLoaded(participant.identity, 'camera')">
-
-
-
-
- 摄像头已关闭
-
-
-
- {{ participant.identity }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ cameraEnabled ? '关闭摄像头' : '开启摄像头' }}
-
-
-
-
-
-
-
-
-
-
- {{ device.label || `摄像头 ${cameraDevices.indexOf(device) + 1}` }}
-
-
-
-
- 刷新设备列表
-
-
-
-
-
-
-
- {{ microphoneEnabled ? '关闭麦克风' : '开启麦克风' }}
-
-
-
-
-
-
-
-
-
-
- {{ device.label || `麦克风 ${microphoneDevices.indexOf(device) + 1}` }}
-
-
-
-
- 刷新设备列表
-
-
-
-
-
-
-
-
- 停止共享
- 他人共享中
- 共享屏幕
-
-
-
-
- {{ isWhiteboardActive ? '退出白板' : '共享白板' }}
-
-
- {{ isLaserPointerActive ? '关闭激光笔' : '激光笔' }}
-
-
- 文件
-
-
- 邀请人员
-
-
- 离开会议
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/conferencingRoom/index_old.vue b/src/views/conferencingRoom/index_old.vue
deleted file mode 100644
index 68315bf..0000000
--- a/src/views/conferencingRoom/index_old.vue
+++ /dev/null
@@ -1,2808 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ screenSharingUser }}
-
-
- 激光笔模式中
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ hostUid }}
-
-
-
-
-
-
-
- 摄像头已关闭
-
-
-
-
-
-
-
-
-
-
-
-
handleVideoLoaded(participant.identity, 'camera')">
-
-
-
-
- 暂无视频流
-
-
-
-
-
{{ participant.identity }}
-
-
-
- 暂无视频流
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ cameraEnabled ? '关闭摄像头' : '开启摄像头' }}
-
-
-
-
-
-
-
-
-
-
- {{ device.label || `摄像头 ${cameraDevices.indexOf(device) + 1}` }}
-
-
-
-
- 刷新设备列表
-
-
-
-
-
-
-
- {{ microphoneEnabled ? '关闭麦克风' : '开启麦克风' }}
-
-
-
-
-
-
-
-
-
-
- {{ device.label || `麦克风 ${microphoneDevices.indexOf(device) + 1}` }}
-
-
-
-
- 刷新设备列表
-
-
-
-
-
-
- 停止共享
- 他人共享中
- 共享屏幕
-
-
- {{ isWhiteboardActive ? '退出白板' : '共享白板' }}
-
-
- {{ isLaserPointerActive ? '关闭激光笔' : '激光笔' }}
-
-
- 文件
-
-
- 邀请人员
-
-
- 离开会议
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/conferencingRoom/latest.vue b/src/views/conferencingRoom/latest.vue
deleted file mode 100644
index fb2b169..0000000
--- a/src/views/conferencingRoom/latest.vue
+++ /dev/null
@@ -1,3547 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 暂无视频流
-
-
-
- {{ enlargedParticipant.identity === hostUid ? '我' : enlargedParticipant.identity }}
-
-
-
-
-
-
- 激光笔模式中
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ screenSharingUser }}
-
-
- 激光笔模式中
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ hostUid }}
-
-
-
-
-
-
-
- 摄像头已关闭
-
-
-
-
-
-
-
-
-
-
-
handleVideoLoaded(participant.identity, 'camera')">
-
-
-
-
- 摄像头已关闭
-
-
-
- {{ participant.identity }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ cameraEnabled ? '关闭摄像头' : '开启摄像头' }}
-
-
-
-
-
-
-
-
-
-
- {{ device.label || `摄像头 ${cameraDevices.indexOf(device) + 1}` }}
-
-
-
-
- 刷新设备列表
-
-
-
-
-
-
-
- {{ microphoneEnabled ? '关闭麦克风' : '开启麦克风' }}
-
-
-
-
-
-
-
-
-
-
- {{ device.label || `麦克风 ${microphoneDevices.indexOf(device) + 1}` }}
-
-
-
-
- 刷新设备列表
-
-
-
-
-
-
- 停止共享
- 他人共享中
- 共享屏幕
-
-
- {{ isWhiteboardActive ? '退出白板' : '共享白板' }}
-
-
- {{ isLaserPointerActive ? '关闭激光笔' : '激光笔' }}
-
-
- 文件
-
-
- 邀请人员
-
-
- 离开会议
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/conferencingRoom/pathTransit.vue b/src/views/conferencingRoom/pathTransit.vue
deleted file mode 100644
index 6bb0774..0000000
--- a/src/views/conferencingRoom/pathTransit.vue
+++ /dev/null
@@ -1,3175 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 暂无视频流
-
-
-
- {{ enlargedParticipant.identity === hostUid ? '我' : enlargedParticipant.identity }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ screenSharingUser }}
-
-
- 激光笔模式中
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ hostUid }}
-
-
-
-
-
-
-
- 摄像头已关闭
-
-
-
-
-
-
-
-
-
-
-
handleVideoLoaded(participant.identity, 'camera')">
-
-
-
-
- 暂无视频流
-
-
-
-
-
{{ participant.identity }}
-
-
-
- 暂无视频流
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ cameraEnabled ? '关闭摄像头' : '开启摄像头' }}
-
-
-
-
-
-
-
-
-
-
- {{ device.label || `摄像头 ${cameraDevices.indexOf(device) + 1}` }}
-
-
-
-
- 刷新设备列表
-
-
-
-
-
-
-
- {{ microphoneEnabled ? '关闭麦克风' : '开启麦克风' }}
-
-
-
-
-
-
-
-
-
-
- {{ device.label || `麦克风 ${microphoneDevices.indexOf(device) + 1}` }}
-
-
-
-
- 刷新设备列表
-
-
-
-
-
-
- 停止共享
- 他人共享中
- 共享屏幕
-
-
- {{ isWhiteboardActive ? '退出白板' : '共享白板' }}
-
-
- {{ isLaserPointerActive ? '关闭激光笔' : '激光笔' }}
-
-
- 文件
-
-
- 邀请人员
-
-
- 离开会议
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/conferencingRoom/text.vue b/src/views/conferencingRoom/text.vue
deleted file mode 100644
index 0b69db1..0000000
--- a/src/views/conferencingRoom/text.vue
+++ /dev/null
@@ -1,3519 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 暂无视频流
-
-
-
- {{ enlargedParticipant.identity === hostUid ? '我' : enlargedParticipant.identity }}
-
-
-
-
-
-
- 激光笔模式中
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ screenSharingUser }}
-
-
- 激光笔模式中
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ hostUid }}
-
-
-
-
-
-
-
- 摄像头已关闭
-
-
-
-
-
-
-
-
-
-
-
handleVideoLoaded(participant.identity, 'camera')">
-
-
-
-
- 摄像头已关闭
-
-
-
- {{ participant.identity }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ cameraEnabled ? '关闭摄像头' : '开启摄像头' }}
-
-
-
-
-
-
-
-
-
-
- {{ device.label || `摄像头 ${cameraDevices.indexOf(device) + 1}` }}
-
-
-
-
- 刷新设备列表
-
-
-
-
-
-
-
- {{ microphoneEnabled ? '关闭麦克风' : '开启麦克风' }}
-
-
-
-
-
-
-
-
-
-
- {{ device.label || `麦克风 ${microphoneDevices.indexOf(device) + 1}` }}
-
-
-
-
- 刷新设备列表
-
-
-
-
-
-
- 停止共享
- 他人共享中
- 共享屏幕
-
-
- {{ isWhiteboardActive ? '退出白板' : '共享白板' }}
-
-
- {{ isLaserPointerActive ? '关闭激光笔' : '激光笔' }}
-
-
- 文件
-
-
- 邀请人员
-
-
- 离开会议
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/conferencingRoom/transit.vue b/src/views/conferencingRoom/transit.vue
deleted file mode 100644
index 664ca84..0000000
--- a/src/views/conferencingRoom/transit.vue
+++ /dev/null
@@ -1,3325 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 暂无视频流
-
-
-
- {{ enlargedParticipant.identity === hostUid ? '我' : enlargedParticipant.identity }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ screenSharingUser }}
-
-
- 激光笔模式中
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ hostUid }}
-
-
-
-
-
-
-
- 摄像头已关闭
-
-
-
-
-
-
-
-
-
-
-
handleVideoLoaded(participant.identity, 'camera')">
-
-
-
-
- 摄像头已关闭
-
-
-
- {{ participant.identity }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ cameraEnabled ? '关闭摄像头' : '开启摄像头' }}
-
-
-
-
-
-
-
-
-
-
- {{ device.label || `摄像头 ${cameraDevices.indexOf(device) + 1}` }}
-
-
-
-
- 刷新设备列表
-
-
-
-
-
-
-
- {{ microphoneEnabled ? '关闭麦克风' : '开启麦克风' }}
-
-
-
-
-
-
-
-
-
-
- {{ device.label || `麦克风 ${microphoneDevices.indexOf(device) + 1}` }}
-
-
-
-
- 刷新设备列表
-
-
-
-
-
-
- 停止共享
- 他人共享中
- 共享屏幕
-
-
- {{ isWhiteboardActive ? '退出白板' : '共享白板' }}
-
-
- {{ isLaserPointerActive ? '关闭激光笔' : '激光笔' }}
-
-
- 文件
-
-
- 邀请人员
-
-
- 离开会议
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/conferencingRoom/transits.vue b/src/views/conferencingRoom/transits.vue
deleted file mode 100644
index ef99f77..0000000
--- a/src/views/conferencingRoom/transits.vue
+++ /dev/null
@@ -1,3326 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 暂无视频流
-
-
-
- {{ enlargedParticipant.identity === hostUid ? '我' : enlargedParticipant.identity }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ screenSharingUser }}
-
-
- 激光笔模式中
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ hostUid }}
-
-
-
-
-
-
-
- 摄像头已关闭
-
-
-
-
-
-
-
-
-
-
-
handleVideoLoaded(participant.identity, 'camera')">
-
-
-
-
- 摄像头已关闭
-
-
-
- {{ participant.identity }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ cameraEnabled ? '关闭摄像头' : '开启摄像头' }}
-
-
-
-
-
-
-
-
-
-
- {{ device.label || `摄像头 ${cameraDevices.indexOf(device) + 1}` }}
-
-
-
-
- 刷新设备列表
-
-
-
-
-
-
-
- {{ microphoneEnabled ? '关闭麦克风' : '开启麦克风' }}
-
-
-
-
-
-
-
-
-
-
- {{ device.label || `麦克风 ${microphoneDevices.indexOf(device) + 1}` }}
-
-
-
-
- 刷新设备列表
-
-
-
-
-
-
- 停止共享
- 他人共享中
- 共享屏幕
-
-
- {{ isWhiteboardActive ? '退出白板' : '共享白板' }}
-
-
- {{ isLaserPointerActive ? '关闭激光笔' : '激光笔' }}
-
-
- 文件
-
-
- 邀请人员
-
-
- 离开会议
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/conferencingRoom/utils/request.js b/src/views/conferencingRoom/utils/request.js
deleted file mode 100644
index 8ca56ea..0000000
--- a/src/views/conferencingRoom/utils/request.js
+++ /dev/null
@@ -1,186 +0,0 @@
-import axios from "axios";
-import {
- ElNotification,
- ElMessageBox,
- ElMessage,
-} from "element-plus";
-import { tansParams } from "@/utils/ruoyi";
-import cache from "@/plugins/cache";
-import { getToken, removeToken } from "@/utils/auth";
-import router from '@/router';
-import { useMeterStore } from '@/stores/modules/meter'
-
-axios.defaults.headers["Content-Type"] = "application/x-www-form-urlencoded";
-const meterStore = useMeterStore()
-meterStore.initUdid()
-// 创建axios实例
-const service = axios.create({
- // axios中请求配置有baseURL选项,表示请求URL公共部分
- baseURL: import.meta.env.VITE_APP_BASE_API_livekit,
- // 超时
- timeout: 10000,
-});
-
-// request拦截器
-service.interceptors.request.use(
- (config) => {
- // 是否需要防止数据重复提交
- const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
- if (meterStore.getSudid()) {
- config.headers["X-User-Agent"] = `gxtech/web 1.0.0: c=GxTech, udid=${meterStore.getSudid()}, sv=15.4.1, app=stt`;
- }
- // get请求映射params参数
- if (config.method === "get" && config.params) {
- let url = config.url + "?" + tansParams(config.params);
- url = url.slice(0, -1);
- config.params = {};
- config.url = url;
- }
- if (
- !isRepeatSubmit &&
- (config.method === "post" || config.method === "put")
- ) {
- const requestObj = {
- url: config.url,
- data:
- typeof config.data === "object"
- ? JSON.stringify(config.data)
- : config.data,
- time: new Date().getTime(),
- };
- const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小
- const limitSize = 5 * 1024 * 1024; // 限制存放数据5M
- if (requestSize >= limitSize) {
- console.warn(
- `[${config.url}]: ` +
- "请求数据大小超出允许的5M限制,无法进行防重复提交验证。"
- );
- return config;
- }
- const sessionObj = cache.session.getJSON("sessionObj");
- if (
- sessionObj === undefined ||
- sessionObj === null ||
- sessionObj === ""
- ) {
- cache.session.setJSON("sessionObj", requestObj);
- } else {
- const s_url = sessionObj.url; // 请求地址
- const s_data = sessionObj.data; // 请求数据
- const s_time = sessionObj.time; // 请求时间
- const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
- if (
- s_data === requestObj.data &&
- requestObj.time - s_time < interval &&
- s_url === requestObj.url
- ) {
- const message = "数据正在处理,请勿重复提交";
- console.warn(`[${s_url}]: ` + message);
- return Promise.reject(new Error(message));
- } else {
- cache.session.setJSON("sessionObj", requestObj);
- }
- }
- }
- return config;
- },
- (error) => {
- Promise.reject(error);
- }
-);
-
-service.interceptors.response.use(
- (response) => {
- // 1. 检查响应是否存在
- if (!response) {
- ElMessage.error('无响应数据');
- return Promise.reject(new Error('无响应数据'));
- }
- // 2. 安全获取响应数据和状态码
- const responseData = response.data || {};
- const statusCode = response.status;
- const businessCode = responseData.meta?.code || statusCode;
-
- // 3. 二进制数据直接返回
- if (
- response.request.responseType === 'blob' ||
- response.request.responseType === 'arraybuffer'
- ) {
- return responseData;
- }
-
- // 4. 根据业务码处理不同情况
- switch (businessCode) {
- case 200:
- case 201:
- return Promise.resolve(responseData);
-
- case 401:
- console.log('未授权', responseData)
- return Promise.resolve(responseData);
- // return handleUnauthorized().then(() => {
- // return Promise.reject({ code: 401, message: '未授权' });
- // });
-
- case 500:
- const serverErrorMsg = responseData.meta?.message || '服务器内部错误';
- ElMessage({ message: serverErrorMsg, type: 'error' });
- return Promise.reject({ code: 500, message: serverErrorMsg });
-
- default:
- const errorMsg = responseData.meta?.message || `业务错误 (${businessCode})`;
- ElNotification.error({ title: errorMsg });
- return Promise.reject({ code: businessCode, message: errorMsg });
- }
- },
- (error) => {
- let { message } = error;
- let code = error?.response?.status || -1;
- if (message == 'Network Error') {
- message = '后端接口连接异常';
- ElMessage({ message, type: 'error', duration: 5 * 1000 });
- } else if (message.includes('timeout')) {
- message = '系统接口请求超时';
- ElMessage({ message, type: 'error', duration: 5 * 1000 });
- } else if (message.includes('Request failed with status code')) {
- // message = '系统接口' + message.substr(message.length - 3) + '异常';
- }
-
- // 返回结构化错误
- return Promise.reject({
- code,
- message,
- raw: error // 保留原始 error
- });
- }
-);
-
-// 单独处理401未授权
-function handleUnauthorized() {
- return ElMessageBox.confirm(
- '认证信息已失效,您可以继续留在该页面,或者重新登录',
- '系统提示',
- {
- confirmButtonText: '重新登录',
- cancelButtonText: '取消',
- type: 'warning',
- }
- )
- .then(() => {
- removeToken()
- if (router.currentRoute.path !== '/login') {
- router.push({
- path: '/login',
- query: { redirect: router.currentRoute.fullPath }
- });
- } else {
- // 如果在登录页,强制刷新以清除残留状态
- window.location.reload();
- }
- })
- .catch(() => {
- return Promise.reject('用户取消操作');
- });
-}
-
-export default service;
diff --git a/src/views/coordinate/personnelList/components/assistWx/index.vue b/src/views/coordinate/personnelList/components/assistWx/index.vue
deleted file mode 100644
index 37314cb..0000000
--- a/src/views/coordinate/personnelList/components/assistWx/index.vue
+++ /dev/null
@@ -1,236 +0,0 @@
-
-
-
-
-
-
-
-
{{ userName }}
-
{{ statusText }}
-
-
-
-
-
-
-
- 挂断
-
-
- 呼叫中...
-
-
-
-
-
-
- 接听
-
-
- 挂断
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/coordinate/personnelList/components/leftTab/index.vue b/src/views/coordinate/personnelList/components/leftTab/index.vue
deleted file mode 100644
index f411858..0000000
--- a/src/views/coordinate/personnelList/components/leftTab/index.vue
+++ /dev/null
@@ -1,682 +0,0 @@
-
-
-
-
-
-
(leftTab = 1)"
- >
-
-
-
-
(leftTab = 2)"
- >
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ parseTime(item.created_at, '{m}月{d}日') }}
- {{ weekName[new Date(item.created_at).getDay()] }}
-
-
- {{ parseTime(item.created_at, '{y}年') }}
-
-
-
-
-
-
- {{
- items.display_name +
- (indexs + 1 == item.all_participants.length
- ? ''
- : '、')
- }}
-
-
-
- 发起人:{{ item.all_participants.find(item => item.participant_role == 'moderator')?.display_name || ''}}
-
-
- 时间:{{
- parseTime(item.created_at, '{h}:{i}') +
- ' ~ ' +
- (item.updated_at ? parseTime(item.updated_at, '{h}:{i}') : '')
- }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ data.name }}
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/coordinate/personnelList/index.vue b/src/views/coordinate/personnelList/index.vue
deleted file mode 100644
index 08cf442..0000000
--- a/src/views/coordinate/personnelList/index.vue
+++ /dev/null
@@ -1,707 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{ tabValue == 1 ? '协作信息' : '员工信息' }}
-
-
-
- 发起人
-
- {{ detail.initiator }}
-
-
-
- 协作时间
-
- {{
- detail.created_at ?
- parseTime(detail.created_at, '{y}年{m}月{d}日') +
- ' ' +
- weekName[new Date(detail.created_at).getDay()] +
- ' ' +
- parseTime(detail.created_at, '{h}:{i}')
- : '暂无'
- }}
-
-
-
- 成员
-
-
- {{
- items.display_name +
- (indexs + 1 == detail.all_participants.length
- ? ''
- : '、')
- }}
-
-
-
-
- 协作时长
-
- {{ getTime() }}
-
-
-
-
-
-
-
-
-
-
-
-
- 附件({{
- detail?.fileList?.length ? detail.fileList.length : 0
- }})
-
-
-
-
-
-
-
-
- {{ item.file_name }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{{ detail.nickName || detail.name || '暂无信息' }}
-
-
-
-
- 发起协作
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/custom/api/index.js b/src/views/custom/api/index.js
deleted file mode 100644
index 3000959..0000000
--- a/src/views/custom/api/index.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import request from "@/utils/request.js";
-
-// 上传绘制数据
-export const getWhiteboardShapes = (data, room_uid) => {
- return request({
- url: `/api/v1/whiteboard/rooms/${room_uid}/shapes`,
- method: "put",
- data: data
- });
-};
-
-// 获取以往绘制数据
-export const getWhiteboardHistory = (data, room_uid) => {
- return request({
- url: `/api/v1/whiteboard/rooms/${room_uid}/history`,
- method: "get",
- params: data
- });
-};
-
-//获取用户信息
-// export const getWhiteboardHistory = (data, room_uid) => {
-// return request({
-// url: `/api/v1/user/self`,
-// method: "get",
-// params: data
-// });
-// };
diff --git a/src/views/custom/tabulaRase/index.vue b/src/views/custom/tabulaRase/index.vue
deleted file mode 100644
index dd64e29..0000000
--- a/src/views/custom/tabulaRase/index.vue
+++ /dev/null
@@ -1,145 +0,0 @@
-
-
-
-
-
-
- 正在进入互动画板。。。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/custom/tabulaRase/index_old.vue b/src/views/custom/tabulaRase/index_old.vue
deleted file mode 100644
index f8cf179..0000000
--- a/src/views/custom/tabulaRase/index_old.vue
+++ /dev/null
@@ -1,185 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- 加入互动画板
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/interfaceManagement/index.vue b/src/views/interfaceManagement/index.vue
new file mode 100644
index 0000000..17025d6
--- /dev/null
+++ b/src/views/interfaceManagement/index.vue
@@ -0,0 +1,317 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.created_at) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 权限字符
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 接口 路径
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 请求方法
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/login.vue b/src/views/login.vue
index 571ff76..933c488 100644
--- a/src/views/login.vue
+++ b/src/views/login.vue
@@ -4,7 +4,7 @@