提交 1710f157 作者: Hao

add

父级 2a956ba1
......@@ -16,8 +16,9 @@ declare module 'vue' {
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElImage: typeof import('element-plus/es')['ElImage']
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElMain: typeof import('element-plus/es')['ElMain']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -12,11 +12,18 @@
"@luohc92/vue3-image-viewer": "^1.0.0",
"axios": "^1.6.7",
"core-js": "^3.8.3",
"cos-wx-sdk-v5": "^1.6.0",
"element-plus": "^2.6.1",
"emoji.json": "^15.1.0",
"mockjs": "^1.1.0",
"moment": "^2.30.1",
"pinia": "^2.1.7",
"pinia-plugin-persistedstate": "^3.2.1",
"socket.io-client": "^4.7.4",
"unplugin-auto-import": "0.16.1",
"unplugin-vue-components": "^0.25.2",
"vue": "^3.2.13",
"vue-native-websocket": "^2.0.15",
"vue-router": "^4.0.3",
"vuex": "^4.0.0"
},
......
......@@ -127,4 +127,7 @@ q:after {
table {
border-collapse: collapse;
border-spacing: 0;
}
::-webkit-scrollbar {
display: none;
}
\ No newline at end of file
// axios.js
import axios from 'axios';
const instance = axios.create({
baseURL: 'https://api.example.com', // 设置基础 URL
baseURL: '/api', // 设置基础 URL
timeout: 1000, // 设置请求超时时间
});
......@@ -15,7 +15,6 @@ instance.interceptors.request.use(
return config;
},
(error:any) => {
// 对请求错误做些什么
return Promise.reject(error);
}
);
......
import http from "../index";
const Login = (query: any) => {
return http({
url: `/login`,
method: "get",
data: query,
});
};
export { Login };
......@@ -2,89 +2,118 @@
<div>
<div class="chat-textarea">
<div class="chat-bar">
<emotion
v-if="showEmotion"
style="position: absolute; top: calc(100% - 465px); background: #fff;"
:height="200"
@emotion="handleEmotion"
/>
<el-icon
style="
cursor: pointer;
margin-left: 20px;
color: #333;
"
@click.stop="showEmotion = true"
>
<i class="iconfonts icon-xiaolian" style=" font-size: 20px;" alt="表情" />
</el-icon>
<el-icon
style="
font-size: 20px;
cursor: pointer;
margin-left: 20px;
color: #333;
"
@click="upfile"
>
<Picture />
</el-icon>
<el-icon
style="
font-size: 20px;
cursor: pointer;
margin-left: 20px;
color: #333;
"
@click="showWord"
>
<InfoFilled />
</el-icon>
<div>
<img
src="../assets/emojiSmiles-v1-light.png"
class="icon emoji"
@click.stop="showEmotion = true"
/>
<img
src="../assets/icon_image_s1_01.png"
@click="upfile"
class="icon emoji"
alt=""
/>
<img
src="../assets/icon_folder_s1_01.png"
@click="upfile"
class="icon emoji"
alt=""
/>
</div>
<div class="chat-bar-right">
<img
src="../assets/icon_folder_s1_01.png"
@click="upfile"
class="icon emoji"
alt=""
/>
快捷回复
</div>
</div>
<el-autocomplete
<!-- <el-autocomplete
class="autocomplete"
v-model="state"
:fetch-suggestions="querySearchAsync"
placeholder="请输入问题"
type="textarg"
@select="handleSelect"
ref="automaticPromptRef"
/> -->
<el-input
v-model="state"
ref="automaticPromptRef"
class="el-autocomplete"
placeholder="请输入问题"
type="textarea"
resize="none"
@change="handleSelect"
/>
</div>
<emotion
v-if="showEmotion"
style="position: absolute; top: calc(100% - 465px); background: #fff;"
:height="200"
@emotion="handleEmotion"
/>
<input
ref="file"
style="display: none;"
accept="image/bmp,image/jpeg,image/jpg,image/png"
type="file"
@change="fileChange"
/>
</div>
</template>
<script lang="ts" setup>
import Emotion from './IndexComponent.vue'
import { ElLoading } from 'element-plus'
import { ref, watch, defineEmits, defineExpose } from 'vue'
import axios from 'axios'
const state = ref('')
const file = ref(null)
interface LinkItem {
value: string
link: string
}
const showEmotion = ref<boolean>(false)
const automaticPromptRef = ref(null)
const links = ref<LinkItem[]>([])
const handleEmotion = () => {
console.log(1)
const handleEmotion = (i) => {
state.value += i
showEmotion.value = false
automaticPromptRef.value.focus()
}
const upfile = () => {
console.log(2)
file.value.click()
}
const fileChange = () => {
var e = window.event || event
var oFile = e.target.files[0]
console.log(oFile)
const loading = ElLoading.service({
lock: true,
text: '上传中...',
spinner: 'el-icon-loading',
})
loading.close()
}
const showWord = () => {
console.log(3)
}
const loadFromBackend = async (value: string) => {
try {
//输入时候请求后端根据输入值得到提示。 后端返回集合,集合里面对象属性为value和link都是string类型
const response = await axios.get(
`http://localhost:8080/getAutoMsg/${value}`,
)
links.value = response.data
} catch (error) {
console.error(error)
}
}
// const loadFromBackend = async (value: string) => {
// try {
// //输入时候请求后端根据输入值得到提示。 后端返回集合,集合里面对象属性为value和link都是string类型
// const response = await axios.get(
// `http://localhost:8080/getAutoMsg/${value}`,
// )
// links.value = response.data
// } catch (error) {
// console.error(error)
// }
// }
const querySearchAsync = (queryString: string, cb: (arg: any) => void) => {
const results = queryString
......@@ -104,14 +133,8 @@ const handleSelect = (value: string) => {
}
const emit = defineEmits(['updateState'])
watch(state, async (newValue) => {
emit('updateState', newValue)
if (newValue) {
await loadFromBackend(newValue)
} else {
links.value = []
}
})
defineExpose({
......@@ -123,21 +146,42 @@ defineExpose({
},
})
</script>
<style lang="scss">
<style lang="scss" scoped>
.icon {
width: 24px;
height: 24px;
margin-right: 32px;
}
.chat-bar {
padding: 10px;
display: flex;
align-items: center;
margin-bottom: 8px;
justify-content: space-between;
}
.el-autocomplete {
width: 100%;
height: 100%;
.el-input {
width: 100%;
}
.el-input__wrapper {
:deep(.el-textarea__inner ){
width: 100%;
height: 200px;
align-items: start;
box-shadow: none;
padding: 0px;
background: transparent;
}
}
.chat-bar-right {
font-family: 'PingFang SC';
font-size: 14px;
font-style: normal;
font-weight: 400;
color: #384860;
display: flex;
align-items: center;
.icon {
margin-right: 8px;
}
}
</style>
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import store from "./store/index";
import "./assets/css/reset.css";
import * as ElementPlusIconsVue from "@element-plus/icons-vue";
const app = createApp(App)
import { initWebSocket } from "../src/utils/websocket";
import { useUserStore } from "./store/modules/user";
import 'element-plus/dist/index.css'
import "../src/mocks/mock";
const app = createApp(App);
app.use(store).use(router).mount("#app");
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component);
}
const connectMsg = () => {
const useUser = useUserStore();
const toIp = `ws://192.168.31.228:8888?username=admin&password=123`;
console.log(useUser.isConnected, "store");
useUser.connect();
initWebSocket(toIp);
};
connectMsg();
const COS = require('cos-wx-sdk-v5');
const uploadMixin = {
data() {
return {
uploadMixinPath: '',
uploadMixinType: '',
uploadMixinCredentials: {},
uploadMixinTimeStamp: 0
};
},
methods: {
upLoadFilesHander(tempFilePaths, tempFiles, zip){
return new Promise((resolve)=>{
if (tempFiles.length != 0) {
if(typeof this.upLoadHander !== 'function') return;
let uploadObj = {};
let uploadNum = tempFiles.length;
uploadObj.length = tempFiles.length;
//处理上传结果函数
function loadHandler({ success, message },i){
uploadNum = uploadNum - 1;
uploadObj[i] = message;
if (!success) {
uploadObj[i] = '';
wx.showToast({
title: `[${i+1}]上传失败,请重新上传!`,
icon: 'none',
duration: 2000
});
}
if (uploadNum == 0) {
const arr = Array.from(uploadObj);
// ;
resolve({success: true, result: arr})
}
}
//进行上传
tempFiles.forEach((file, i) => {
this.upLoadHander({
path: tempFilePaths[i],
file: file.path,
zip: zip || '',
onSuccess: ({ success, message }) => {
loadHandler({ success, message },i)
},
onError: (res) => {
loadHandler({ success: false, message:''}, i)
}
});
});
}else{
resolve({success: true,result: []})
}
});
},
upLoadHander(obj) {
const { path, file, biz} = obj;
const pathArr = (path || '').split('/');
const pathStr = pathArr[pathArr.length -1];
const fileName = (pathStr || '').split('.');
let fileInfo = {
fileTyle: fileName.length > 1 ? fileName[fileName.length - 1] : '',
fileName: fileName[0],
biz: biz || 'temp',
file: file
};
const that = this;
const none = (async function hander(noCredentials) {
let res = {},
staticDomain = '',
resResult = true;
//noCredentials变量控制是否走对象存储
if (noCredentials) {
console.log(that.$https,'https')
res = await that.$https.request({
url: that.$interfaces.getUploadConfigInfo,
method: "get",
});
if (res.code === 200 && res.result) {
that.uploadMixinPath = res.result.upLoadPath;
that.uploadMixinType = res.result.uploadType;
staticDomain = res.result.staticDomain || 'https://cdn.tikcos.cn';
if (that.uploadMixinType === 'txcos') {
const ress = res.result.response;
const credentials = ress.credentials;
that.uploadMixinCredentials = {
TmpSecretId: credentials.tmpSecretId,
TmpSecretKey: credentials.tmpSecretKey,
SecurityToken: credentials.sessionToken,
StartTime: ress.startTime,
ExpiredTime: ress.expiredTime
};
}
} else {
resResult = false;
}
}
//resResult判断接口是否正常
if (resResult) {
if (that.uploadMixinType == 'txcos') {
//走对象存储
const cos = new COS({
getAuthorization: (options, callback) => {
callback(that.uploadMixinCredentials);
}
});
const tempFolder = fileInfo.biz === 'temp' ? '' : `${fileInfo.biz}/`;
const folder = `${fileInfo.fileName}_${new Date().getTime()}.${fileInfo.fileTyle}`;
cos.postObject(
{
FilePath: fileInfo.file,
Bucket: res.result.bucketName || 'tikcos-1257774783',
Region: res.result.regionid || 'ap-guangzhou',
Key: that.uploadMixinPath + tempFolder + folder,
Body: fileInfo.file,
onProgress: function (progressData) {
obj.onProgress && obj.onProgress(progressData);
}
},
(err, data) => {
if (!err && data.statusCode === 200) {
const imgurl = `${staticDomain}/${that.uploadMixinPath}${tempFolder}${folder}`;
obj.onSuccess({
success: true,
message: imgurl
});
} else {
obj.onError({
success: false,
message: err || '图片上传失败'
});
}
}
);
} else {
//走系统上传
that.$utils.ossUpload(
{
biz: fileInfo.biz,
file: fileInfo.file
},
(uploadRes) => {
// ;
if (uploadRes.success && uploadRes.message) {
//保存绝对路径,不然小程序会有问题
let url = uploadRes.message;
obj.onSuccess({ success: true, message: url });
} else {
obj.onError({
success: false,
message: uploadRes.message || '图片上传失败'
});
}
}
);
}
} else {
obj.onError({
success: false,
message: '服务接口报错'
});
}
})(true);
},
setOssUpload(obj) {
ossUpload(
{
biz: obj.biz,
file: obj.file
},
(uploadRes) => {
if (uploadRes.success && uploadRes.message) {
//保存绝对路径,不然小程序会有问题
let url = uploadRes.message;
const pre = url.startsWith('/') ? '' : '/';
url = axios['imgUrl'] + url;
obj.onSuccess({ success: true, message: url });
} else {
obj.onError({
success: false,
message: uploadRes.message || '图片上传失败'
});
}
}
);
}
}
};
export { uploadMixin };
// import io from 'socket.io-client';
// import { ref, onMounted, onUnmounted } from 'vue'
// import { ElMessage } from 'element-plus'
// export default function () {
// const message = {};
// const showMessage = {};
// const socket = ref(new WebSocket("ws://192.168.31.228:8888?username=admin&password=123"));
// socket.value.onopen = function (e) {
// console.log(e)
// }
// socket.value.onerror = function(e){
// console.log(e)
// };
// socket.value.onmessage = function (e) {
// console.log(e)
// };
// return {
// message,
// showMessage
// }
// }
\ No newline at end of file
const Mock = require('mockjs')
Mock.mock("/api/login", "get", () => {
return {
code: "200",
success: true,
message: '',
result: {
userName: "admin",
token:'admin'
},
};
});
//询价单
Mock.mock("/api/inquiryAdd", "get", () => {
return {
code: "200",
success: true,
message: '',
result: {
userName: "admin",
token:'admin'
},
};
});
import { createStore } from 'vuex'
export default createStore({
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
}
})
import { createPinia } from "pinia";
// 创建 Pinia 实例
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);
export default pinia;
import moment from "moment";
import { defineStore } from "pinia";
export const useUserStore = defineStore("user", {
state: () => {
return {
isConnected: false, //连接状态
messages: [],
customerInfo: {},
count: 0,
userInfo: {
userName: "admin",
},
userList: [],
};
},
actions: {
setCount(num: number) {
this.count = num;
},
setCustomerInfo(res: any) {
this.customerInfo = res;
},
setUserInfo(res: any) {
this.userInfo = res;
},
setUserListMessages(res: any) {
const userList: any = this.userList || [];
const obj = {
isSent: false,
msgType: res.msgType,
content: res.content,
cmd: res.cmd,
to: res.to,
id: res.id,
form: res.from,
userImg:
"https://cdn.lirimall.com//lirigo/filetempImage/新鲜水果_1661668973048.png",
time: moment(res.createTime).format("YYYY-DD-MM HH:mm:ss"),
};
const info = {
userId: res.id,
userName: res.from,
messages: [obj],
userImg: obj.userImg,
};
if (
userList.length > 0 &&
userList.some((item: any) => item.userName == res.from)
) {
userList.forEach((item: any) => {
if (item.userName == res.from) item.messages.push(obj);
});
} else {
userList.push(info);
}
this.userList = userList;
},
setUserNameMessage(res: any) {
const friends = res.friends;
for (const key in friends) {
const chatDatas = friends[key];
chatDatas.forEach((item: any) => {
item.userImg =
"https://cdn.lirimall.com//lirigo/filetempImage/新鲜水果_1661668973048.png";
item.time = moment(res.createTime).format("YYYY-DD-MM HH:mm:ss");
});
for (const index in chatDatas) {
const userId = chatDatas[index].from;
this.userList.forEach((item: any) => {
if (item && item?.userName == userId) {
item.messages = chatDatas;
}
});
}
}
},
connect() {
// 连接成功后,将 isConnected 状态设置为 true
this.isConnected = true;
},
disconnect() {
// 断开连接或退出登录时,将 isConnected 状态设置为 false
this.isConnected = false;
},
},
persist: true,
});
export function getShortDate(): string {
const now = new Date();
let month: string = (now.getMonth() + 1).toString();
if (month.length < 2) {
month = "0" + month;
}
let day: string = now.getDate().toString();
if (day.length < 2) {
day = "0" + day;
}
let hour: string = now.getHours().toString();
if (hour.length < 2) {
hour = "0" + hour;
}
let minutes: string = now.getMinutes().toString();
if (minutes.length < 2) {
minutes = "0" + minutes;
}
return month + "-" + day + " " + hour + ":" + minutes;
}
import { ElMessage } from "element-plus";
import { useUserStore } from "../store/modules/user";
let websocket: WebSocket | null = null; // 用于存储实例化后websocket
let rec: any; // 断线重连后,延迟5秒重新创建WebSocket连接 rec用来存储延迟请求的代码
// 创建websocket
function creatWebSocket(wsUrl: string) {
// 判断当前浏览器是否支持WebSocket
if ("WebSocket" in window) {
console.log("当前浏览器支持 WebSocket");
} else if ("MozWebSocket" in window) {
console.log("当前浏览器支持 MozWebSocket");
} else {
console.log("当前浏览器不支持 WebSocket");
}
try {
initWebSocket(wsUrl); // 初始化websocket连接
} catch (e) {
console.log("尝试创建连接失败");
reConnect(wsUrl); // 如果无法连接上 webSocket 那么重新连接!可能会因为服务器重新部署,或者短暂断网等导致无法创建连接
}
}
// 初始化websocket
function initWebSocket(wsUrl: string) {
if (!websocket) websocket = new WebSocket(wsUrl);
websocket.onopen = function () {
websocketOpen();
};
// // 接收
websocket.onmessage = function (e: MessageEvent<any>) {
websocketonmessage(e);
};
// 连接发生错误
websocket.onerror = function () {
console.log("WebSocket连接发生错误");
// isConnect = false; // 连接断开修改标识
reConnect(wsUrl); // 连接错误 需要重连
};
websocket.onclose = function (e) {
websocketclose(e);
};
}
// 定义重连函数
const reConnect = (wsUrl: string) => {
console.log("尝试重新连接");
if (useUserStore().isConnected) return; // 如果已经连上就不在重连了
rec && clearTimeout(rec);
rec = setTimeout(function () {
// 延迟5秒重连 避免过多次过频繁请求重连
creatWebSocket(wsUrl);
}, 5000);
};
// 创建连接
function websocketOpen() {
console.log("连接成功");
useUserStore().connect();
}
// 数据接收
function websocketonmessage(e: MessageEvent<any>) {
const res = JSON.parse(e.data); // 解析JSON格式的数据
console.log(res, "发送一次");
// 下面的判断则是后台返回的接收到的数据 如何处理自己决定
if (res.command == 11) {
//将数据放在store中
useUserStore().setUserListMessages(res.data);
} else if (res.command == 20) {
useUserStore().setUserNameMessage(res.data);
}
}
// 关闭
function websocketclose(e: any) {
useUserStore().disconnect(); // 修改连接状态
}
// 数据发送
function websocketsend(res: any) {
console.log(websocket, "websocket");
if (websocket && useUserStore().isConnected) {
// 检查连接状态
console.log("发送的数据", websocket);
websocket.send(JSON.stringify(res));
} else {
ElMessage({
showClose: true,
message: "请选择设备连接",
type: "error",
});
}
}
// 实际调用的方法==============
// 发送
function sendWebSocket(data: any) {
// 如果未保持连接状态 不允许直接发送消息 提示请选择连接设备
if (!useUserStore().isConnected) {
ElMessage({
showClose: true,
message: "请选择设备连接",
type: "error",
});
} else {
websocketsend(data);
console.log("------------------");
}
}
// 关闭
const closeWebSocket = () => {
if (websocket) {
websocket.close();
ElMessage({
showClose: true,
message: "设备已关闭",
type: "success",
});
}
};
// function initWebSocket(){
// const store = useUserStore()
// console.log(store.isConnected,'打印22')
// }
// export { initWebSocket, };
export { initWebSocket, sendWebSocket, creatWebSocket, closeWebSocket };
<template>
<div class="common-layout">
<el-container>
<el-header
:style="{
height: '50px',
width: '100%',
backgroundColor: '#1890ff',
'line-height': '50px',
}"
>
<p class="centered-text">{{customerInfo.name}}</p>
</el-header>
<el-container>
<el-aside width="280px">
<el-menu
active-text-color="#000"
background-color="#fff"
default-active="1"
<el-aside width="280px">
<el-header class="el-header-left">
<el-input placeholder="搜索" />
</el-header>
<div
active-text-color="#000"
background-color="#fff"
default-active="1"
>
<div
class="el-menu-item"
:class="getMenuItem(item)"
:index="item?.userId"
:key="item?.userId"
v-for="item in userList"
@click="handleMenuClick(item)"
>
<el-menu-item
:index="item.userId"
:key="item.userId"
v-for="item in userList"
@click="handleMenuClick(item)"
>
<div class="user-info-box">
<div class="user-img-box">
<img :src="item.userImg" alt="" />
</div>
<div class="user-info-right">
<div>
<div class="user-name-box">
<span class="user-name">{{ item.name }}</span>
<div class="label pc">
pc端
</div>
</div>
<div>
<span class="user-reply">回复</span>
<div class="user-info-box">
<div class="user-img-box">
<img :src="item.userImg" alt="" />
</div>
<div class="user-info-right">
<div class="user-box-right-nbs">
<div class="user-name-box">
<span class="user-name">{{ item?.userName }}</span>
<div class="user-time">
05-19 16:38
</div>
</div>
<div class="user-time">
05-19 16:38
<div>
<span class="user-reply">
{{
item?.messages[
item?.messages.length - 1
]?.content.includes('http')
? '[图片]'
: item.messages[item.messages.length - 1]?.content
}}
</span>
</div>
</div>
</div>
</el-menu-item>
</el-menu>
</el-aside>
<el-container>
<el-main
:style="{
height: '600px',
width: '100%',
border: '1px solid #ccc',
}"
</div>
</div>
</div>
</el-aside>
<el-container class="el-container-center" v-if="customerInfo.userName">
<el-header class="el-header-center">
<p class="name">{{ customerInfo.userName }}</p>
<p class="url">US|https://www.ibeautytop.com</p>
</el-header>
<el-main
id="srollId"
ref="srollId"
:style="{
height: '600px',
width: '100%',
border: '1px solid #ccc',
}"
>
<div
class="message-container"
v-for="(message, index) in messages"
:key="index"
:class="getMessageClass(message?.isSent)"
>
<div
class="message-container"
v-for="(message, index) in messages"
:key="index"
:class="getMessageClass(message.isSent)"
>
<div v-if="message.isSent" class="message-container">
<div class="bubble">
<div class="message" v-html="message.content"></div>
</div>
<div class="avatar">
<img
src="../assets/logo.png"
alt="Avatar"
class="avatar-image"
<div class="time">{{ message.time }}</div>
<div v-if="message.isSent" class="message-container">
<div class="bubble">
<div
v-if="message?.msgType == 0"
class="message"
v-html="message?.content"
@click.prevent="handleMessageClick($event)"
></div>
<div v-else class="img-wraper">
<el-image
:src="message?.content"
:preview-src-list="[message?.content]"
/>
</div>
</div>
<div v-if="!message.isSent" class="message-container">
<div class="avatar">
<img
src="../assets/logo.png"
alt="Avatar"
class="avatar-image"
/>
</div>
<div class="bubble">
<div
class="message"
v-html="message.content"
@click.prevent="handleMessageClick($event)"
></div>
</div>
<div class="avatar">
<img
src="../assets/logo.png"
alt="Avatar"
class="avatar-image"
/>
</div>
</div>
</el-main>
<el-footer class="el-footer">
<AutomaticPrompt
@keydown.enter="handleButtonClick"
@updateState="getState"
ref="automaticPromptRef"
></AutomaticPrompt>
<el-button
type="primary"
plain
class="btn-send"
style="width: 50px;"
@click.stop="handleButtonClick"
>
发送
</el-button>
</el-footer>
</el-container>
<el-aside width="280px">
<div class="customer-info user-wrapper">
<div v-if="customerInfo.userId > 0" class="user">
<div v-if="!message.isSent" class="message-container">
<div class="avatar">
<img :src="customerInfo.userImg" />
</div>
<div class="name line1">
<span>{{ customerInfo.name }}</span>
<img
:src="message?.userImg"
class="avatar-image"
/>
</div>
<div class="label">
<span class="label pc">PC端</span>
<div class="bubble">
<div
v-if="message?.msgType == 0"
class="message"
v-html="message?.content"
@click.prevent="handleMessageClick($event)"
></div>
<div v-else class="img-wraper">
<el-image
:src="message?.content"
:preview-src-list="[message?.content]"
/>
</div>
</div>
</div>
<div v-if="customerInfo.userId > 0" class="user-info">
<div class="item">
<span>IP</span>
<span>{{ customerInfo.customerIp }}</span>
</div>
</el-main>
<el-footer class="el-footer">
<AutomaticPrompt
@keydown.enter="handleButtonClick"
@updateState="getState"
ref="automaticPromptRef"
></AutomaticPrompt>
<el-button
type="primary"
plain
class="btn-send"
style="width: 50px;"
@click.stop="handleButtonClick"
>
发送
</el-button>
</el-footer>
</el-container>
<el-container class="el-container-center" v-else></el-container>
<el-aside width="400px">
<div>
<el-header class="el-header-right">
<img src="../assets/logo.png" alt="Avatar" />
<div class="name">询价单</div>
</el-header>
<div class="customer-info user-wrapper">
<div class="customer-info-right">
<div class="customer-info-box">
<div class="avatar-box">
<img src="../assets/shop.jpg" alt="Avatar" />
</div>
<div class="avatar-right">
<div class="avatar-right-name">
Industrial 5V 12V RS232 RS-232 Parallel PCI PC
</div>
<div class="avatar-right-price">
<div>20.00</div>
<div>USD</div>
</div>
<div class="avatar-input-box">
<div>
<el-input-number
class="avatar-number-input"
:min="1"
@change="handleChange"
v-model="count"
:max="10"
/>
</div>
<div class="avatar-input-right">
<div class="change">更换</div>
<div class="delete">删除</div>
</div>
</div>
</div>
</div>
<div class="item">
<span>地区</span>
<span>{{ customerInfo.province }} {{ customerInfo.city }}</span>
<div class="add">
<img src="../assets/add-line.png" />
<div>添加</div>
</div>
</div>
<div class="form">
<el-form
ref="ruleFormRef"
style="max-width: 600px;"
:model="ruleForm"
label-position="top"
status-icon
label-width="auto"
:inline="false"
>
<el-form-item label="客户名称" prop="pass">
<el-input
v-model="ruleForm.pass"
type="password"
placeholder="默认展示"
autocomplete="off"
/>
</el-form-item>
<el-form-item label="国家/地区" prop="checkPass">
<el-input
v-model="ruleForm.checkPass"
type="password"
placeholder="默认展示"
autocomplete="off"
/>
</el-form-item>
<el-form-item label="Email" prop="age">
<el-input
placeholder="默认展示"
v-model.number="ruleForm.age"
/>
</el-form-item>
<el-form-item label="WatchApp" prop="age">
<el-input
placeholder="默认展示"
v-model.number="ruleForm.age"
/>
</el-form-item>
<el-form-item label="备注" prop="age">
<el-input
placeholder="默认展示"
v-model.number="ruleForm.age"
/>
</el-form-item>
<el-form-item label="备注" prop="age">
<el-input
placeholder="默认展示"
v-model.number="ruleForm.age"
type="textarea"
:rows="8"
/>
</el-form-item>
</el-form>
</div>
</div>
</el-aside>
</el-container>
</div>
</el-aside>
</el-container>
</div>
</template>
<script lang="ts" setup>
import '../assets/font/iconfont.css'
import { ref, onMounted, reactive } from 'vue'
import {
ref,
onMounted,
reactive,
watch,
nextTick,
getCurrentInstance,
toRaw,
} from 'vue'
import { getShortDate } from '../utils/index'
import { useUserStore } from '../store/modules/user'
import AutomaticPrompt from '../components/AutomaticPrompt.vue'
import axios from 'axios'
import ImageViewer from '@luohc92/vue3-image-viewer'
import {
closeWebSocket,
initWebSocket,
sendWebSocket,
} from '../utils/websocket'
import type { FormInstance } from 'element-plus'
import '@luohc92/vue3-image-viewer/dist/style.css'
const ruleForm = ref({})
const ruleFormRef = ref<FormInstance>()
const customerInfo = ref({})
const userList = reactive([
{
userImg: require('../assets/logo.png'),
name: '张伟豪',
userId: '1',
province: '湖北省',
city: '荆州市',
customerIp: '127.0.0.1',
},
{
userImg: require('../assets/logo.png'),
name: '罗宏盛',
userId: '2',
province: '湖南省',
city: '长沙市',
customerIp: '127.0.0.2',
},
{
userImg: require('../assets/logo.png'),
name: '钟嘉豪',
userId: '3',
customerIp: '127.0.0.3',
province: '广东省',
city: '深圳市',
},
])
customerInfo.value = userList[0]
const messages = ref([])
const count = ref(0)
const store = useUserStore()
const userList = store.userList
const automaticPromptRef = ref('')
let msg = ''
const messages = ref([])
//进入页面直接发送请求从后端获取热点数据
onMounted(async () => {
count.value = store.count
setMessage()
})
//设置message
const setMessage = () => {
customerInfo.value = store.customerInfo
messages.value = customerInfo.value.messages
setSrollHeight()
}
//获取子组件中state的值,这个好像是写多余了,可以直接使用automaticPromptRef.value.setState('');获取state值
const getState = (v: string) => {
msg = v
}
const handleChange = (val: any) => {
store.setCount(val)
}
watch(
userList,
(newVal, oldVal) => {
if (newVal && newVal.length > 0) {
if (customerInfo.value.userName) {
messages.value =
newVal.find((item: any) => {
return item.userName == customerInfo.value.userName
}).messages || {}
}
}
},
{ deep: true },
)
watch(
messages,
(newVal, oldVal) => {
if (newVal?.length > 0) {
setSrollHeight()
}
},
{ deep: true },
)
const setSrollHeight = () => {
nextTick(() => {
const div = document.getElementById('srollId')
if(div) div.scrollTop = div?.scrollHeight
})
}
//切换聊天人
const handleMenuClick = (item:object)=>{
customerInfo.value=item
messages.value = []
}
//对机器人回复的【link】标签进行渲染(替换字符串)
const formatString = (str: any) => {
str = str.replace(
/(\[link submit="faqvote.*?\])/g,
'<a class="underline-link" href="">',
)
const replacedStr1 = str.replace(
/(\[link.*?\])/g,
'<br><a class="underline-link" href="">',
)
const replacedStr2 = replacedStr1.replace(/\[\/link\]/g, `</a>`)
const replacedStr3 = replacedStr2.replace(/\\r\\n/g, `<br>`)
const replacedStr4 = replacedStr3.replace(/\\\\r\\\\n/g, ``)
return replacedStr4
const handleMenuClick = (item: object) => {
customerInfo.value = item
store.setCustomerInfo(item)
messages.value = item?.messages || []
const data = {
cmd: '19',
type: '1',
fromUserId: item?.userName,
group_id: '',
userId: store.userInfo.userName,
}
sendWebSocket(data)
setSrollHeight()
}
//发送按钮
const handleButtonClick = () => {
messages.value.push({ content: msg, isSent: true })
sendMsg(msg)
automaticPromptRef.value.setState('')
}
//向后端发送请求逻辑
const sendMsg = async (msg: string) => {
let responseMsg = ''
try {
//请求后端问题答案,并对问题答案进行封装,这里需要各位对各自的后端返回格式进行解析
const response = await axios.get(`http://localhost:8080/question/` + msg)
//正常情况的文本处理
if (response.data.content !== undefined) {
responseMsg = formatString(response.data.content)
console.log(responseMsg)
}
//图片处理
let mark = false
let imageTxt = ''
let imageUrl = ''
for (let i = 0; i < response.data.commands.length; i++) {
if (
response.data.commands[i].name === 'imgmsg' ||
response.data.commands[i].name === 'txtimage'
) {
mark = true
for (let j = 0; j < response.data.commands[i].args.length; j++) {
if (response.data.commands[i].args[j].includes('http://')) {
imageUrl += response.data.commands[i].args[j]
} else {
imageTxt += response.data.commands[i].args[j] + '<br>'
}
}
}
}
if (mark) {
responseMsg =
responseMsg +
'<br>' +
imageTxt +
'<img src="' +
imageUrl +
'" alt="Image" style="width: 200px; height: auto;">'
}
if (
response.data.relatedQuestions !== undefined &&
response.data.relatedQuestions.length !== 0
) {
responseMsg = responseMsg + '<br>您可能想问:'
for (let i = 0; i < response.data.relatedQuestions.length; i++) {
let responseIndex = i + 1
responseMsg =
responseMsg +
'<br>' +
responseIndex +
':' +
'<a class="underline-link" href="">' +
response.data.relatedQuestions[i] +
'</a>'
}
}
} catch (error) {
console.error(error)
responseMsg = '网络异常'
let data = {
content: msg,
isSent: true,
cmd: '11',
msgType: 0,
chatType: '2',
group_id: '',
time: getShortDate(),
to: customerInfo.value.userName,
form: store.userInfo.userName,
}
messages.value.push({ content: responseMsg, isSent: false })
messages.value?.push(data)
sendWebSocket(data)
automaticPromptRef.value.setState('')
}
const handleMessageClick = (event: any) => {
......@@ -302,43 +382,77 @@ const handleMessageClick = (event: any) => {
const handleLinkClick = (msg: string) => {
messages.value.push({ content: msg, isSent: true })
sendMsg(msg)
// sendMsg(msg)
}
//消息框样式动态选择
const getMessageClass = (isSent) => {
return isSent ? 'message-container-right' : 'message-container-left'
}
//进入页面直接发送请求从后端获取热点数据
onMounted(async () => {
let responseMsg = ''
try {
const response = await axios.get(`http://localhost:8080/getHotAsk`)
responseMsg = responseMsg + '<br>您可能想问:'
for (let i = 0; i < response.data.length; i++) {
let responseIndex = i + 1
responseMsg =
responseMsg +
'<br>' +
responseIndex +
':' +
'<a class="underline-link" href="">' +
response.data[i] +
'</a>'
}
} catch (error) {
console.error(error)
responseMsg = '网络异常,暂时无法加载出热点问题'
}
messages.value.push({ content: responseMsg, isSent: false })
})
//左边按钮操作
const getMenuItem = (item) => {
return item.userName == customerInfo.value.userName ? 'is-active' : ''
}
</script>
<style lang="scss" scoped>
.el-header-left {
height: 76px;
width: 100%;
border: 1px solid #e6e8ed;
text-align: center;
padding: 16px;
.el-input {
height: 44px;
width: 100%;
}
}
.el-container-center {
background: #e6e8ed;
}
.el-header-center {
height: 76px;
width: 100%;
border: 1px solid #e6e8ed;
padding: 16px 24px;
display: flex;
justify-content: space-between;
flex-direction: column;
.name {
color: #010914;
font-family: 'Inter';
font-size: 18px;
font-style: normal;
font-weight: 600;
}
.url {
color: #798494;
}
}
.el-header-right {
height: 76px;
width: 100%;
border: 1px solid #e6e8ed;
display: flex;
align-items: center;
img {
width: 15.42px;
height: 17.92px;
margin-right: 14px;
}
.name {
color: #010914;
font-family: 'PingFang SC';
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: 20px;
}
}
.el-footer {
width: 100%;
border: 1px solid #ccc;
border-top: 0px;
padding: 10px;
height: calc(100vh - 600px - 50px);
height: calc(100vh - 600px - 76px);
position: relative;
.btn-send {
position: absolute;
......@@ -349,7 +463,7 @@ onMounted(async () => {
.el-menu-item {
line-height: initial;
padding: 0px !important;
height: auto;
height: 86px;
border-left: 3px solid transparent;
&.is-active {
background: #eff0f1;
......@@ -360,14 +474,16 @@ onMounted(async () => {
display: flex;
width: 100%;
height: 100%;
padding: 10px;
padding:0px 10px;
box-sizing: border-box;
justify-content: space-between;
.user-img-box {
margin-right: 10px;
display: flex;
align-items: center;
img {
width: 42px;
height: 42px;
border-radius: 50%;
width: 40px;
height: 40px;
}
}
.user-info-right {
......@@ -376,6 +492,9 @@ onMounted(async () => {
align-items: center;
height: 100%;
width: 100%;
.user-box-right-nbs {
width: 100%;
}
.label {
margin-left: 5px;
color: #3875ea;
......@@ -392,8 +511,12 @@ onMounted(async () => {
.user-name-box {
display: flex;
align-items: center;
justify-content: space-between;
.user-name {
max-width: 150px;
word-break:break-all;
text-overflow:ellipsis;
overflow: hidden;
max-width: 120px;
font-size: 16px;
color: rgba(0, 0, 0, 0.65);
margin-right: 10px;
......@@ -411,125 +534,104 @@ onMounted(async () => {
}
}
.customer-info {
background: #fff;
.customer-info-right {
.customer-info-box {
display: flex;
.avatar-box {
width: 88px;
height: 88px;
border-radius: 8px;
margin-right: 12px;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
.avatar-input-box {
display: flex;
align-items: center;
margin-top: 8px;
justify-content: space-between;
.change {
margin-right: 27px;
color: #010914;
text-align: right;
font-family: 'PingFang SC';
font-size: 12px;
font-style: normal;
font-weight: 400;
}
.delete {
color: #ff6600;
text-align: right;
font-family: 'PingFang SC';
font-size: 12px;
font-style: normal;
font-weight: 400;
}
}
.avatar-input-right {
display: flex;
}
.avatar-right {
flex: 1;
.avatar-right-name {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
flex: 1 0 0;
overflow: hidden;
color: #010914;
font-feature-settings: 'clig' off, 'liga' off;
text-overflow: ellipsis;
font-family: 'Inter';
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 20px;
}
.avatar-right-price {
display: flex;
color: #010914;
font-feature-settings: 'clig' off, 'liga' off;
font-family: 'Inter';
font-size: 16px;
font-style: normal;
line-height: 24px;
div {
&:nth-of-type(1) {
margin-right: 4px;
font-weight: 600;
}
&:nth-of-type(2) {
font-weight: 400;
}
}
}
}
}
}
.customer-info {
border-left: 1px solid #ececec;
.el-input__wrapper {
width: 48px;
}
.user-wrapper {
padding: 0 8px;
}
.user-wrapper .user {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
padding: 16px 0;
border-bottom: 1px solid #ececec;
}
.user-wrapper .user .avatar {
width: 42px;
height: 42px;
}
.user-wrapper .user .avatar img {
display: block;
width: 100%;
height: 100%;
border-radius: 50%;
}
.user-wrapper .user .name {
max-width: 150px;
margin-left: 10px;
font-size: 16px;
color: rgba(0, 0, 0, 0.65);
}
.user-wrapper .user .label {
margin-left: 5px;
font-size: 12px;
border-radius: 2px;
padding: 2px 5px;
}
.user-wrapper .user .label.pc {
background: rgba(100, 64, 194, 0.16);
color: #6440c2;
}
.user-wrapper .user .label {
margin-left: 5px;
font-size: 12px;
border-radius: 2px;
padding: 2px 5px;
padding: 16px;
}
.user-info {
padding-top: 15px;
padding-bottom: 10px;
}
.user-info .item {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
margin-bottom: 10px;
font-size: 14px;
color: #333;
}
.user-info .item span {
font-size: 13px;
color: #666;
width: 70px;
&:nth-of-type(2){
width: 100px;
}
}
.chat-textarea {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
height: 214px;
border-top: 1px solid #ececec;
}
.chat-bar {
height: 50px;
width: 100%;
line-height: 50px;
text-align: left;
}
.chat-textarea .textarea-box {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
min-height: 0;
position: relative;
}
.chat-textarea .editable {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
padding: 4px 7px;
overflow-x: hidden;
overflow-y: auto;
font-size: 14px;
line-height: 1.5;
color: #515a6e;
}
.send-btn {
position: absolute;
right: 0;
......@@ -543,11 +645,6 @@ onMounted(async () => {
margin-top: 10px;
margin-right: 10px;
}
.centered-text {
text-align: center;
color: #fff;
font-weight: bold;
}
.underline-link {
text-decoration: underline;
......@@ -557,8 +654,15 @@ onMounted(async () => {
display: flex;
align-items: center;
margin-bottom: 10px;
position: relative;
}
.message-container .time {
text-align: center;
color: #999;
font-size: 14px;
position: absolute;
width: 100%;
}
.avatar {
margin-left: 10px; /* 修改这里将头像放在消息框的右边 */
}
......@@ -575,6 +679,17 @@ onMounted(async () => {
color: #000;
padding: 10px;
border-radius: 5px;
max-width: 320px;
background: #f5f5f5;
border-radius: 10px;
color: #000;
font-size: 14px;
overflow: hidden;
.img-wraper img {
max-width: 100%;
height: auto;
display: block;
}
}
.message {
......@@ -589,4 +704,62 @@ onMounted(async () => {
.message-container-left {
justify-content: flex-start;
}
.avatar-number-input :deep(.el-input) {
width: 102px !important;
}
.avatar-number-input {
width: 102px !important;
}
.add {
display: flex;
height: var(--Layout-lg, 32px);
padding: 0 var(--Spacing-lg, 12px) 0 var(--Spacing-md, 8px);
justify-content: center;
align-items: center;
gap: 4px;
border-radius: var(--Radius-xs, 4px);
border: var(--Edges-zero, 1px) solid var(--color-Stroke-Weak, #e6e8ed);
background: var(--color-bg-Program-White, #fff);
width: 72px;
height: 32px;
margin-top: 16px;
img {
width: 20px;
height: 20px;
}
}
.form {
margin-top: 32px;
:deep(.el-form-item__label) {
color: #010914;
font-family: 'PingFang SC';
font-size: 14px;
font-style: normal;
font-weight: bolder;
line-height: 20px;
}
:deep(.el-input__wrapper) {
padding: 0px;
}
:deep(.el-input__inner) {
padding: 8px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
flex: 1 0 0;
overflow: hidden;
color: #798494;
font-feature-settings: 'clig' off, 'liga' off;
text-overflow: ellipsis;
font-family: 'PingFang SC';
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 20px;
background: #f2f3f5;
}
:deep(.el-textarea__inner) {
background: #f2f3f5;
}
}
</style>
......@@ -44,12 +44,15 @@
<script lang="ts">
import { LoginData } from '../type/Login'
import { reactive, ref } from 'vue'
import { useUserStore } from '../store/modules/user'
import type { FormInstance } from 'element-plus'
import { useRouter } from 'vue-router'
import { Login } from '../axios/model/user'
export default {
setup() {
const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive(new LoginData())
const store = useUserStore()
const router = useRouter()
const rules = reactive({
userName: [
......@@ -75,20 +78,24 @@ export default {
formEl.resetFields()
}
//登录
const submitForm = (formEl: FormInstance | undefined) => {
console.log(formEl, 'formEl')
let query = {}
if (!formEl) return
formEl.validate((valid: boolean) => {
console.log(valid)
if (valid) {
console.log('submit!')
router.push('/')
Login(query).then(({ success, message,result }: any) => {
if (success) {
router.push('/')
store.setUserInfo(result)
}
})
} else {
console.log('error submit!')
return false
}
})
}
return { ruleForm, ruleFormRef, rules, resetForm, submitForm }
},
}
......
......@@ -33,7 +33,7 @@
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
, "src/minxins/minxin.js" ],
"exclude": [
"node_modules"
]
......
......@@ -13,5 +13,5 @@ module.exports = defineConfig({
resolvers: [ElementPlusResolver()],
}),
],
}
},
})
\ No newline at end of file
......@@ -1034,7 +1034,7 @@
"@element-plus/icons-vue@^2.3.1":
version "2.3.1"
resolved "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz#1f635ad5fdd5c85ed936481525570e82b5a8307a"
resolved "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz"
integrity sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==
"@eslint-community/eslint-utils@^4.2.0":
......@@ -1226,6 +1226,11 @@
resolved "https://registry.npmmirror.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz"
integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==
"@socket.io/component-emitter@~3.1.0":
version "3.1.0"
resolved "https://registry.npmmirror.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz"
integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==
"@soda/friendly-errors-webpack-plugin@^1.8.0":
version "1.8.1"
resolved "https://registry.npmmirror.com/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.1.tgz"
......@@ -1869,7 +1874,7 @@
optionalDependencies:
prettier "^1.18.2 || ^2.0.0"
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.5.1":
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.5.0", "@vue/devtools-api@^6.5.1":
version "6.6.1"
resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.1.tgz"
integrity sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==
......@@ -2077,6 +2082,11 @@
"@webassemblyjs/ast" "1.11.6"
"@xtuc/long" "4.2.2"
"@xmldom/xmldom@^0.8.6":
version "0.8.10"
resolved "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99"
integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==
"@xtuc/ieee754@^1.2.0":
version "1.2.0"
resolved "https://registry.npmmirror.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz"
......@@ -2223,7 +2233,7 @@ arch@^2.1.1:
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz"
resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz"
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
dependencies:
sprintf-js "~1.0.2"
......@@ -2257,7 +2267,7 @@ async@^2.6.4:
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
at-least-node@^1.0.0:
......@@ -2279,7 +2289,7 @@ autoprefixer@^10.2.4:
axios@^1.6.7:
version "1.6.7"
resolved "https://registry.npmmirror.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7"
resolved "https://registry.npmmirror.com/axios/-/axios-1.6.7.tgz"
integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==
dependencies:
follow-redirects "^1.15.4"
......@@ -2399,7 +2409,7 @@ boolbase@^1.0.0:
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
dependencies:
balanced-match "^1.0.0"
......@@ -2662,11 +2672,16 @@ colorette@^2.0.10:
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
commander@*:
version "12.0.0"
resolved "https://registry.npmmirror.com/commander/-/commander-12.0.0.tgz#b929db6df8546080adfd004ab215ed48cf6f2592"
integrity sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==
commander@^2.20.0:
version "2.20.3"
resolved "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz"
......@@ -2780,6 +2795,14 @@ core-util-is@~1.0.0:
resolved "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz"
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
cos-wx-sdk-v5@^1.6.0:
version "1.6.0"
resolved "https://registry.npmmirror.com/cos-wx-sdk-v5/-/cos-wx-sdk-v5-1.6.0.tgz#dfdf1724863177e39c2ca9e20ae5507a71570bb3"
integrity sha512-FvOsGwllO2ZeC3oIiaLHSMKYDH5AT+IhMyzzqbSW2iOtl/jgIq/IlYgIIExfzdiwl/t2/5bsiC4GgYM1i2qbKQ==
dependencies:
"@xmldom/xmldom" "^0.8.6"
mime "^2.4.6"
cosmiconfig@^6.0.0:
version "6.0.0"
resolved "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz"
......@@ -2804,8 +2827,8 @@ cosmiconfig@^7.0.0:
cross-spawn@^5.0.1:
version "5.1.0"
resolved "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-5.1.0.tgz"
integrity sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz"
integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
dependencies:
lru-cache "^4.0.1"
shebang-command "^1.2.0"
......@@ -2964,7 +2987,7 @@ debounce@^1.2.1:
debug@2.6.9:
version "2.6.9"
resolved "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz"
resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
dependencies:
ms "2.0.0"
......@@ -2976,7 +2999,7 @@ debug@^3.2.7:
dependencies:
ms "^2.1.1"
debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2:
version "4.3.4"
resolved "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
......@@ -3037,7 +3060,7 @@ define-properties@^1.2.1:
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
depd@2.0.0:
......@@ -3184,7 +3207,7 @@ emoji-regex@^8.0.0:
emoji.json@^15.1.0:
version "15.1.0"
resolved "https://registry.npmmirror.com/emoji.json/-/emoji.json-15.1.0.tgz#1a1bac02f95983c808601a74b0b367677e52db3b"
resolved "https://registry.npmmirror.com/emoji.json/-/emoji.json-15.1.0.tgz"
integrity sha512-GqE6SCE8rSc5Gyd+oh6s/pkoNSW/pULdgJTB6jd/sM87FWA/a1nmvFMdWBjvSA5vdomzDvZgy584KNgzdYJwDA==
emojis-list@^3.0.0:
......@@ -3204,6 +3227,22 @@ end-of-stream@^1.1.0:
dependencies:
once "^1.4.0"
engine.io-client@~6.5.2:
version "6.5.3"
resolved "https://registry.npmmirror.com/engine.io-client/-/engine.io-client-6.5.3.tgz"
integrity sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==
dependencies:
"@socket.io/component-emitter" "~3.1.0"
debug "~4.3.1"
engine.io-parser "~5.2.1"
ws "~8.11.0"
xmlhttprequest-ssl "~2.0.0"
engine.io-parser@~5.2.1:
version "5.2.2"
resolved "https://registry.npmmirror.com/engine.io-parser/-/engine.io-parser-5.2.2.tgz"
integrity sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==
enhanced-resolve@^5.0.0, enhanced-resolve@^5.15.0:
version "5.15.1"
resolved "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz"
......@@ -3420,7 +3459,7 @@ espree@^9.0.0:
esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.npmmirror.com/esprima/-/esprima-4.0.1.tgz"
resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
esquery@^1.4.0:
......@@ -3476,7 +3515,7 @@ event-pubsub@4.3.0:
eventemitter3@^4.0.0:
version "4.0.7"
resolved "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-4.0.7.tgz"
resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
events@^3.2.0:
......@@ -3698,7 +3737,7 @@ fork-ts-checker-webpack-plugin@^6.4.0:
form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
......@@ -3778,8 +3817,8 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4:
get-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/get-stream/-/get-stream-3.0.0.tgz"
integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==
resolved "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz"
integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
get-stream@^4.0.0:
version "4.1.0"
......@@ -3933,7 +3972,7 @@ highlight.js@^10.7.1:
hosted-git-info@^2.1.4:
version "2.8.9"
resolved "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz"
resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz"
integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
hpack.js@^2.1.6:
......@@ -4111,7 +4150,7 @@ inflight@^1.0.4:
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz"
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
inherits@2.0.3:
......@@ -4206,7 +4245,7 @@ is-plain-obj@^3.0.0:
is-plain-object@^2.0.4:
version "2.0.4"
resolved "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-2.0.4.tgz"
resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz"
integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==
dependencies:
isobject "^3.0.1"
......@@ -4332,7 +4371,7 @@ json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1:
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz"
resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema-traverse@^1.0.0:
......@@ -4653,9 +4692,14 @@ mime@1.6.0:
resolved "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
mime@^2.4.6:
version "2.6.0"
resolved "https://registry.npmmirror.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367"
integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==
mimic-fn@^1.0.0:
version "1.2.0"
resolved "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-1.2.0.tgz"
resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz"
integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
mimic-fn@^2.1.0:
......@@ -4673,7 +4717,7 @@ mini-css-extract-plugin@^2.5.3:
minimalistic-assert@^1.0.0:
version "1.0.1"
resolved "https://registry.npmmirror.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz"
resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz"
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
minimatch@^3.0.4, minimatch@^3.1.1:
......@@ -4719,11 +4763,23 @@ mlly@^1.2.0, mlly@^1.4.2:
pkg-types "^1.0.3"
ufo "^1.3.2"
mockjs@^1.1.0:
version "1.1.0"
resolved "https://registry.npmmirror.com/mockjs/-/mockjs-1.1.0.tgz#e6a0c378e91906dbaff20911cc0273b3c7d75b06"
integrity sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==
dependencies:
commander "*"
module-alias@^2.2.2:
version "2.2.3"
resolved "https://registry.npmmirror.com/module-alias/-/module-alias-2.2.3.tgz"
integrity sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==
moment@^2.30.1:
version "2.30.1"
resolved "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==
mrmime@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.0.tgz"
......@@ -5118,6 +5174,19 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
resolved "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
pinia-plugin-persistedstate@^3.2.1:
version "3.2.1"
resolved "https://registry.npmmirror.com/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-3.2.1.tgz#66780602aecd6c7b152dd7e3ddc249a1f7a13fe5"
integrity sha512-MK++8LRUsGF7r45PjBFES82ISnPzyO6IZx3CH5vyPseFLZCk1g2kgx6l/nW8pEBKxxd4do0P6bJw+mUSZIEZUQ==
pinia@^2.1.7:
version "2.1.7"
resolved "https://registry.npmmirror.com/pinia/-/pinia-2.1.7.tgz#4cf5420d9324ca00b7b4984d3fbf693222115bbc"
integrity sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==
dependencies:
"@vue/devtools-api" "^6.5.0"
vue-demi ">=0.14.5"
pkg-dir@^4.1.0:
version "4.2.0"
resolved "https://registry.npmmirror.com/pkg-dir/-/pkg-dir-4.2.0.tgz"
......@@ -5454,7 +5523,7 @@ proxy-addr@~2.0.7:
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
resolved "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
pseudomap@^1.0.2:
......@@ -5702,7 +5771,7 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0:
"safer-buffer@>= 2.1.2 < 3":
version "2.1.2"
resolved "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz"
resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
sass-loader@^12.0.0:
......@@ -5857,7 +5926,7 @@ set-function-length@^1.2.1:
setprototypeof@1.1.0:
version "1.1.0"
resolved "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.1.0.tgz"
resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz"
integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
setprototypeof@1.2.0:
......@@ -5939,6 +6008,24 @@ slice-ansi@^4.0.0:
astral-regex "^2.0.0"
is-fullwidth-code-point "^3.0.0"
socket.io-client@^4.7.4:
version "4.7.4"
resolved "https://registry.npmmirror.com/socket.io-client/-/socket.io-client-4.7.4.tgz"
integrity sha512-wh+OkeF0rAVCrABWQBaEjLfb7DVPotMbu0cgWgyR0v6eA4EoVnAwcIeIbcdTE3GT/H3kbdLl7OoH2+asoDRIIg==
dependencies:
"@socket.io/component-emitter" "~3.1.0"
debug "~4.3.2"
engine.io-client "~6.5.2"
socket.io-parser "~4.2.4"
socket.io-parser@~4.2.4:
version "4.2.4"
resolved "https://registry.npmmirror.com/socket.io-parser/-/socket.io-parser-4.2.4.tgz"
integrity sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==
dependencies:
"@socket.io/component-emitter" "~3.1.0"
debug "~4.3.1"
sockjs@^0.3.24:
version "0.3.24"
resolved "https://registry.npmmirror.com/sockjs/-/sockjs-0.3.24.tgz"
......@@ -5963,7 +6050,7 @@ source-map-support@~0.5.20:
source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz"
resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@^0.7.4:
......@@ -6078,7 +6165,7 @@ string_decoder@^1.1.1:
string_decoder@~1.1.1:
version "1.1.1"
resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz"
resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
dependencies:
safe-buffer "~5.1.0"
......@@ -6486,7 +6573,7 @@ v8-compile-cache@^2.0.3:
validate-npm-package-license@^3.0.1:
version "3.0.4"
resolved "https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz"
resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz"
integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==
dependencies:
spdx-correct "^3.0.0"
......@@ -6497,7 +6584,7 @@ vary@~1.1.2:
resolved "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
vue-demi@*:
vue-demi@*, vue-demi@>=0.14.5:
version "0.14.7"
resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.7.tgz"
integrity sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==
......@@ -6529,6 +6616,11 @@ vue-loader@^17.0.0:
hash-sum "^2.0.0"
watchpack "^2.4.0"
vue-native-websocket@^2.0.15:
version "2.0.15"
resolved "https://registry.npmmirror.com/vue-native-websocket/-/vue-native-websocket-2.0.15.tgz"
integrity sha512-i3UvRL99rY8ytV0VJzcWDwY3fRPoeh2fGYvB9862JocEQOx/oCw/VtPIUwP4tSzmzJvJZNkvP71wfhfS1sVhxQ==
vue-router@^4.0.3:
version "4.3.0"
resolved "https://registry.npmmirror.com/vue-router/-/vue-router-4.3.0.tgz"
......@@ -6751,7 +6843,7 @@ whatwg-url@^5.0.0:
which@^1.2.9:
version "1.3.1"
resolved "https://registry.npmmirror.com/which/-/which-1.3.1.tgz"
resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz"
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
dependencies:
isexe "^2.0.0"
......@@ -6800,6 +6892,16 @@ ws@^8.13.0:
resolved "https://registry.npmmirror.com/ws/-/ws-8.16.0.tgz"
integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==
ws@~8.11.0:
version "8.11.0"
resolved "https://registry.npmmirror.com/ws/-/ws-8.11.0.tgz"
integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==
xmlhttprequest-ssl@~2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz"
integrity sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==
y18n@^5.0.5:
version "5.0.8"
resolved "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz"
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论