This commit is contained in:
PQZ 2025-07-21 15:47:14 +08:00
parent a1fd60420d
commit 74ba07df9d
9 changed files with 353 additions and 13 deletions

BIN
assets/image/customer.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 KiB

View File

@ -57,7 +57,7 @@ export default {
plugins: [
'~plugins/main',
'~plugins/axios',
{ src: "~plugins/websocket.js", ssr: true },
// { src: "~plugins/websocket.js", ssr: true },
{ src: "~plugins/router.js", ssr: true },
{ src: "~plugins/i18n.js", ssr: true },
{ src: "~plugins/element-ui.js", ssr: true },

54
package-lock.json generated
View File

@ -17,6 +17,7 @@
"core-js": "^3.43.0",
"dayjs": "^1.11.7",
"element-ui": "^2.15.14",
"fingerprintjs2": "^2.1.4",
"jquery": "^3.4.1",
"lru-cache": "^7.18.3",
"nuxt": "2.15.0",
@ -4178,6 +4179,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmmirror.com/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"optional": true,
"dependencies": {
"file-uri-to-path": "1.0.0"
}
},
"node_modules/bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmmirror.com/bluebird/-/bluebird-3.7.2.tgz",
@ -6922,6 +6932,12 @@
"url": "https://opencollective.com/webpack"
}
},
"node_modules/file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"optional": true
},
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
@ -6999,6 +7015,12 @@
"micromatch": "^4.0.2"
}
},
"node_modules/fingerprintjs2": {
"version": "2.1.4",
"resolved": "https://registry.npmmirror.com/fingerprintjs2/-/fingerprintjs2-2.1.4.tgz",
"integrity": "sha512-veP2yVsnYvjDVkzZMyIEwpqCAQfsBLH+U4PK5MlFAnLjZrttbdRqEArE1fPcnJFz5oS5CrdONbsV7J6FGpIJEQ==",
"deprecated": "Package has been renamed to @fingerprintjs/fingerprintjs. Install @fingerprintjs/fingerprintjs to get updates."
},
"node_modules/flat": {
"version": "5.0.2",
"resolved": "https://registry.npmmirror.com/flat/-/flat-5.0.2.tgz",
@ -9523,6 +9545,12 @@
"resolved": "https://registry.npmmirror.com/mute-stream/-/mute-stream-0.0.8.tgz",
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
},
"node_modules/nan": {
"version": "2.23.0",
"resolved": "https://registry.npmmirror.com/nan/-/nan-2.23.0.tgz",
"integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==",
"optional": true
},
"node_modules/nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz",
@ -20381,6 +20409,15 @@
"resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz",
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="
},
"bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmmirror.com/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"optional": true,
"requires": {
"file-uri-to-path": "1.0.0"
}
},
"bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmmirror.com/bluebird/-/bluebird-3.7.2.tgz",
@ -22497,6 +22534,12 @@
}
}
},
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"optional": true
},
"fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
@ -22561,6 +22604,11 @@
"micromatch": "^4.0.2"
}
},
"fingerprintjs2": {
"version": "2.1.4",
"resolved": "https://registry.npmmirror.com/fingerprintjs2/-/fingerprintjs2-2.1.4.tgz",
"integrity": "sha512-veP2yVsnYvjDVkzZMyIEwpqCAQfsBLH+U4PK5MlFAnLjZrttbdRqEArE1fPcnJFz5oS5CrdONbsV7J6FGpIJEQ=="
},
"flat": {
"version": "5.0.2",
"resolved": "https://registry.npmmirror.com/flat/-/flat-5.0.2.tgz",
@ -24397,6 +24445,12 @@
"resolved": "https://registry.npmmirror.com/mute-stream/-/mute-stream-0.0.8.tgz",
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
},
"nan": {
"version": "2.23.0",
"resolved": "https://registry.npmmirror.com/nan/-/nan-2.23.0.tgz",
"integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==",
"optional": true
},
"nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz",

View File

@ -20,6 +20,7 @@
"core-js": "^3.43.0",
"dayjs": "^1.11.7",
"element-ui": "^2.15.14",
"fingerprintjs2": "^2.1.4",
"jquery": "^3.4.1",
"lru-cache": "^7.18.3",
"nuxt": "2.15.0",

View File

