mirror of
https://github.com/cool-team-official/cool-admin-vue.git
synced 2026-02-25 14:40:28 +00:00
添加 mock 数据,添加客服聊天
This commit is contained in:
parent
cdc38f2a01
commit
9c96709e1e
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cool-admin-vue",
|
"name": "cool-admin-vue",
|
||||||
"version": "3.0.2",
|
"version": "3.1.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve",
|
"serve": "vue-cli-service serve",
|
||||||
"build": "vue-cli-service build",
|
"build": "vue-cli-service build",
|
||||||
@ -10,8 +10,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"cl-admin": "^1.3.4",
|
"cl-admin": "^1.4.0",
|
||||||
"cl-admin-crud": "^1.6.0",
|
"cl-admin-crud": "^1.6.2",
|
||||||
"cl-admin-theme": "^0.0.4",
|
"cl-admin-theme": "^0.0.4",
|
||||||
"clipboard": "^2.0.7",
|
"clipboard": "^2.0.7",
|
||||||
"codemirror": "^5.59.4",
|
"codemirror": "^5.59.4",
|
||||||
@ -20,6 +20,7 @@
|
|||||||
"echarts": "^4.5.0",
|
"echarts": "^4.5.0",
|
||||||
"element-ui": "^2.15.1",
|
"element-ui": "^2.15.1",
|
||||||
"js-beautify": "^1.13.5",
|
"js-beautify": "^1.13.5",
|
||||||
|
"mockjs": "^1.1.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"qs": "^6.9.1",
|
"qs": "^6.9.1",
|
||||||
"quill": "^1.3.7",
|
"quill": "^1.3.7",
|
||||||
|
|||||||
@ -25,6 +25,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"chat",
|
||||||
"task",
|
"task",
|
||||||
"copy",
|
"copy",
|
||||||
"distpicker",
|
"distpicker",
|
||||||
|
|||||||
@ -66,7 +66,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(["conf", "menuGroup"]),
|
...mapGetters(["menuGroup"]),
|
||||||
|
|
||||||
lastName() {
|
lastName() {
|
||||||
return _.last(this.list).name;
|
return _.last(this.list).name;
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="chat-wrap">
|
<div class="cl-chat__wrap">
|
||||||
<!-- 聊天窗口 -->
|
<!-- 聊天窗口 -->
|
||||||
<cl-dialog :visible.sync="visible" v-bind="conf">
|
<cl-dialog :visible.sync="visible" v-bind="conf">
|
||||||
<div class="chat-box">
|
<div class="cl-chat">
|
||||||
<!-- 会话区域 -->
|
<!-- 会话区域 -->
|
||||||
<div class="chat-box__session">
|
<div class="cl-chat__session">
|
||||||
<div class="chat-box__session-search">
|
<div class="cl-chat__session-search">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="session.keyWord"
|
v-model="session.keyWord"
|
||||||
placeholder="搜索"
|
placeholder="搜索"
|
||||||
@ -18,9 +18,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 会话列表 -->
|
<!-- 会话列表 -->
|
||||||
<ul class="chat-box__session-list scroller1">
|
<ul class="cl-chat__session-list scroller1" v-if="sessionList.length > 0">
|
||||||
<li
|
<li
|
||||||
class="chat-box__session-item"
|
class="cl-chat__session-item"
|
||||||
v-for="(item, index) in sessionList"
|
v-for="(item, index) in sessionList"
|
||||||
:key="index"
|
:key="index"
|
||||||
:class="{
|
:class="{
|
||||||
@ -47,18 +47,23 @@
|
|||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- 空态 -->
|
||||||
|
<div class="cl-chat__session-empty" v-else>
|
||||||
|
没有搜索到内容...
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 会话详情 -->
|
<!-- 会话详情 -->
|
||||||
<div class="chat-box__detail">
|
<div class="cl-chat__detail">
|
||||||
<template v-if="session.current">
|
<template v-if="session.current">
|
||||||
<div
|
<div
|
||||||
class="chat-box__detail-container scroller1"
|
class="cl-chat__detail-container scroller1"
|
||||||
ref="scroller"
|
ref="scroller"
|
||||||
v-loading="message.loading"
|
v-loading="message.loading"
|
||||||
>
|
>
|
||||||
<!-- 加载更多 -->
|
<!-- 加载更多 -->
|
||||||
<div class="chat-box__detail-more" v-if="message.list.length > 0">
|
<div class="cl-chat__detail-more" v-if="message.list.length > 0">
|
||||||
<el-button
|
<el-button
|
||||||
round
|
round
|
||||||
size="mini"
|
size="mini"
|
||||||
@ -72,9 +77,9 @@
|
|||||||
<message :list="message.list" />
|
<message :list="message.list" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="chat-box__detail-footer">
|
<div class="cl-chat__detail-footer">
|
||||||
<!-- 工具栏 -->
|
<!-- 工具栏 -->
|
||||||
<div class="chat-box__opbar">
|
<div class="cl-chat__opbar">
|
||||||
<ul>
|
<ul>
|
||||||
<!-- 表情 -->
|
<!-- 表情 -->
|
||||||
<li>
|
<li>
|
||||||
@ -93,7 +98,7 @@
|
|||||||
</el-popover>
|
</el-popover>
|
||||||
</li>
|
</li>
|
||||||
<!-- 图片上传 -->
|
<!-- 图片上传 -->
|
||||||
<li>
|
<li hidden>
|
||||||
<cl-upload
|
<cl-upload
|
||||||
accept="image/*"
|
accept="image/*"
|
||||||
list-type
|
list-type
|
||||||
@ -103,7 +108,7 @@
|
|||||||
</cl-upload>
|
</cl-upload>
|
||||||
</li>
|
</li>
|
||||||
<!-- 视频上传 -->
|
<!-- 视频上传 -->
|
||||||
<li>
|
<li hidden>
|
||||||
<cl-upload
|
<cl-upload
|
||||||
accept="video/*"
|
accept="video/*"
|
||||||
list-type
|
list-type
|
||||||
@ -126,7 +131,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 输入框,发送按钮 -->
|
<!-- 输入框,发送按钮 -->
|
||||||
<div class="chat-box__input">
|
<div class="cl-chat__input">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="message.value"
|
v-model="message.value"
|
||||||
placeholder="请描述您想咨询的问题"
|
placeholder="请描述您想咨询的问题"
|
||||||
@ -158,9 +163,9 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import io from "socket.io-client";
|
|
||||||
import { isString, debounce } from "cl-admin/utils";
|
|
||||||
import { mapGetters } from "vuex";
|
import { mapGetters } from "vuex";
|
||||||
|
import { isString, debounce } from "cl-admin/utils";
|
||||||
|
import io from "socket.io-client";
|
||||||
import { socketUrl } from "@/config/env";
|
import { socketUrl } from "@/config/env";
|
||||||
import Emoji from "./emoji";
|
import Emoji from "./emoji";
|
||||||
import Message from "./message";
|
import Message from "./message";
|
||||||
@ -180,14 +185,16 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
visible: false,
|
visible: false,
|
||||||
|
socket: null,
|
||||||
conf: {
|
conf: {
|
||||||
title: "聊天对话框",
|
title: "聊天对话框",
|
||||||
|
height: "650px",
|
||||||
|
width: "1000px",
|
||||||
props: {
|
props: {
|
||||||
modal: true,
|
modal: true,
|
||||||
"custom-class": "chat-box__wrap",
|
customClass: "cl-chat__dialog",
|
||||||
"append-to-body": true,
|
"append-to-body": true,
|
||||||
"close-on-click-modal": false,
|
"close-on-click-modal": false
|
||||||
width: "1000px"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
@ -212,8 +219,7 @@ export default {
|
|||||||
},
|
},
|
||||||
emoji: {
|
emoji: {
|
||||||
visible: false
|
visible: false
|
||||||
},
|
}
|
||||||
socket: null
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -233,28 +239,26 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
created() {
|
||||||
this.socket = io(`${socketUrl}?isAdmin=true&token=${this.token}`);
|
// this.socket = io(`${socketUrl}?isAdmin=true&token=${this.token}`);
|
||||||
|
// this.socket.on("connect", () => {
|
||||||
this.socket.on("connect", () => {
|
// console.log("socket connect");
|
||||||
console.log("socket connect");
|
// });
|
||||||
});
|
// this.socket.on("admin", msg => {
|
||||||
|
// this.onMessage(msg);
|
||||||
this.socket.on("admin", msg => {
|
// });
|
||||||
this.onMessage(msg);
|
// this.socket.on("error", err => {
|
||||||
});
|
// console.log(err);
|
||||||
|
// });
|
||||||
this.socket.on("error", err => {
|
// this.socket.on("disconnect", () => {
|
||||||
console.log(err);
|
// console.log("disconnect connect");
|
||||||
});
|
// });
|
||||||
|
|
||||||
this.socket.on("disconnect", () => {
|
|
||||||
console.log("disconnect connect");
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
destroyed() {
|
destroyed() {
|
||||||
|
if (this.socket) {
|
||||||
this.socket.close();
|
this.socket.close();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@ -342,7 +346,7 @@ export default {
|
|||||||
order: "updateTime",
|
order: "updateTime",
|
||||||
sort: "desc"
|
sort: "desc"
|
||||||
})
|
})
|
||||||
.then(async res => {
|
.then(res => {
|
||||||
this.session.list = res.list;
|
this.session.list = res.list;
|
||||||
this.session.pagination = res.pagination;
|
this.session.pagination = res.pagination;
|
||||||
|
|
||||||
@ -411,7 +415,10 @@ export default {
|
|||||||
scrollToBottom: debounce(function() {
|
scrollToBottom: debounce(function() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (this.$refs["scroller"]) {
|
if (this.$refs["scroller"]) {
|
||||||
this.$refs["scroller"].scrollTo(0, 999999);
|
this.$refs["scroller"].scrollTo({
|
||||||
|
top: 99999,
|
||||||
|
behavior: "smooth"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 300),
|
}, 300),
|
||||||
@ -580,12 +587,14 @@ export default {
|
|||||||
content
|
content
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (this.socket) {
|
||||||
this.socket.emit(`user@${userId}`, {
|
this.socket.emit(`user@${userId}`, {
|
||||||
contentType,
|
contentType,
|
||||||
type: 0,
|
type: 0,
|
||||||
content: JSON.stringify(content),
|
content: JSON.stringify(content),
|
||||||
sessionId: id
|
sessionId: id
|
||||||
});
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -642,22 +651,22 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.chat-box__wrap {
|
.cl-chat__dialog {
|
||||||
height: 650px;
|
|
||||||
min-width: 1000px;
|
|
||||||
margin-bottom: 0 !important;
|
margin-bottom: 0 !important;
|
||||||
|
min-width: 1000px;
|
||||||
|
|
||||||
.el-dialog__body {
|
.el-dialog__body {
|
||||||
height: calc(100% - 46px);
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-fullscreen {
|
||||||
.cl-dialog__container {
|
.cl-dialog__container {
|
||||||
height: 100%;
|
height: calc(100vh - 46px) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-box {
|
.cl-chat {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: #f7f7f7;
|
background-color: #f7f7f7;
|
||||||
@ -673,7 +682,7 @@ export default {
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
&-list {
|
||||||
height: calc(100% - 52px);
|
height: calc(100% - 52px);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
@ -684,14 +693,12 @@ export default {
|
|||||||
border-left: 5px solid #fff;
|
border-left: 5px solid #fff;
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
height: 40px;
|
|
||||||
width: 40px;
|
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
display: block;
|
display: block;
|
||||||
height: 100%;
|
height: 40px;
|
||||||
width: 100%;
|
width: 40px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
}
|
}
|
||||||
@ -741,6 +748,11 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-empty {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__detail {
|
&__detail {
|
||||||
@ -779,6 +791,7 @@ export default {
|
|||||||
|
|
||||||
&__opbar {
|
&__opbar {
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
display: flex;
|
display: flex;
|
||||||
li {
|
li {
|
||||||
@ -1,3 +1,4 @@
|
|||||||
import Notice from "./notice";
|
import Notice from "./notice";
|
||||||
|
import Chat from "./chat";
|
||||||
|
|
||||||
export default { Notice };
|
export default { Notice, Chat };
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div class="avatar" @tap="toUserDetail(item)">
|
<div class="avatar" @tap="toUserDetail(item)">
|
||||||
<el-image :src="item.avatarUrl"></el-image>
|
<img :src="item.avatarUrl" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="det">
|
<div class="det">
|
||||||
@ -185,11 +185,13 @@ export default {
|
|||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
|
|
||||||
.el-image {
|
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
import { BaseService, Service, Permission } from "cl-admin";
|
import { BaseService, Service, Permission } from "cl-admin";
|
||||||
|
|
||||||
@Service("app/im/message")
|
@Service({
|
||||||
|
namespace: "im/message",
|
||||||
|
mock: true
|
||||||
|
})
|
||||||
class ImMessage extends BaseService {
|
class ImMessage extends BaseService {
|
||||||
@Permission("read")
|
@Permission("read")
|
||||||
read(data) {
|
read(data) {
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
import { BaseService, Service, Permission } from "cl-admin";
|
import { BaseService, Service, Permission } from "cl-admin";
|
||||||
|
|
||||||
@Service("app/im/session")
|
@Service({
|
||||||
|
namespace: "im/session",
|
||||||
|
mock: true
|
||||||
|
})
|
||||||
class ImSession extends BaseService {
|
class ImSession extends BaseService {
|
||||||
@Permission("unreadCount")
|
@Permission("unreadCount")
|
||||||
unreadCount() {
|
unreadCount() {
|
||||||
|
|||||||
@ -9,6 +9,9 @@ import router from "@/router";
|
|||||||
// 缓存
|
// 缓存
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
|
|
||||||
|
// mock
|
||||||
|
import "@/mock";
|
||||||
|
|
||||||
// 阻止显示生产模式的消息
|
// 阻止显示生产模式的消息
|
||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
|
|
||||||
|
|||||||
75
src/mock/chat.js
Normal file
75
src/mock/chat.js
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import Mock from "mockjs";
|
||||||
|
|
||||||
|
Mock.mock("/im/session/page", "post", options => {
|
||||||
|
const { keyWord = "" } = JSON.parse(options.body);
|
||||||
|
|
||||||
|
const data = Mock.mock({
|
||||||
|
"list|20": [
|
||||||
|
{
|
||||||
|
id: "@id",
|
||||||
|
nickname: "@name",
|
||||||
|
createTime: "@datetime(yy-MM-dd HH:mm:ss)",
|
||||||
|
text: "@cparagraph(5)",
|
||||||
|
content() {
|
||||||
|
return JSON.stringify({ text: this.text });
|
||||||
|
},
|
||||||
|
"contentType|0-3": 0,
|
||||||
|
"serviceUnreadCount|0-10": 0,
|
||||||
|
headimgurl() {
|
||||||
|
return Mock.Random.image(
|
||||||
|
"40x40",
|
||||||
|
Mock.Random.color(),
|
||||||
|
"#FFF",
|
||||||
|
"png",
|
||||||
|
this.nickname[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 1000,
|
||||||
|
data: {
|
||||||
|
list: data.list.filter(e => e.nickname.includes(keyWord)),
|
||||||
|
pagination: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
Mock.mock("/im/session/unreadCount", "get", options => {
|
||||||
|
const data = Mock.mock({
|
||||||
|
"count|1-50": 1
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 1000,
|
||||||
|
data: data.count
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
Mock.mock("/im/message/page", "post", options => {
|
||||||
|
const data = Mock.mock({
|
||||||
|
"list|20": [
|
||||||
|
{
|
||||||
|
id: "@id",
|
||||||
|
nickname: "@name",
|
||||||
|
createTime: "@datetime",
|
||||||
|
text: "@cparagraph(1, 4)",
|
||||||
|
content() {
|
||||||
|
return JSON.stringify({ text: this.text });
|
||||||
|
},
|
||||||
|
contentType: 0,
|
||||||
|
"type|0-1": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 1000,
|
||||||
|
data: {
|
||||||
|
list: data.list,
|
||||||
|
pagination: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
1
src/mock/index.js
Normal file
1
src/mock/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
import "./chat";
|
||||||
Loading…
x
Reference in New Issue
Block a user