添加im聊天功能,添加用户搜索功能
This commit is contained in:
parent
df715f924d
commit
43915ff365
|
|
@ -10,6 +10,7 @@
|
|||
"dependencies": {
|
||||
"axios": "^1.6.5",
|
||||
"cors": "^2.8.5",
|
||||
"crypto-js": "^4.2.0",
|
||||
"element-plus": "^2.4.4",
|
||||
"js-md5": "^0.8.3",
|
||||
"qrcode": "^1.5.3",
|
||||
|
|
@ -1104,6 +1105,11 @@
|
|||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/crypto-js": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
"dependencies": {
|
||||
"axios": "^1.6.5",
|
||||
"cors": "^2.8.5",
|
||||
"crypto-js": "^4.2.0",
|
||||
"element-plus": "^2.4.4",
|
||||
"js-md5": "^0.8.3",
|
||||
"qrcode": "^1.5.3",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
import request from '@/utils/request.js'
|
||||
|
||||
export const getImKeyService = (Data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
params.append(key, Data[key])
|
||||
}
|
||||
return request.post('/im/get_imKey', params,{
|
||||
headers: {
|
||||
'token': Data.token, // 将 token 替换为您的令牌值
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -38,6 +38,19 @@ export const getUUIDService = (registerData) => {
|
|||
return request.post('/user/uuid', params)
|
||||
}
|
||||
|
||||
export const SearchUserService = (Data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
params.append(key, Data[key])
|
||||
}
|
||||
return request.post('/user/search', params,{
|
||||
headers: {
|
||||
'token': Data.token, // 将 token 替换为您的令牌值
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export const getQRService = (qrData) => {
|
||||
const params = new URLSearchParams();
|
||||
//console.log("qrdata=",qrData);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import LoginVue from "@/views/Login.vue";
|
|||
import VideoVue from "@/views/Video.vue";
|
||||
import VideoListVue from "@/views/VideoList.vue";
|
||||
import DeviceListVue from "@/views/DeviceList.vue";
|
||||
import UserListVue from "@/views/UserList.vue";
|
||||
import ImVue from "@/views/Im.vue";
|
||||
|
||||
const routes = [
|
||||
{
|
||||
|
|
@ -26,6 +28,16 @@ const routes = [
|
|||
name: 'Device',
|
||||
component: DeviceListVue
|
||||
},
|
||||
{
|
||||
path: '/im',
|
||||
name: 'Im',
|
||||
component: ImVue
|
||||
},
|
||||
{
|
||||
path: '/user',
|
||||
name: 'User',
|
||||
component: UserListVue
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/login'
|
||||
|
|
|
|||
|
|
@ -150,6 +150,9 @@ export default {
|
|||
@click.prevent="handleMenuSelect('/device')"
|
||||
>设备管理</el-button
|
||||
>
|
||||
<el-button type="primary" size="mini" @click.prevent="handleMenuSelect('/User')"
|
||||
>用户</el-button
|
||||
>
|
||||
<el-container style="height: 700px; border: 1px solid #eee">
|
||||
<el-header style="font-size: 40px; background-color: rgb(238, 241, 246)"
|
||||
>监控设备列表</el-header
|
||||
|
|
|
|||
|
|
@ -0,0 +1,372 @@
|
|||
<template>
|
||||
<div style="padding: 10px; margin-bottom: 50px">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/videoList')"
|
||||
>视频列表</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/device')"
|
||||
>设备管理</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/User')"
|
||||
>用户</el-button
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="16">
|
||||
<div
|
||||
style="
|
||||
width: 800px;
|
||||
margin: 0 auto;
|
||||
background-color: white;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 10px #ccc;
|
||||
"
|
||||
>
|
||||
<div style="text-align: center; line-height: 50px">
|
||||
Web聊天室({{ chatUser }})
|
||||
</div>
|
||||
<div
|
||||
style="height: 350px; overflow: auto; border-top: 1px solid #ccc"
|
||||
v-html="content"
|
||||
></div>
|
||||
<div style="height: 200px">
|
||||
<textarea
|
||||
v-model="text"
|
||||
style="
|
||||
height: 160px;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
border: none;
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
outline: none;
|
||||
"
|
||||
></textarea>
|
||||
<div style="text-align: right; padding-right: 10px">
|
||||
<el-button type="primary" size="mini" @click="send"
|
||||
>发送</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { ref, onMounted, inject, onUnmounted } from "vue";
|
||||
import { getImKeyService } from "@/api/im.js";
|
||||
import router from "@/router/index.js";
|
||||
import * as crypto from "crypto";
|
||||
import CryptoJS from "crypto-js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
circleUrl:
|
||||
"https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png",
|
||||
user: {},
|
||||
isCollapse: false,
|
||||
users: [{ username: "admin" }, { username: "zhang" }],
|
||||
chatUser: "2002",
|
||||
text: "",
|
||||
messages: [],
|
||||
session: "",
|
||||
imKey: "testimkey",
|
||||
socket: null,
|
||||
content: "",
|
||||
to_user_id: 0,
|
||||
to_user_name: "",
|
||||
cnt: 0,
|
||||
intervalId: null,
|
||||
tokenData: {
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
username: localStorage.getItem("username"),
|
||||
to_user_id: this.to_user_id,
|
||||
},
|
||||
intervalId: ref(null),
|
||||
timerId: null, // 用于存储定时器的ID
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async send() {
|
||||
if (!this.text) {
|
||||
this.$message({ type: "warning", message: "请输入内容" });
|
||||
} else {
|
||||
if (typeof WebSocket == "undefined") {
|
||||
console.log("您的浏览器不支持WebSocket");
|
||||
} else {
|
||||
// 组装待发送的消息 json
|
||||
// {"type":"msg","data":"hello","to_user_id":1,"from_user_id":2002,"session":"11917957"}
|
||||
// let message = {
|
||||
// type: "msg",
|
||||
// data: "hello",
|
||||
// to_user_id: this.to_user_id,
|
||||
// from_user_id: this.tokenData.userId,
|
||||
// session: this.session,
|
||||
// };
|
||||
// let json=JSON.stringify(message)
|
||||
// var aesEnc = await this.aesEncrypt(
|
||||
// this.text,
|
||||
// this.imKey,
|
||||
// this.session
|
||||
// );
|
||||
var aesEnc = await this.aesEncrypt(
|
||||
this.text,
|
||||
this.imKey,
|
||||
this.imKey
|
||||
);
|
||||
let data =
|
||||
'{"type":"msg","data":"' +
|
||||
aesEnc +
|
||||
'","to_user_id":' +
|
||||
this.to_user_id +
|
||||
',"from_user_id":' +
|
||||
this.tokenData.userId +
|
||||
',"session":"' +
|
||||
this.session +
|
||||
'"}';
|
||||
this.socket.send(data); // 将组装好的json发送给服务端,由服务端进行转发
|
||||
this.messages.push(JSON.parse(data));
|
||||
// 构建消息内容,本人消息
|
||||
this.createContent(null, this.tokenData.username, this.text);
|
||||
this.text = "";
|
||||
}
|
||||
}
|
||||
},
|
||||
startInterval() {
|
||||
this.timerId = setInterval(() => {
|
||||
this.getIMKey();
|
||||
}, 1000); // 每秒(1000毫秒)执行一次
|
||||
},
|
||||
handleMenuSelect(val) {
|
||||
router.push(val);
|
||||
},
|
||||
stopInterval() {
|
||||
clearInterval(this.timerId);
|
||||
},
|
||||
async getIMKey() {
|
||||
let result = {};
|
||||
try {
|
||||
let req = {
|
||||
to_user_id: this.to_user_id,
|
||||
token: this.tokenData.token,
|
||||
};
|
||||
result = await getImKeyService(req);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
let data = result.data;
|
||||
if (result.code != 0) {
|
||||
this.cnt++;
|
||||
if (this.cnt > 10) {
|
||||
//暂停定时器
|
||||
this.stopInterval();
|
||||
alert("连接失败,请重试!");
|
||||
router.push("/user");
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (data.is_read == 1) {
|
||||
// 读取到了新的消息
|
||||
this.imKey = data.im_key;
|
||||
this.session = data.im_session;
|
||||
console.log("imKey:",this.imKey)
|
||||
localStorage.setItem("imkey_" + this.to_user_id, this.imKey);
|
||||
//记录过期时间
|
||||
localStorage.setItem(
|
||||
"imkey_" + this.to_user_id + "_expire",
|
||||
data.expire
|
||||
);
|
||||
this.session = data.im_session;
|
||||
//暂停定时器
|
||||
this.stopInterval();
|
||||
this.connectWebSocket();
|
||||
} else {
|
||||
this.cnt++;
|
||||
if (this.cnt > 30) {
|
||||
//暂停定时器
|
||||
this.stopInterval();
|
||||
alert("连接失败,请重试!");
|
||||
router.push("/user");
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
createContent(remoteUser, nowUser, text) {
|
||||
// 这个方法是用来将 json的聊天消息数据转换成 html的。
|
||||
var html;
|
||||
// 当前用户消息
|
||||
if (nowUser) {
|
||||
// nowUser 表示是否显示当前用户发送的聊天消息,绿色气泡
|
||||
html =
|
||||
'<div class="el-row" style="padding: 5px 0">\n' +
|
||||
' <div class="el-col el-col-22" style="text-align: right; padding-right: 10px">\n' +
|
||||
' <div class="tip left">' +
|
||||
text +
|
||||
"</div>\n" +
|
||||
" </div>\n" +
|
||||
' <div class="el-col el-col-2">\n' +
|
||||
' <span class="el-avatar el-avatar--circle" style="height: 40px; width: 40px; line-height: 40px;">\n' +
|
||||
' <img src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" style="object-fit: cover;">\n' +
|
||||
" </span>\n" +
|
||||
" </div>\n" +
|
||||
"</div>";
|
||||
} else if (remoteUser) {
|
||||
// remoteUser表示远程用户聊天消息,蓝色的气泡
|
||||
html =
|
||||
'<div class="el-row" style="padding: 5px 0">\n' +
|
||||
' <div class="el-col el-col-2" style="text-align: right">\n' +
|
||||
' <span class="el-avatar el-avatar--circle" style="height: 40px; width: 40px; line-height: 40px;">\n' +
|
||||
' <img src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" style="object-fit: cover;">\n' +
|
||||
" </span>\n" +
|
||||
" </div>\n" +
|
||||
' <div class="el-col el-col-22" style="text-align: left; padding-left: 10px">\n' +
|
||||
' <div class="tip right">' +
|
||||
text +
|
||||
"</div>\n" +
|
||||
" </div>\n" +
|
||||
"</div>";
|
||||
}
|
||||
this.content += html;
|
||||
},
|
||||
aesEncrypt(text, password, iv) {
|
||||
// CryptoJS使用WordArray而不是Buffer,所以我们需要将密码和IV转换为WordArray
|
||||
const passwordWordArray = CryptoJS.enc.Utf8.parse(password);
|
||||
const ivWordArray = CryptoJS.enc.Utf8.parse(iv);
|
||||
|
||||
// 使用CryptoJS创建AES加密实例
|
||||
const cipher = CryptoJS.AES.encrypt(
|
||||
CryptoJS.enc.Utf8.parse(text), // 加密的数据
|
||||
passwordWordArray, // 密钥
|
||||
{
|
||||
iv: ivWordArray, // 初始化向量
|
||||
mode: CryptoJS.mode.CBC, // 加密模式
|
||||
padding: CryptoJS.pad.Pkcs7, // 填充方式
|
||||
}
|
||||
);
|
||||
|
||||
// CryptoJS默认返回的是CipherParams对象,我们需要将其转换为Base64字符串
|
||||
const encrypted = cipher.toString();
|
||||
|
||||
return encrypted;
|
||||
},
|
||||
decryptAES(encryptedData, secretKey, iv) {
|
||||
// 确保密钥和偏移量(IV)是WordArray对象
|
||||
const key = CryptoJS.enc.Utf8.parse(secretKey);
|
||||
const ivData = CryptoJS.enc.Utf8.parse(iv);
|
||||
|
||||
// Base64 解码加密数据
|
||||
// 注意:CryptoJS.enc.Base64.parse 实际上是用于将WordArray转换为Base64字符串的,
|
||||
// 对于从Base64字符串解码,应该使用 CryptoJS.enc.Base64.parse(CryptoJS.enc.Base64.stringify(someWordArray)),
|
||||
// 但在这里我们直接使用字符串作为输入,因为encryptedData已经是Base64编码的字符串。
|
||||
try {
|
||||
const decrypted = CryptoJS.AES.decrypt(encryptedData, key, {
|
||||
iv: ivData,
|
||||
mode: CryptoJS.mode.CBC,
|
||||
padding: CryptoJS.pad.Pkcs7,
|
||||
});
|
||||
|
||||
// 检查解密是否成功
|
||||
if (decrypted.sigBytes === 0) {
|
||||
throw new Error("Decryption failed. Invalid data or password.");
|
||||
}
|
||||
|
||||
// 将解密后的 WordArray 转换为 UTF-8 字符串
|
||||
const decryptedText = decrypted.toString(CryptoJS.enc.Utf8);
|
||||
console.log("decryptedText: " + decryptedText,secretKey, iv,encryptedData);
|
||||
return decryptedText;
|
||||
} catch (error) {
|
||||
// 捕获并处理异常
|
||||
console.error("Decryption error:", error);
|
||||
throw error; // 或者返回一个错误消息或空字符串等
|
||||
}
|
||||
},
|
||||
connectWebSocket() {
|
||||
// 连接WebSocket
|
||||
let _this = this;
|
||||
if (typeof WebSocket == "undefined") {
|
||||
console.log("您的浏览器不支持WebSocket");
|
||||
} else {
|
||||
console.log("您的浏览器支持WebSocket");
|
||||
let socketUrl =
|
||||
"wss://gep.ljsea.top/im/ws?to_user_id=" +
|
||||
this.to_user_id +
|
||||
"&token=" +
|
||||
this.tokenData.token;
|
||||
|
||||
console.log("socketUrl:", socketUrl);
|
||||
if (this.socket != null) {
|
||||
this.socket.close();
|
||||
this.socket = null;
|
||||
}
|
||||
// 开启一个websocket服务
|
||||
this.socket = new WebSocket(socketUrl);
|
||||
//打开事件
|
||||
this.socket.onopen = function () {
|
||||
alert("websocket已打开");
|
||||
};
|
||||
this.socket.onerror = (error) => {
|
||||
console.error("WebSocket Error:", error);
|
||||
};
|
||||
// 浏览器端收消息,获得从服务端发送过来的文本消息
|
||||
this.socket.onmessage = async function (msg) {
|
||||
console.log("收到数据====" + msg.data);
|
||||
let data = JSON.parse(msg.data); // 对收到的json数据进行解析, 类似这样的:
|
||||
// 如果服务器端发送过来的json数据 不包含 users 这个key,那么发送过来的就是聊天文本json数据
|
||||
data.data=await _this.decryptAES(data.data, _this.imKey, _this.imKey)
|
||||
_this.messages.push(data);
|
||||
console.log("收到数据====" + msg.data);
|
||||
// 构建消息内容
|
||||
_this.createContent(_this.to_user_name, null, data.data);
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
// 生命周期钩子,在组件挂载完成后被调用
|
||||
mounted() {
|
||||
console.log("chatUser:", this.chatUser);
|
||||
this.to_user_id = localStorage.getItem("to_user_id");
|
||||
this.to_user_name = localStorage.getItem("to_user_name");
|
||||
this.chatUser = this.to_user_name;
|
||||
//console.log("to_user_id:", this.to_user_id, this.to_user_name);
|
||||
this.startInterval();
|
||||
//this.connectWebSocket();
|
||||
},
|
||||
// 生命周期钩子,在组件卸载之前被调用
|
||||
beforeDestroy() {
|
||||
this.stopInterval();
|
||||
this.socket.close();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.tip {
|
||||
color: white;
|
||||
text-align: center;
|
||||
border-radius: 10px;
|
||||
font-family: sans-serif;
|
||||
padding: 10px;
|
||||
width: auto;
|
||||
display: inline-block !important;
|
||||
display: inline;
|
||||
}
|
||||
.right {
|
||||
background-color: deepskyblue;
|
||||
}
|
||||
.left {
|
||||
background-color: forestgreen;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
@ -0,0 +1,210 @@
|
|||
<script>
|
||||
import axios from "axios";
|
||||
import { SearchUserService } from "@/api/user.js";
|
||||
import router from "@/router/index.js";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ip: "",
|
||||
tableData: [],
|
||||
tokenData: {
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
username: localStorage.getItem("username"),
|
||||
id: 2002,
|
||||
keyword: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
// methods 是一些用来更改状态与触发更新的函数
|
||||
// 它们可以在模板中作为事件处理器绑定
|
||||
methods: {
|
||||
async getUserList() {
|
||||
let result = {};
|
||||
try {
|
||||
result = await SearchUserService(this.tokenData);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
let data = result.data;
|
||||
|
||||
// for(let d in data){
|
||||
// let res = JSON.parse(d);
|
||||
// console.log("res=",res);
|
||||
// this.tableData.push(res);
|
||||
// }
|
||||
this.tableData = data;
|
||||
},
|
||||
onSubmit() {
|
||||
getUserList({ token: token });
|
||||
},
|
||||
handleSizeChange() {
|
||||
alert("每页记录数变化" + val);
|
||||
},
|
||||
handleCurrentChange() {
|
||||
alert("页码发生变化" + val);
|
||||
},
|
||||
|
||||
//设置设备重启
|
||||
async startChat(index) {
|
||||
var id = this.tableData[index].ID;
|
||||
var name = this.tableData[index].Name;
|
||||
// var user_data = {
|
||||
// to_user_id: id,
|
||||
// to_user_name: this.tableData[index].Name,
|
||||
// };
|
||||
//转到聊天页面
|
||||
localStorage.setItem("to_user_id", id);
|
||||
localStorage.setItem("to_user_name", name);
|
||||
router.push("/im");
|
||||
},
|
||||
|
||||
handleMenuSelect(val) {
|
||||
router.push(val);
|
||||
},
|
||||
toVideoList() {
|
||||
router.push("/videoList");
|
||||
},
|
||||
// 修改条纹颜色
|
||||
tableRowClassName({ row, rowIndex }) {
|
||||
if (row.human === 1) {
|
||||
return {
|
||||
background: "#488aff",
|
||||
};
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
// 生命周期钩子会在组件生命周期的各个不同阶段被调用
|
||||
// 例如这个函数就会在组件挂载完成后被调用
|
||||
async mounted() {
|
||||
let now = new Date();
|
||||
if (localStorage.getItem("token") === null) {
|
||||
router.push("/login");
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/videoList')"
|
||||
>视频列表</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/device')"
|
||||
>设备管理</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/User')"
|
||||
>用户</el-button
|
||||
>
|
||||
<el-container style="height: 700px; border: 1px solid #eee">
|
||||
<el-header style="font-size: 40px; background-color: rgb(238, 241, 246)"
|
||||
>用户搜索列表</el-header
|
||||
>
|
||||
<el-container>
|
||||
<el-main>
|
||||
<el-col :span="8">
|
||||
<!-- 搜索与添加区域 -->
|
||||
<el-input
|
||||
placeholder="请输入ID"
|
||||
v-model="tokenData.id"
|
||||
clearable
|
||||
@clear="getUserList"
|
||||
>
|
||||
</el-input>
|
||||
<el-input
|
||||
placeholder="请输入关键字"
|
||||
v-model="tokenData.keyword"
|
||||
clearable
|
||||
@clear="getUserList"
|
||||
>
|
||||
</el-input>
|
||||
<template #append>
|
||||
<el-button @click="getUserList"
|
||||
><el-icon><search /></el-icon
|
||||
></el-button>
|
||||
</template>
|
||||
</el-col>
|
||||
<!-- 表单 -->
|
||||
<el-form :inline="true" :model="tokenData" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<el-button
|
||||
class="el-button--danger"
|
||||
type="primary"
|
||||
@click="getUserList()"
|
||||
>查询</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 表格 :row-style="this.tableRowClassName"-->
|
||||
<el-table :data="tableData" width="100%" border>
|
||||
:row-style="this.tableRowClassName"
|
||||
<el-table-column prop="ID" label="id" width="80"></el-table-column>
|
||||
<el-table-column
|
||||
prop="Name"
|
||||
label="名称"
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="Email"
|
||||
label="用户邮箱"
|
||||
width="180"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="Age"
|
||||
label="用户Age"
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="Gender"
|
||||
label="用户性别"
|
||||
width="80"
|
||||
></el-table-column>
|
||||
<el-table-column label="操作" width="300">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="startChat(scope.$index)"
|
||||
>聊天</el-button
|
||||
>
|
||||
<!-- <el-button type="danger" size="mini">删除</el-button> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<br />
|
||||
|
||||
<!-- 分页条 -->
|
||||
<!-- Pagination 分页 -->
|
||||
<!-- <el-pagination
|
||||
background
|
||||
layout="total,sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:total="1000"
|
||||
></el-pagination> -->
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
.blueRowbg {
|
||||
background: "#488aff";
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
<script>
|
||||
import axios from "axios";
|
||||
import { inject } from "vue";
|
||||
import { getVideoListService, quashVideoService } from "@/api/video.js";
|
||||
import { delayVideoService } from "@/api/video.js";
|
||||
import router from "@/router/index.js";
|
||||
|
|
@ -226,6 +225,9 @@ export default {
|
|||
<el-button type="primary" size="mini" @click.prevent="handleMenuSelect('/device')"
|
||||
>设备管理</el-button
|
||||
>
|
||||
<el-button type="primary" size="mini" @click.prevent="handleMenuSelect('/User')"
|
||||
>用户</el-button
|
||||
>
|
||||
<el-container style="height: 700px; border: 1px solid #eee">
|
||||
<el-header style="font-size: 40px; background-color: rgb(238, 241, 246)"
|
||||
>监控视频列表</el-header
|
||||
|
|
|
|||
Loading…
Reference in New Issue