@ -187,12 +187,15 @@
</b-form>
</div>
</div>
<!-- 聊天记录弹出框-->
<chat-form ref="chatFrom"></chat-form>
</div>
</template>
<script>
import vuePhotoZoomPro from 'vue-photo-zoom-pro';
import 'vue-photo-zoom-pro/dist/style/vue-photo-zoom-pro.css';
import chatForm from "./chatForm";
if (process.client) {
var { swiper, swiperSlide } = require("vue-awesome-swiper");
}
@ -204,6 +207,7 @@ export default {
swiper,
swiperSlide,
vuePhotoZoomPro,
chatForm
},
data() {
return {
@ -243,9 +247,13 @@ export default {
e.preventDefault()
console.log(this.dataForm);
},
/**打开聊天窗口,并建立连接*/
chat(){
this.$store.dispatch('modules/websocket/websocket_send', 'kehuduan,userface,hello');
this.$refs.chatFrom.show()
}
}
}
</script>

246
pages/products/chatForm.vue Normal file
View File

@ -0,0 +1,246 @@
<template>
<!-- 选择产品对话框 -->
<el-dialog :title="title" :visible.sync="open" @close="close" width="800px" append-to-body>
<el-card style="height: 600px">
<el-container class="AddressBook-container">
<el-header class="AddressBook-header" style="height: 30px">
<span></span>
<!-- <span style="margin-left: 500px">当前在线人数{{count.split(',')[1]}}</span>-->
</el-header>
<el-container>
<!-- <el-aside width="200px" class="AddressBook-aside">-->
<!-- <el-input placeholder="请输入用户名"-->
<!-- size="mini"-->
<!-- v-model="userQuery.name"-->
<!-- clearable-->
<!-- @clear="getUserList"-->
<!-- @keyup.enter.native="getUserList">-->
<!-- &lt;!&ndash; <el-button size="small" icon="el-icon-search" @click="getAddressBook"></el-button>&ndash;&gt;-->
<!-- </el-input>-->
<!-- <div style="margin-top: 0px">-->
<!-- <div v-for="item in userList" class="userList">-->
<!-- <div style="height:5px">-->
<!-- </div>-->
<!-- <el-avatar shape="square" size="medium" :src="item.userface"-->
<!-- style="margin-left: 5px"></el-avatar>-->
<!-- <span class="name">{{item.name}}</span>-->
<!-- </div>-->
<!-- <div style="height:5px">-->
<!-- </div>-->
<!-- </div>-->
<!-- </el-aside>-->
<el-container>
<el-main class="AddressBook-main">
<el-row style="margin-top: 20px" v-for="item in message" :key="item.createTime">
<el-row v-if="item.dataFrom===name" type="flex" justify="end">
<el-col :span="8">
<el-card shadow="always" :style="'item.dataFrom===name'?'':'background-color: greenyellow;'">
{{ item.content }}
</el-card>
</el-col>
<el-col :span="2">
<el-avatar shape="square" size="medium" icon="el-icon-user-solid"
style="margin-left: 5px"></el-avatar>
</el-col>
</el-row>
<el-row v-else type="flex" justify="start">
<el-col :span="2">
<el-avatar shape="square" size="medium" icon="el-icon-user-solid"
style="margin-left: 5px"></el-avatar>
</el-col>
<el-col :span="8">
<el-card shadow="always" style="background-color: greenyellow">
{{ item.content }}
</el-card>
</el-col>
</el-row>
</el-row>
</el-main>
<el-footer class="uesrtext" style="height:150px">
<el-input type="textarea"
class="inputT"
placeholder="按 Enter 发送" v-model="text"
@keyup.enter.native="sendToServer"
></el-input>
<el-button type="primary" icon="el-icon-s-promotion" @click="sendToServer"></el-button>
</el-footer>
</el-container>
</el-container>
</el-container>
</el-card>
</el-dialog>
</template>
<script>
import Fingerprint2 from "fingerprintjs2";
export default {
name: 'chatForm',
data() {
return {
//
open: false,
title: null,
//
message: [],
//
name: null,
//
text: null,
//
chatMain: {},
}
},
destroyed: function () {
//
this.$store.dispatch('modules/websocket/websocket_close')
},
mounted() {
},
methods: {
/**用户列表*/
getUserList() {
},
/**
* 组件显示
*/
show() {
this.open = true
this.getChatMain()
},
/**获取原有聊天记录*/
getChatMain() {
//id
// this.$store.dispatch('modules/websocket/websocket_send', murmur + ',userface,hello');
//id
Fingerprint2.get((components) => {
const values = components.map((component) => component.value);
const fingerprintHash = Fingerprint2.x64hash128(values.join(''), 31);
this.name = fingerprintHash
const data = {
cusCode: fingerprintHash,
tenantId: 'main',
};
// 使 `this` Vue
this.$axios.$post('/web/chatMain', data).then((res) => {
if (res.id != null) {
this.chatMain = res;
const websocketUrl = `ws://localhost:8099/ws/asset/${fingerprintHash}`;
// Vuex dispatchWebSocket
this.$store.dispatch('modules/websocket/websocket_init', websocketUrl)
.then(() => {
console.log('WebSocket 初始化成功');
})
.catch((err) => {
console.error('WebSocket 初始化失败:', err);
});
} else {
console.error('请求返回错误:', res);
}
}).catch(error => {
console.error('请求错误:', error);
});
});
},
/**弹窗关闭方法*/
close() {
this.$store.dispatch('modules/websocket/websocket_close')
},
/**发送消息*/
sendToServer() {
this.$store.dispatch('modules/websocket/websocket_send',this.name + "," + this.text);
this.message=this.$store.state.modules.websocket.messages;
this.text=''
}
}
}
</script>
<style lang="scss" scoped>
.el-card {
background-color: transparent;
border: none;
}
.AddressBook-container {
height: 100%;
width: 100%;
border: 1px solid #909399;
border-radius: 3px;
}
.AddressBook-header {
background-color: #0b60b5;
color: #d3dce6;
display: flex;
align-items: center;
}
.AddressBook-main {
height: 380px;
background-color: #DCDFE6;
}
.AddressBook-aside {
background-color: #909399;
}
.userList {
padding-top: 3px;
box-shadow: 0px 3px 3px #888888;
.name {
vertical-align: top;
/*margin-top: 2px;*/
margin-left: 15px;
font-size: 15px;
}
}
.uesrtext {
position: relative;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
border-top: solid 1px #DDD;
background-color: white;
.inputT {
padding-top: 10px;
width: 100%;
height: 200%;
border: none;
outline: none;
}
.el-button {
position: absolute;
bottom: 10px;
right: 10px;
}
}
.message-avatar {
}
</style>

