feat:跟新组织架构
19
src/api/coordinate.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 获取组织列表
|
||||
export function getDirectories(data) {
|
||||
return request({
|
||||
url: `/api/v1/auth/directories`,
|
||||
method: 'get',
|
||||
params:data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取指定目录下的用户列表
|
||||
export function getDirectoriesUsers(directory_uuid,data) {
|
||||
return request({
|
||||
url: `/api/v1/auth/directories/${directory_uuid}/users`,
|
||||
method: 'get',
|
||||
params:data
|
||||
})
|
||||
}
|
||||
@@ -22,7 +22,7 @@ export function login(username, password) {
|
||||
// 获取用户详细信息
|
||||
export function getInfo(userUid) {
|
||||
return request({
|
||||
url: `/api/v1/auth/user/${userUid}`,
|
||||
url: `/api/v1/auth/users/${userUid}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
BIN
src/assets/images/cooponents-tab1.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/images/cooponents-tab2.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
src/assets/images/cooponents-tab3.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/images/cooponents-tab4.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/images/profile.jpg
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/images/user-information1.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/images/user-information2.png
Normal file
|
After Width: | Height: | Size: 535 B |
BIN
src/assets/images/user-information3.png
Normal file
|
After Width: | Height: | Size: 939 B |
BIN
src/assets/images/user-information4.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
src/assets/images/userlist-icon1.png
Normal file
|
After Width: | Height: | Size: 676 B |
BIN
src/assets/images/userlist-icon2.png
Normal file
|
After Width: | Height: | Size: 777 B |
@@ -20,6 +20,16 @@ const router = createRouter({
|
||||
path: "/login",
|
||||
component: () => import("@/views/login.vue"),
|
||||
},
|
||||
{
|
||||
path: "/coordinate",
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: "Coordinate",
|
||||
component: () => import("@/views/coordinate/personnelList/index.vue")
|
||||
}
|
||||
]
|
||||
},
|
||||
// 错误页面路由
|
||||
{
|
||||
path: "/:pathMatch(.*)*",
|
||||
|
||||
@@ -33,13 +33,14 @@ class MQTTClient {
|
||||
this.client.on("error", (error) => reject(error))
|
||||
|
||||
// 消息分发
|
||||
this.client.on("message", (topic, payload) => {
|
||||
this.client.on("message", (topic, payload) => {
|
||||
try {
|
||||
const message = JSON.parse(payload.toString())
|
||||
// const message = JSON.parse(payload.toString())
|
||||
// 遍历所有订阅主题,执行通配符匹配
|
||||
this.messageHandlers.forEach((handlers, subTopic) => {
|
||||
if (this.topicMatch(subTopic, topic)) {
|
||||
handlers.forEach((handler) => handler(message, topic))
|
||||
// handlers.forEach((handler) => handler(message, topic))
|
||||
handlers.forEach((handler) => handler(payload, topic))
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
|
||||
@@ -99,11 +99,13 @@ service.interceptors.request.use(
|
||||
|
||||
service.interceptors.response.use(
|
||||
(response) => {
|
||||
console.log(response,'response')
|
||||
// 1. 检查响应是否存在
|
||||
if (!response) {
|
||||
ElMessage.error('无响应数据');
|
||||
return Promise.reject(new Error('无响应数据'));
|
||||
}
|
||||
console.log(response.data,'response.data')
|
||||
// 2. 安全获取响应数据和状态码
|
||||
const responseData = response.data || {};
|
||||
const statusCode = response.status;
|
||||
@@ -124,6 +126,7 @@ service.interceptors.response.use(
|
||||
return Promise.resolve(responseData);
|
||||
|
||||
case 401:
|
||||
console.log('未授权', responseData)
|
||||
return handleUnauthorized().then(() => {
|
||||
return Promise.reject({ code: 401, message: '未授权' });
|
||||
});
|
||||
@@ -143,6 +146,13 @@ service.interceptors.response.use(
|
||||
console.error('请求错误:', error);
|
||||
let { message } = error;
|
||||
let code = error?.response?.status || -1;
|
||||
console.log(code,'code')
|
||||
|
||||
if(code == 401) {
|
||||
return handleUnauthorized().then(() => {
|
||||
return Promise.reject({ code: 401, message: '未授权' });
|
||||
});
|
||||
}
|
||||
|
||||
if (message == 'Network Error') {
|
||||
message = '后端接口连接异常';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { mqttClient } from "./mqtt";
|
||||
import { getWhiteboardShapes, getWhiteboardHistory } from "@/views/custom/api";
|
||||
import { useMeterStore } from '@/stores/modules/meter';
|
||||
import { encode, decode } from '@msgpack/msgpack'
|
||||
|
||||
const meterStore = useMeterStore();
|
||||
meterStore.initUdid();
|
||||
@@ -42,12 +43,15 @@ export const WhiteboardSync = {
|
||||
|
||||
// 订阅当前房间
|
||||
const topic = `xSynergy/ROOM/${roomUid}/whiteboard/#`;
|
||||
mqttClient.subscribe(topic, async (shapeData) => {
|
||||
mqttClient.subscribe(topic, async (shapeData) => {
|
||||
// console.log(shapeData, 'shapeData++格式装换')
|
||||
const shapeDataNew = decode(shapeData);
|
||||
// console.log(shapeDataNew, '格式解码')
|
||||
try {
|
||||
isRemote = true;
|
||||
// 如果 shape 来自本地用户,则跳过
|
||||
if (shapeData.user_uid === localUid) return;
|
||||
const res = await getWhiteboardHistory({ after_timestamp: shapeData.created_at }, roomUid);
|
||||
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 {
|
||||
@@ -62,7 +66,7 @@ export const WhiteboardSync = {
|
||||
|
||||
console.log("✅ 已订阅:", topic);
|
||||
} catch (err) {
|
||||
console.log("初始化多人同步失败:",err)
|
||||
console.log("初始化多人同步失败:", err)
|
||||
// console.error("❌ 连接或订阅失败:", err);
|
||||
}
|
||||
|
||||
@@ -72,10 +76,9 @@ export const WhiteboardSync = {
|
||||
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;
|
||||
if (shape.user_uid && shape.user_uid === localUid) return;
|
||||
|
||||
shape.room_uid = roomUid;
|
||||
try {
|
||||
await getWhiteboardShapes(shape, roomUid);
|
||||
} catch (err) {
|
||||
@@ -85,7 +88,7 @@ export const WhiteboardSync = {
|
||||
|
||||
// 监听画布事件:清空
|
||||
canvas.on('clear', async () => {
|
||||
if (!isRemote) {
|
||||
if (!isRemote) {
|
||||
try {
|
||||
// TODO: 调用接口,后端再发 MQTT
|
||||
// await clearWhiteboard(roomUid);
|
||||
|
||||
596
src/views/coordinate/personnelList/components/leftTab/index.vue
Normal file
@@ -0,0 +1,596 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- v-loading="leftListLoading || loading" -->
|
||||
<div class="left-list" v-loading="leftListLoading || loading">
|
||||
<div class="list-tab">
|
||||
<div
|
||||
:class="'list-tab-item ' + (leftTab == 1 ? 'pitch-on' : '')"
|
||||
@click="() => (leftTab = 1)"
|
||||
>
|
||||
<img src="@/assets/images/cooponents-tab3.png" v-if="leftTab == 1" />
|
||||
<img src="@/assets/images/cooponents-tab4.png" v-else />
|
||||
</div>
|
||||
<div
|
||||
:class="'list-tab-item ' + (leftTab == 2 ? 'pitch-on' : '')"
|
||||
@click="() => (leftTab = 2)"
|
||||
>
|
||||
<img src="@/assets/images/cooponents-tab2.png" v-if="leftTab == 2" />
|
||||
<img src="@/assets/images/cooponents-tab1.png" v-else />
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-content">
|
||||
<div class="content-top-input">
|
||||
<el-input
|
||||
v-model="queryFrom.nickName"
|
||||
placeholder="搜索成员"
|
||||
type="text"
|
||||
prefix-icon="Search"
|
||||
@change="searchList"
|
||||
/>
|
||||
</div>
|
||||
<div class="content-datapicker" v-if="leftTab == 1">
|
||||
<el-date-picker
|
||||
v-model="queryFrom.leftDatePicker"
|
||||
type="datetimerange"
|
||||
:shortcuts="shortcuts"
|
||||
range-separator="到"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
format="YYYY-MM-DD HH:mm"
|
||||
value-format="YYYY-MM-DD HH:mm"
|
||||
@change="searchList"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar class="left-list-scrollbar" v-if="isShow && leftTab == 1">
|
||||
<div
|
||||
class="content-list"
|
||||
v-infinite-scroll="infinite"
|
||||
v-if="dataList?.length"
|
||||
>
|
||||
<div
|
||||
v-for="(item, index) in dataList"
|
||||
:key="index"
|
||||
class="content-list-item"
|
||||
@click="updateDetail(item)"
|
||||
:style="
|
||||
item.assistanceId == assistanceId
|
||||
? 'border-color: #409EFF; '
|
||||
: ''
|
||||
"
|
||||
>
|
||||
<div class="list-item-top">
|
||||
<span>
|
||||
{{ parseTime(item.beginTime, '{m}月{d}日') }}
|
||||
{{ weekName[new Date(item.beginTime).getDay()] }}
|
||||
</span>
|
||||
<span>
|
||||
{{ parseTime(item.beginTime, '{y}年') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-content-text">
|
||||
<div style="display: flex; flex-wrap: wrap">
|
||||
<span
|
||||
v-for="(items, indexs) in item.assistanceMemberList"
|
||||
:key="indexs"
|
||||
>
|
||||
{{
|
||||
items.nickName +
|
||||
(indexs + 1 == item.assistanceMemberList.length
|
||||
? ''
|
||||
: '、')
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<span>
|
||||
发起人:{{ item.initiatorName ? item.initiatorName : '' }}
|
||||
</span>
|
||||
<span>
|
||||
时间:{{
|
||||
parseTime(item.beginTime, '{h}:{i}') +
|
||||
' ~ ' +
|
||||
(item.endTime ? parseTime(item.endTime, '{h}:{i}') : '')
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: center" v-if="dataList?.length">
|
||||
<p v-if="more">Loading...</p>
|
||||
<p v-else>No more</p>
|
||||
</div>
|
||||
<div v-else class="list-empty">
|
||||
<el-empty description="暂无记录" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
<div v-if="!isShow && leftTab == 1" class="list-empty">
|
||||
<el-empty description="暂无记录" />
|
||||
</div>
|
||||
|
||||
<el-scrollbar
|
||||
class="left-list-scrollbar1"
|
||||
height="calc(100vh - 120px)"
|
||||
v-if="leftTab == 2"
|
||||
>
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
lazy
|
||||
:load="HandleLoadNode"
|
||||
:filter-node-method="filterNode"
|
||||
highlight-current
|
||||
:props="treeProps"
|
||||
style="width: 100%"
|
||||
@node-click="updateDetail"
|
||||
>
|
||||
<template #default="{ data }">
|
||||
<div class="tree-item">
|
||||
{{ data.name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
// getAssistanceList,
|
||||
getDirectories,
|
||||
getDirectoriesUsers
|
||||
} from '@/api/coordinate.js'
|
||||
import { nextTick, reactive, toRefs, watch, onMounted } from 'vue'
|
||||
|
||||
// 接收 props
|
||||
const props = defineProps({
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 定义 emit
|
||||
const emit = defineEmits(['updateDetail', 'updateTab'])
|
||||
|
||||
// state
|
||||
const state = reactive({
|
||||
isFirst: true,
|
||||
leftTab: 2,
|
||||
queryFrom: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
nickName: '',
|
||||
leftDatePicker: null,
|
||||
},
|
||||
leftListLoading: true,
|
||||
loading: false,
|
||||
dataList: [],
|
||||
more: false,
|
||||
isShow: false,
|
||||
shortcuts: [
|
||||
{
|
||||
text: '本周',
|
||||
value: () => {
|
||||
const now = new Date()
|
||||
const nowDaty = now.getDay()
|
||||
const start = new Date(now)
|
||||
start.setDate(now.getDate() - nowDaty)
|
||||
const end = new Date(start)
|
||||
end.setDate(start.getDate() + 6)
|
||||
return [start, end]
|
||||
},
|
||||
},
|
||||
{
|
||||
text: '最近三周',
|
||||
value: () => {
|
||||
const now = new Date()
|
||||
const nowDaty = now.getDay()
|
||||
let end = new Date(now)
|
||||
end.setDate(now.getDate() + (6 - nowDaty))
|
||||
const start = new Date(end)
|
||||
start.setDate(start.getDate() - 20)
|
||||
return [start, end]
|
||||
},
|
||||
},
|
||||
{
|
||||
text: '本月',
|
||||
value: () => {
|
||||
const now = new Date()
|
||||
const start = new Date(now.getFullYear(), now.getMonth(), 1)
|
||||
const end = new Date(now.getFullYear(), now.getMonth() + 1, 0)
|
||||
return [start, end]
|
||||
},
|
||||
},
|
||||
],
|
||||
weekName: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
|
||||
treeRef: null,
|
||||
|
||||
treeProps: {
|
||||
children: 'users',
|
||||
label: 'name',
|
||||
value: 'uid',
|
||||
isLeaf: (node) => {
|
||||
if(node.uid) return true
|
||||
},
|
||||
},
|
||||
assistanceId: '',
|
||||
})
|
||||
|
||||
/**
|
||||
* 树状列表筛选
|
||||
*/
|
||||
const filterNode = (value, data) => {
|
||||
if (!value) return true
|
||||
return data.name.includes(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索框变化
|
||||
*/
|
||||
const searchList = () => {
|
||||
if (state.leftTab == 1) {
|
||||
state.queryFrom.pageNum = 1
|
||||
state.dataList = []
|
||||
getList()
|
||||
} else {
|
||||
console.log('treeRef.filter',state.treeRef)
|
||||
state.treeRef.filter(state.queryFrom.nickName)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 变更详情
|
||||
*/
|
||||
const updateDetail = (item) => {
|
||||
if (state.leftTab == 1) {
|
||||
state.assistanceId = item.assistanceId
|
||||
emit('updateDetail', item)
|
||||
} else {
|
||||
if (item.uid) {
|
||||
emit('updateDetail', item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 触底加载
|
||||
*/
|
||||
// const infinite = () => {
|
||||
// if (state.more) {
|
||||
// state.queryFrom.pageNum++
|
||||
// getList()
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 协作记录
|
||||
*/
|
||||
const getList = async () => {
|
||||
try {
|
||||
state.leftListLoading = true
|
||||
|
||||
let query = structuredClone(state.queryFrom)
|
||||
if (query.leftDatePicker?.length) {
|
||||
query.beginSignTime = query.leftDatePicker[0]
|
||||
query.endSignTime = query.leftDatePicker[1]
|
||||
}
|
||||
delete query.leftDatePicker
|
||||
|
||||
let infoData = await getAssistanceList({ ...query })
|
||||
|
||||
state.dataList = infoData.rows.length
|
||||
? state.dataList.concat(infoData.rows)
|
||||
: []
|
||||
|
||||
if (state.isFirst) {
|
||||
emit('updateDetail', state.dataList.length ? state.dataList[0] : null)
|
||||
state.assistanceId = state.dataList.length
|
||||
? state.dataList[0].assistanceId
|
||||
: ''
|
||||
state.isFirst = false
|
||||
}
|
||||
|
||||
state.more = state.dataList.length < infoData.total
|
||||
state.isShow = Boolean(state.dataList.length)
|
||||
state.leftListLoading = false
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
state.leftListLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通讯录 人员信息树
|
||||
*/
|
||||
const HandleLoadNode = async (node, resolve) => {
|
||||
if(node.level === 0){
|
||||
loadNode(resolve)
|
||||
}else if(node.level === 1){
|
||||
loadNode(resolve,node.data.directory_uid)
|
||||
}
|
||||
}
|
||||
|
||||
const loadNode = async(resolve,id)=>{
|
||||
try {
|
||||
state.leftListLoading = true
|
||||
if(!id){
|
||||
let res = await getDirectories({level:1})
|
||||
resolve(res.data)
|
||||
}else{
|
||||
let res = await getDirectoriesUsers(id,{directory_uuid:id})
|
||||
resolve(res.data)
|
||||
}
|
||||
state.leftListLoading = false
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
state.leftListLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
// try {
|
||||
// if (userList.data.sub_units?.length) {
|
||||
// state.dataList = userList.data.sub_units
|
||||
// let user = getUser(state.dataList)
|
||||
// emit('updateDetail', user)
|
||||
// } else {
|
||||
// emit('updateDetail', null)
|
||||
// }
|
||||
// state.leftListLoading = false
|
||||
// }
|
||||
|
||||
|
||||
|
||||
const getUser = (list) => {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
if (list[i].type == 2) {
|
||||
return list[i]
|
||||
} else if (list[i].children?.length) {
|
||||
let user = getUser(list[i].children)
|
||||
if (user != null) {
|
||||
return user
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听 props.loading
|
||||
*/
|
||||
watch(
|
||||
() => props.loading,
|
||||
(newValue) => {
|
||||
state.loading = newValue
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* 监听 tab 切换
|
||||
*/
|
||||
watch(
|
||||
() => state.leftTab,
|
||||
(newValue) => {
|
||||
emit('updateTab', newValue)
|
||||
state.dataList = []
|
||||
state.isFirst = true
|
||||
state.queryFrom = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
nickName: '',
|
||||
leftDatePicker: null,
|
||||
}
|
||||
|
||||
if (newValue == 1) {
|
||||
state.isShow = false
|
||||
getList()
|
||||
} else {
|
||||
HandleLoadNode()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
state.dataList = []
|
||||
state.isFirst = true
|
||||
// getList()
|
||||
})
|
||||
|
||||
/**
|
||||
* 暴露给模板
|
||||
*/
|
||||
const {
|
||||
isFirst, leftTab, queryFrom, leftListLoading, loading,
|
||||
dataList, more, isShow, shortcuts, weekName,
|
||||
treeRef, treeProps, assistanceId
|
||||
} = toRefs(state)
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.flex {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.left-list {
|
||||
display: flex;
|
||||
height: calc(100vh - 40px);
|
||||
|
||||
.list-tab {
|
||||
@extend .flex;
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
margin-right: 6px;
|
||||
|
||||
.list-tab-item {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-content {
|
||||
@extend .flex;
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
width: calc(100% - 56px);
|
||||
box-shadow: 0px 5px 15px 0px rgba(153, 153, 153, 0.3);
|
||||
|
||||
.content-top-input {
|
||||
@extend .flex;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
padding: 6px 20px;
|
||||
background: #167bff;
|
||||
}
|
||||
|
||||
.content-datapicker {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.left-list-scrollbar {
|
||||
width: 100%;
|
||||
height: calc(100vh - 170px);
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.left-list-scrollbar1 {
|
||||
width: 100%;
|
||||
height: calc(100vh - 120px);
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.content-list {
|
||||
width: 100%;
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.content-list-item {
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
background: #f5f7fa;
|
||||
border: 1.5px solid #c9d4e6;
|
||||
cursor: pointer;
|
||||
|
||||
.list-item-top {
|
||||
@extend .flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
padding: 0 13px;
|
||||
background: #c9d4e6;
|
||||
|
||||
span {
|
||||
color: #333333;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.list-item-content {
|
||||
@extend .flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
padding: 13px;
|
||||
background: #f5f7fa;
|
||||
|
||||
img {
|
||||
width: 27px;
|
||||
height: 27px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.list-item-content-text {
|
||||
@extend .flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
|
||||
div {
|
||||
@extend .flex;
|
||||
justify-content: flex-start;
|
||||
|
||||
span {
|
||||
margin: 0;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
margin-top: 6px;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-empty {
|
||||
@extend .flex;
|
||||
width: 100%;
|
||||
height: calc(100vh - 170px);
|
||||
}
|
||||
|
||||
.tree-item {
|
||||
@extend .flex;
|
||||
justify-content: flex-start;
|
||||
height: 45px;
|
||||
|
||||
.tree-item-img1 {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.tree-item-text1 {
|
||||
margin-left: 10px;
|
||||
color: #333333;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.tree-item-text2 {
|
||||
color: #333333;
|
||||
font-size: 18px;
|
||||
}
|
||||
.tree-item-text3 {
|
||||
margin-left: 15px;
|
||||
color: #999999;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-tree-node__content {
|
||||
@extend .flex;
|
||||
justify-content: flex-start;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
::v-deep .list-content .el-input__wrapper {
|
||||
height: 38px;
|
||||
border-radius: 19px;
|
||||
}
|
||||
|
||||
::v-deep .content-datapicker .el-date-editor {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
background: #e6f1ff;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
::v-deep .left-list-scrollbar .el-scrollbar__wrap {
|
||||
height: calc(100vh - 170px);
|
||||
}
|
||||
|
||||
::v-deep .left-list-scrollbar1 .el-scrollbar__wrap {
|
||||
height: calc(100vh - 120px);
|
||||
}
|
||||
</style>
|
||||
755
src/views/coordinate/personnelList/index.vue
Normal file
@@ -0,0 +1,755 @@
|
||||
<template>
|
||||
<div class="app-container" v-loading="load" :element-loading-text="loadText">
|
||||
<el-row :gutter="6" style="padding: 0 10px; background: #fefefe">
|
||||
<el-col :xs="24" :sm="24" :md="8" :lg="6">
|
||||
<leftTab
|
||||
@updateDetail="updateDetail"
|
||||
@updateTab="updateTab"
|
||||
:loading="!detail?.appId && !detail?.userId && isShow"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="16" :lg="18">
|
||||
<div
|
||||
class="right-content"
|
||||
|
||||
>
|
||||
<!-- v-loading="!detail?.appId && !detail?.userId && isShow" -->
|
||||
<div class="right-content-title">
|
||||
{{ tabValue == 1 ? '协作信息' : '员工信息' }}
|
||||
</div>
|
||||
<div
|
||||
class="agency-detail-massage-cont right-content-message"
|
||||
v-if="isShow && tabValue == 1"
|
||||
>
|
||||
<div class="agency-detail-cont-item">
|
||||
<span class="agency-detail-item-title">发起人</span>
|
||||
<span class="agency-detail-item-content">
|
||||
{{ detail.initiatorName }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="agency-detail-cont-item">
|
||||
<span class="agency-detail-item-title">协作时间</span>
|
||||
<span class="agency-detail-item-content">
|
||||
<!-- {{
|
||||
parseTime(detail.beginTime, '{y}年{m}月{d}日') +
|
||||
' ' +
|
||||
weekName[new Date(detail.beginTime).getDay()] +
|
||||
' ' +
|
||||
parseTime(detail.beginTime, '{h}:{i}')
|
||||
}} -->
|
||||
</span>
|
||||
</div>
|
||||
<div class="agency-detail-cont-item">
|
||||
<span class="agency-detail-item-title">成员</span>
|
||||
<span
|
||||
class="agency-detail-item-content"
|
||||
v-if="detail?.assistanceMemberList?.length"
|
||||
style="display: flex; flex-wrap: wrap"
|
||||
>
|
||||
<span
|
||||
v-for="(items, indexs) in detail.assistanceMemberList"
|
||||
:key="indexs"
|
||||
>
|
||||
{{
|
||||
items.nickName +
|
||||
(indexs + 1 == detail.assistanceMemberList.length
|
||||
? ''
|
||||
: '、')
|
||||
}}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="agency-detail-cont-item">
|
||||
<span class="agency-detail-item-title">协作时长</span>
|
||||
<span class="agency-detail-item-content">
|
||||
<!-- {{ getTime() }} -->
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="right-content-file" v-if="isShow && tabValue == 1">
|
||||
<el-row :gutter="15">
|
||||
<el-col :xs="24" :sm="24" :md="16" :lg="18">
|
||||
<div class="content-file-video">
|
||||
<div class="file-top">协作视频</div>
|
||||
<div class="file-video-bottom">
|
||||
<!-- autoplay="autoplay" -->
|
||||
<video
|
||||
v-if="
|
||||
detail.remoteVideoFile?.prefix &&
|
||||
detail.remoteVideoFile.path
|
||||
"
|
||||
:src="
|
||||
detail.remoteVideoFile.prefix +
|
||||
detail.remoteVideoFile.path
|
||||
"
|
||||
id="videoPlayer"
|
||||
loop
|
||||
controls
|
||||
></video>
|
||||
<div v-else class="video-null">暂无视频</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="8" :lg="6">
|
||||
<div>
|
||||
<div class="file-top">
|
||||
附件({{
|
||||
detail?.fileList?.length ? detail.fileList.length : 0
|
||||
}})
|
||||
</div>
|
||||
<div class="content-file-list">
|
||||
<el-scrollbar
|
||||
class="file-list"
|
||||
height="calc(100vh - 380px)"
|
||||
>
|
||||
<div
|
||||
class="file-list-content"
|
||||
v-if="detail?.fileList?.length"
|
||||
>
|
||||
<div
|
||||
class="file-list-item"
|
||||
v-for="(item, index) in detail.fileList"
|
||||
:key="index"
|
||||
>
|
||||
<div class="file-list-item-icon"></div>
|
||||
<div class="file-list-item-text">
|
||||
<div class="list-item-text text-out-of-hiding-1">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
|
||||
<!-- <el-icon
|
||||
:size="18"
|
||||
color="#0d74ff"
|
||||
style="cursor: pointer"
|
||||
@click="clickDetail(item)"
|
||||
>
|
||||
<View />
|
||||
</el-icon> -->
|
||||
<el-link
|
||||
:href="item.prefix + item.path"
|
||||
type="primary"
|
||||
target="_blank"
|
||||
:underline="false"
|
||||
>
|
||||
<el-icon
|
||||
:size="18"
|
||||
color="#0d74ff"
|
||||
style="cursor: pointer"
|
||||
>
|
||||
<Download />
|
||||
</el-icon>
|
||||
</el-link>
|
||||
<el-icon
|
||||
:size="18"
|
||||
color="#FF4646"
|
||||
style="cursor: pointer"
|
||||
@click="clickDeleteFile(item)"
|
||||
>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div
|
||||
class="message-user"
|
||||
v-else-if="isShow && tabValue == 2"
|
||||
style="height: calc(100vh - 90px)"
|
||||
>
|
||||
<div class="message-user-card">
|
||||
<div class="user-card-nickName">
|
||||
<img v-if="detail.avatar" :src="detail.avatar" />
|
||||
<img v-else src="@/assets/images/profile.jpg" />
|
||||
<span>{{ detail.nickName || detail.name || '暂无信息' }}</span>
|
||||
</div>
|
||||
<div class="user-card-information">
|
||||
<div class="user-information-item">
|
||||
<div class="user-information-title">
|
||||
<img src="@/assets/images/user-information1.png" alt="" />
|
||||
<span>性别</span>
|
||||
</div>
|
||||
<div class="user-information-text">
|
||||
<!-- <dict-tag
|
||||
v-if="detail.sex"
|
||||
:options="sys_user_sex"
|
||||
:value="detail.sex"
|
||||
/>
|
||||
<div v-else>
|
||||
{{ '暂无' }}
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-information-item">
|
||||
<div class="user-information-title">
|
||||
<img src="@/assets/images/user-information2.png" alt="" />
|
||||
<span>手机号</span>
|
||||
</div>
|
||||
<div class="user-information-text">
|
||||
{{ detail.phonenumber || '暂无' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-information-item">
|
||||
<div class="user-information-title">
|
||||
<img src="@/assets/images/user-information3.png" alt="" />
|
||||
<span>邮箱</span>
|
||||
</div>
|
||||
<div class="user-information-text">
|
||||
{{ detail.email || '暂无' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-information-item">
|
||||
<div class="user-information-title">
|
||||
<img src="@/assets/images/user-information4.png" alt="" />
|
||||
<span>所属部门</span>
|
||||
</div>
|
||||
<div class="user-information-text">
|
||||
{{ detail.dept?.deptName || '暂无' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-card-btn">
|
||||
<el-button type="primary" @click="clickInitiate">
|
||||
发起协作
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="message-null">
|
||||
<el-empty description="暂无内容" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- <el-dialog
|
||||
v-model="inviteDialog"
|
||||
title="远程协作"
|
||||
width="400px"
|
||||
:close-on-press-escape="false"
|
||||
:close-on-click-modal="false"
|
||||
:show-close="false"
|
||||
>
|
||||
<div>
|
||||
<div style="width: 100%; margin-bottom: 30px; font-size: 20px">
|
||||
"
|
||||
{{
|
||||
socketInformation.data?.inviteNickName
|
||||
? socketInformation.data?.inviteNickName
|
||||
: ''
|
||||
}}
|
||||
" 邀请您参加远程协作
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
<el-button
|
||||
size="large"
|
||||
type="danger"
|
||||
style="font-size: 16px"
|
||||
@click="clickRefuseJoin"
|
||||
>
|
||||
拒 绝
|
||||
</el-button>
|
||||
<el-button
|
||||
size="large"
|
||||
type="primary"
|
||||
style="font-size: 16px"
|
||||
@click="clickJoin"
|
||||
>
|
||||
加 入
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onActivated, onMounted, reactive, toRefs, watch, getCurrentInstance } from 'vue'
|
||||
// import {
|
||||
// getFileList,
|
||||
// getRemoveSolution,
|
||||
// getUserStatus,
|
||||
// refuseAssistance,
|
||||
// } from '@/api/module/cooperation/v1/index'
|
||||
// import { getAppId, getModuleId } from '@/utils/index'
|
||||
|
||||
import leftTab from './components/leftTab/index.vue'
|
||||
import { getInfo } from '@/api/login.js'
|
||||
|
||||
// import useUserStore from '@/store/modules/user'
|
||||
// import { getToken } from '@/utils/auth'
|
||||
// import useWebSocketStore from '@/store/modules/WebSocket'
|
||||
// import usePermissionStore from '@/store/modules/permission'
|
||||
// import logo from '@/assets/logo/logo.png'
|
||||
|
||||
// import { getRtcSetDetail } from '@/api/conferencingRoom'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
// const WebSocketStore = useWebSocketStore()
|
||||
// const { sys_user_sex } = proxy.useDict('sys_user_sex')
|
||||
|
||||
const state = reactive({
|
||||
detail: {},
|
||||
weekName: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
|
||||
tabValue: 2,
|
||||
isShow: true,
|
||||
load: false,
|
||||
loadText: '数据加载中',
|
||||
isLinkKnow: 'F',
|
||||
socketInformation: null,
|
||||
inviteDialog: false,
|
||||
cooperation: import.meta.env.VITE_APP_COOPERATION_TYPE,
|
||||
})
|
||||
|
||||
|
||||
/** 查看文件详情 */
|
||||
const clickDetail = (item) => {
|
||||
// let urls = item.prefix + item.path
|
||||
// let status = proxy.judgeType(urls)
|
||||
// if (status == 2 || status == 1) {
|
||||
// state.imgMp4Ref.showModel('查看', urls)
|
||||
// } else if (status == 3) {
|
||||
// state.documentRef.showModel('查看', urls)
|
||||
// } else if (status == 4) {
|
||||
// state.model3dRef.showModel('查看', import.meta.env.VITE_APP_FILE_API + item.path)
|
||||
// }
|
||||
}
|
||||
|
||||
/** 发起协作邀请 */
|
||||
const clickInitiate = () => {
|
||||
// state.loadText = '初始化协作房间中'
|
||||
// state.load = true
|
||||
// getUserStatus({ userIds: state.detail.userId })
|
||||
// .then((res) => {
|
||||
// res.data.forEach((i) => { i.status = 1 })
|
||||
// if (res.data.every((i) => i.status == 1)) {
|
||||
// proxy.$modal.msgSuccess('邀请已发送')
|
||||
// if (state.cooperation == 'skip') {
|
||||
// getRtcSetDetail().then((res) => {
|
||||
// const queryParams = new URLSearchParams({
|
||||
// type: 1,
|
||||
// userList: JSON.stringify([{ nickName: state.detail.nickName, userId: state.detail.userId }]),
|
||||
// appid: getAppId(),
|
||||
// Modinstid: getModuleId(),
|
||||
// token: getToken(),
|
||||
// userId: useUserStore().userId,
|
||||
// }).toString()
|
||||
// let url = import.meta.env.VITE_APP_ENV == 'development'
|
||||
// ? `/ar/app/conferencingRoom?${queryParams}`
|
||||
// : `${res.data.webMeetingUrl}?${queryParams}`
|
||||
// window.open(url, '_blank')
|
||||
// })
|
||||
// state.load = false
|
||||
// } else {
|
||||
// proxy.$router.push({
|
||||
// path: '/conferencingRoom',
|
||||
// query: {
|
||||
// type: 1,
|
||||
// userList: JSON.stringify([{ nickName: state.detail.nickName, userId: state.detail.userId }]),
|
||||
// appid: getAppId(),
|
||||
// Modinstid: getModuleId(),
|
||||
// token: getToken(),
|
||||
// userId: useUserStore().userId,
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
// } else {
|
||||
// proxy.$modal.msgError(
|
||||
// res.data[0].status == 0 ? '当前用户不在线' : '当前用户正在其他协作中'
|
||||
// )
|
||||
// state.load = false
|
||||
// }
|
||||
// })
|
||||
// .catch(() => {
|
||||
// state.load = false
|
||||
// proxy.$modal.closeLoading()
|
||||
// })
|
||||
}
|
||||
|
||||
/** 删除文件 */
|
||||
const clickDeleteFile = (row) => {
|
||||
// proxy.$modal
|
||||
// .confirm('是否确认删除 “ ' + row.name + ' ” 文件?')
|
||||
// .then(async () => {
|
||||
// await getRemoveSolution({ assistanceId: state.detail.assistanceId, fileId: row.fileId })
|
||||
// proxy.$modal.msgSuccess('删除成功')
|
||||
// getTheFileList(state.detail)
|
||||
// })
|
||||
// .catch(() => {})
|
||||
}
|
||||
|
||||
/** 修改展示列表 */
|
||||
const updateTab = (newValue) => {
|
||||
state.detail = {}
|
||||
state.tabValue = newValue
|
||||
}
|
||||
|
||||
/** 修改展示区内容 */
|
||||
const updateDetail = async (details) => {
|
||||
if (details) {
|
||||
console.log(details,'details')
|
||||
state.detail = {}
|
||||
if (state.tabValue == 1) {
|
||||
state.isShow = true
|
||||
} else {
|
||||
const res = await getInfo(details.uid)
|
||||
console.log(res,'res---+++')
|
||||
// state.detail = proxy.deepClone(res.data)
|
||||
state.detail = res.data
|
||||
|
||||
// getInfo(details.uid)
|
||||
// .then((res) => {
|
||||
// console.log(res,'人员详细信息')
|
||||
// // state.detail = proxy.deepClone(res.data)
|
||||
// })
|
||||
// .finally(() => { state.isShow = true })
|
||||
}
|
||||
} else {
|
||||
state.isShow = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取文件列表 */
|
||||
const getTheFileList = (details) => {
|
||||
// let detail = proxy.deepClone(details)
|
||||
// getFileList({ assistanceId: detail.assistanceId }).then((resser) => {
|
||||
// detail.fileList = resser.data
|
||||
// state.detail = proxy.deepClone(detail)
|
||||
// })
|
||||
}
|
||||
|
||||
/** 获取通话时长 */
|
||||
const getTime = () => {
|
||||
let begin = new Date(state.detail.beginTime).getTime()
|
||||
let end = new Date(state.detail.endTime).getTime()
|
||||
if (begin && end) {
|
||||
let diff = end - begin
|
||||
const h = Math.floor(diff / (1000 * 60 * 60))
|
||||
const m = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60))
|
||||
const s = Math.floor((diff % (1000 * 60)) / 1000)
|
||||
return h > 0 ? `${h}小时 ${m}分钟 ${s}秒`
|
||||
: m > 0 ? `${m}分钟 ${s}秒`
|
||||
: `${s}秒`
|
||||
} else {
|
||||
return '暂无'
|
||||
}
|
||||
}
|
||||
|
||||
/** 加入会议 */
|
||||
const clickJoin = () => {
|
||||
// proxy.$modal.loading('加入会议中,请稍候...')
|
||||
// if (state.cooperation == 'skip') {
|
||||
// getRtcSetDetail().then((res) => {
|
||||
// const queryParams = new URLSearchParams({
|
||||
// type: 2,
|
||||
// assistanceId: state.socketInformation.data.assistanceId,
|
||||
// channelName: state.socketInformation.data.channelName,
|
||||
// nickName: useUserStore().nickName,
|
||||
// appid: getAppId(),
|
||||
// Modinstid: getModuleId(),
|
||||
// token: getToken(),
|
||||
// userId: useUserStore().userId,
|
||||
// }).toString()
|
||||
// let url = import.meta.env.VITE_APP_ENV == 'development'
|
||||
// ? `/ar/app/conferencingRoom?${queryParams}`
|
||||
// : `${res.data.webMeetingUrl}?${queryParams}`
|
||||
// window.open(url, '_blank')
|
||||
// })
|
||||
// } else {
|
||||
// proxy.$router.push({
|
||||
// path: '/conferencingRoom',
|
||||
// query: {
|
||||
// type: 2,
|
||||
// assistanceId: state.socketInformation.data.assistanceId,
|
||||
// channelName: state.socketInformation.data.channelName,
|
||||
// nickName: useUserStore().nickName,
|
||||
// appid: getAppId(),
|
||||
// Modinstid: getModuleId(),
|
||||
// token: getToken(),
|
||||
// userId: useUserStore().userId,
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
// state.inviteDialog = false
|
||||
// proxy.$modal.closeLoading()
|
||||
}
|
||||
|
||||
/** 拒绝加入 */
|
||||
const clickRefuseJoin = () => {
|
||||
// refuseAssistance({
|
||||
// roomId: state.socketInformation.data.channelName,
|
||||
// assistanceId: state.socketInformation.data.assistanceId,
|
||||
// inviteUserId: state.socketInformation.data.inviteUserId,
|
||||
// }).then(() => {
|
||||
// proxy.$modal.msgSuccess('已拒绝加入该协作')
|
||||
// state.inviteDialog = false
|
||||
// })
|
||||
}
|
||||
|
||||
/** 处理 socket 消息 */
|
||||
const processingSocket = (message) => {
|
||||
// if (message) {
|
||||
// state.socketInformation = JSON.parse(message.data)
|
||||
// if (state.socketInformation.type == 'invite_join') {
|
||||
// state.inviteDialog = true
|
||||
// showNotification()
|
||||
// }
|
||||
// if (state.socketInformation.type == 'initiator_out') {
|
||||
// state.inviteDialog = false
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/** 浏览器通知 */
|
||||
const showNotification = () => {
|
||||
// if ('Notification' in window) {
|
||||
// Notification.requestPermission().then((permission) => {
|
||||
// if (permission === 'granted') {
|
||||
// const notification = new Notification('协作邀请', {
|
||||
// body: state.socketInformation.data.inviteNickName + '邀请您参加远程协作',
|
||||
// // icon: logo,
|
||||
// })
|
||||
// notification.onclick = () => { clickJoin() }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
||||
// watch(() => WebSocketStore.messages, (message) => {
|
||||
// if (state.cooperation != 'web') processingSocket(message)
|
||||
// })
|
||||
|
||||
// onMounted(() => {
|
||||
// state.isLinkKnow = proxy.getCurrentApplicationConfig('cooperation_link_know')
|
||||
// state.load = false
|
||||
// })
|
||||
|
||||
// onActivated(() => {})
|
||||
// 暴露给模板
|
||||
const { detail, weekName, tabValue, isShow, load, loadText, isLinkKnow, socketInformation, inviteDialog, cooperation } = toRefs(state)
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.flex {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
// margin: 0 17px;
|
||||
}
|
||||
|
||||
.message-null {
|
||||
@extend .flex;
|
||||
height: calc(100vh - 90px);
|
||||
}
|
||||
|
||||
.right-content {
|
||||
height: calc(100vh - 40px);
|
||||
background: #f4f9ff;
|
||||
|
||||
.right-content-title {
|
||||
@extend .flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
padding: 0 20px;
|
||||
background: #167bff;
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.right-content-message {
|
||||
width: calc(100% - 30px);
|
||||
height: 150px;
|
||||
margin: 15px;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.right-content-file {
|
||||
width: calc(100% - 30px);
|
||||
margin: 0 15px 15px;
|
||||
}
|
||||
|
||||
.file-top {
|
||||
@extend .flex;
|
||||
justify-content: flex-start;
|
||||
height: 50px;
|
||||
padding-left: 20px;
|
||||
background: #e6f1ff;
|
||||
color: #333;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.content-file-video {
|
||||
.file-video-bottom {
|
||||
width: 100%;
|
||||
height: calc(100vh - 350px);
|
||||
padding: 15px;
|
||||
background: #fff;
|
||||
|
||||
video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content-file-list {
|
||||
background: #fff;
|
||||
padding: 15px 5px 15px 10px;
|
||||
|
||||
.file-list {
|
||||
width: 100%;
|
||||
padding-right: 10px;
|
||||
|
||||
.file-list-content {
|
||||
@extend .flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
|
||||
.file-list-item {
|
||||
@extend .flex;
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.file-list-item-icon {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
margin-right: 10px;
|
||||
border-radius: 50%;
|
||||
background: #89b2ff;
|
||||
}
|
||||
|
||||
.file-list-item-text {
|
||||
@extend .flex;
|
||||
justify-content: space-between;
|
||||
width: calc(100% - 23px);
|
||||
padding: 13px 6px 13px 6px;
|
||||
border-radius: 4px;
|
||||
background: #f4f9ff;
|
||||
|
||||
.list-item-text {
|
||||
display: inline-block;
|
||||
width: calc(100% - 50px);
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.message-user {
|
||||
@extend .flex;
|
||||
overflow: auto;
|
||||
|
||||
.message-user-card {
|
||||
@extend .flex;
|
||||
flex-direction: column;
|
||||
width: 500px;
|
||||
height: 95%;
|
||||
max-height: 550px;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
.user-card-nickName {
|
||||
@extend .flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 40%;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(13, 116, 255, 0.22) 0%,
|
||||
rgba(30, 173, 255, 0) 100%
|
||||
);
|
||||
|
||||
img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin-top: 10%;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 50%;
|
||||
background: #167bff;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #051435;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-card-information {
|
||||
@extend .flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
width: 100%;
|
||||
height: 45%;
|
||||
|
||||
.user-information-item {
|
||||
@extend .flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.user-information-title {
|
||||
@extend .flex;
|
||||
justify-content: flex-start;
|
||||
width: 150px;
|
||||
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #999;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-information-text {
|
||||
width: 130px;
|
||||
color: #333333;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
.user-card-btn {
|
||||
@extend .flex;
|
||||
width: 100%;
|
||||
height: 15%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.video-null {
|
||||
color: #999;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
::v-deep .user-card-btn .el-button {
|
||||
width: 70%;
|
||||
height: 55%;
|
||||
border-radius: 25px;
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
@@ -112,7 +112,8 @@ function requestNotificationPermission() {
|
||||
onMounted(async () => {
|
||||
try {
|
||||
loginView.value = true
|
||||
await getInfo("self");
|
||||
const arr = await getInfo("self");
|
||||
console.log(arr,'身份信息')
|
||||
showLogin.value = false;
|
||||
router.push({
|
||||
path: '/whiteboard',
|
||||
|
||||