View File

@ -2,8 +2,32 @@ import Vue from 'vue'
import {
// 添加你需要的其他组件
Tree,
Drawer
Drawer,
Dialog,
Button,
Card,
Container,
Header,
Aside,
Input,
Main,
Footer,
Row,
Col,
Avatar
} from 'element-ui'
Vue.use(Tree)
Vue.use(Drawer)
Vue.use(Drawer)
Vue.use(Dialog)
Vue.use(Button)
Vue.use(Card)
Vue.use(Container)
Vue.use(Header)
Vue.use(Aside)
Vue.use(Input)
Vue.use(Main)
Vue.use(Footer)
Vue.use(Row)
Vue.use(Col)
Vue.use(Avatar)

View File

@ -1,6 +1,13 @@
export default ({ store }) => {
if (process.client){
const websocketUrl = 'ws://localhost:8099/ws/asset/kehuduan'
store.dispatch('modules/websocket/websocket_init', websocketUrl)
}
}
// import Fingerprint2 from 'fingerprintjs2';
//
// export default ({ store }) => {
// if (process.client){
// const fingerprint = Fingerprint2.get((components) => {
// const values = components.map((component)=>component.value)
// const murmur = Fingerprint2.x64hash128(values.join(''),31)
// const websocketUrl = 'ws://localhost:8099/ws/asset/'+murmur
// store.dispatch('modules/websocket/websocket_init', websocketUrl)
// })
// }
// }

View File

@ -15,16 +15,16 @@ export const mutations = {
console.log("WebSocket连接成功");
};
state.socket.onmessage = function (e) {
console.log(e,'接收到的消息')
if (e.data.startsWith("C")) {
state.count = e.data;
}
else if (e.data.startsWith("系统通知")){
state.notices.push(e.data);
console.log(state.notices);
}
else {
state.message.push(JSON.parse(e.data));
console.log(state.message);
state.messages.push(JSON.parse(e.data));
console.log(state.messages);
}
};
state.socket.onerror= function () {