Эх сурвалжийг харах

更新 聊天模块,添加响应式处理

icssoa 4 жил өмнө
parent
commit
f032afbb3c

+ 4 - 4
package.json

@@ -1,6 +1,6 @@
 {
 	"name": "cool-admin-vue",
-	"version": "3.1.0",
+	"version": "3.1.1",
 	"scripts": {
 		"serve": "vue-cli-service serve",
 		"build": "vue-cli-service build",
@@ -10,8 +10,8 @@
 	},
 	"dependencies": {
 		"axios": "^0.21.1",
-		"cl-admin": "^1.4.0",
-		"cl-admin-crud": "^1.6.2",
+		"cl-admin": "^1.5.0",
+		"cl-admin-crud": "^1.6.4",
 		"cl-admin-theme": "^0.0.4",
 		"clipboard": "^2.0.7",
 		"codemirror": "^5.59.4",
@@ -24,7 +24,7 @@
 		"nprogress": "^0.2.0",
 		"qs": "^6.9.1",
 		"quill": "^1.3.7",
-		"socket.io-client": "^3.1.2",
+		"socket.io-client": "2.3.1",
 		"store": "^2.0.12",
 		"uuid": "^8.3.2",
 		"vue": "^2.6.11",

+ 1 - 0
src/assets/css/index.scss

@@ -1,6 +1,7 @@
 * {
 	padding: 0;
 	margin: 0;
+	outline: none;
 	font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
 		"微软雅黑", Arial, sans-serif;
 }

+ 8 - 0
src/cool/index.js

@@ -3,7 +3,9 @@ import Theme from "cl-admin-theme";
 
 export default {
 	modules: [
+		// 基础模块
 		"base",
+		// 文件上传
 		{
 			name: "upload",
 			options: {
@@ -25,11 +27,17 @@ export default {
 				}
 			}
 		},
+		// 客服聊天
 		"chat",
+		// 任务管理
 		"task",
+		// 复制指令
 		"copy",
+		// 省市区选择
 		"distpicker",
+		// 示例页
 		"demo",
+		// 主题切换
 		{
 			name: "theme",
 			value: Theme

+ 1 - 7
src/cool/modules/base/common/index.js

@@ -41,17 +41,11 @@ export const resize = () => {
 			}
 		});
 	}
+
 	store.commit("SET_BROWSER");
 };
 
 window.onload = () => {
-	const observer = new MutationObserver(resize);
-
-	observer.observe(document.getElementById("app"), {
-		childList: true,
-		subtree: true
-	});
-
 	window.addEventListener("resize", resize);
 	resize();
 };

+ 9 - 5
src/cool/modules/base/components/dept/tree.vue

@@ -10,7 +10,7 @@
 					</el-tooltip>
 				</li>
 
-				<li v-if="drag && isPc">
+				<li v-if="drag && !browser.isMini">
 					<el-tooltip content="拖动排序">
 						<i class="el-icon-s-operation" @click="isDrag = true"></i>
 					</el-tooltip>
@@ -46,7 +46,7 @@
 						}}</span>
 						<span
 							class="cl-dept-tree__node-icon"
-							v-if="!isPc"
+							v-if="browser.isMini"
 							@click="openCM($event, data, node)"
 						>
 							<i class="el-icon-more"></i>
@@ -59,8 +59,9 @@
 </template>
 
 <script>
-import { deepTree, isArray, revDeepTree, isPc } from "cl-admin/utils";
+import { deepTree, isArray, revDeepTree } from "cl-admin/utils";
 import { ContextMenu, Form } from "cl-admin-crud";
+import { mapGetters } from "vuex";
 
 export default {
 	name: "cl-dept-tree",
@@ -80,11 +81,14 @@ export default {
 		return {
 			list: [],
 			loading: false,
-			isDrag: false,
-			isPc: isPc()
+			isDrag: false
 		};
 	},
 
+	computed: {
+		...mapGetters(["browser"])
+	},
+
 	created() {
 		this.refresh();
 	},

+ 1 - 1
src/cool/modules/base/components/menu/slider/index.js

@@ -81,7 +81,7 @@ export default {
 						default-active={this.$route.path}
 						background-color="transparent"
 						collapse-transition={false}
-						collapse={this.browser.isMobile ? false : this.menuCollapse}
+						collapse={this.browser.isMini ? false : this.menuCollapse}
 						on-select={this.toView}>
 						{el}
 					</el-menu>

+ 1 - 3
src/cool/modules/base/store/app.js

@@ -7,9 +7,7 @@ export default {
 		info: {
 			...app
 		},
-		browser: {
-			isMobile: false
-		},
+		browser: {},
 		collapse: false
 	},
 	getters: {

+ 70 - 93
src/cool/modules/base/views/menu.vue

@@ -1,83 +1,74 @@
 <template>
-	<div>
-		<cl-crud ref="crud" @load="onLoad" :on-refresh="onRefresh">
-			<el-row type="flex">
-				<cl-refresh-btn />
-				<cl-add-btn />
-			</el-row>
+	<cl-crud ref="crud" @load="onLoad" :on-refresh="onRefresh">
+		<el-row type="flex">
+			<cl-refresh-btn />
+			<cl-add-btn />
+		</el-row>
 
-			<el-row>
-				<cl-table ref="table" v-bind="table" @row-click="onRowClick">
-					<!-- 名称 -->
-					<template #column-name="{ scope }">
-						<span>{{ scope.row.name }}</span>
-						<el-tag
-							size="mini"
-							effect="dark"
-							type="danger"
-							v-if="!scope.row.isShow"
-							style="margin-left: 10px"
-							>隐藏</el-tag
-						>
-					</template>
+		<el-row>
+			<cl-table ref="table" v-bind="table" @row-click="onRowClick">
+				<!-- 名称 -->
+				<template #column-name="{ scope }">
+					<span>{{ scope.row.name }}</span>
+					<el-tag
+						size="mini"
+						effect="dark"
+						type="danger"
+						v-if="!scope.row.isShow"
+						style="margin-left: 10px"
+						>隐藏</el-tag
+					>
+				</template>
 
-					<!-- 图标 -->
-					<template #column-icon="{ scope }">
-						<icon-svg
-							:name="scope.row.icon"
-							size="16px"
-							style="margin-top: 5px"
-						></icon-svg>
-					</template>
+				<!-- 图标 -->
+				<template #column-icon="{ scope }">
+					<icon-svg :name="scope.row.icon" size="16px" style="margin-top: 5px"></icon-svg>
+				</template>
 
-					<!-- 权限 -->
-					<template #column-perms="{ scope }">
-						<el-tag
-							v-for="(item, index) in scope.row.permList"
-							:key="index"
-							size="mini"
-							effect="dark"
-							style="margin: 2px; letter-spacing: 0.5px"
-							>{{ item }}</el-tag
-						>
-					</template>
+				<!-- 权限 -->
+				<template #column-perms="{ scope }">
+					<el-tag
+						v-for="(item, index) in scope.row.permList"
+						:key="index"
+						size="mini"
+						effect="dark"
+						style="margin: 2px; letter-spacing: 0.5px"
+						>{{ item }}</el-tag
+					>
+				</template>
 
-					<!-- 路由 -->
-					<template #column-router="{ scope }">
-						<el-link
-							type="primary"
-							:href="scope.row.router"
-							v-if="scope.row.type == 1"
-							>{{ scope.row.router }}</el-link
-						>
-						<span v-else>{{ scope.row.router }}</span>
-					</template>
+				<!-- 路由 -->
+				<template #column-router="{ scope }">
+					<el-link type="primary" :href="scope.row.router" v-if="scope.row.type == 1">{{
+						scope.row.router
+					}}</el-link>
+					<span v-else>{{ scope.row.router }}</span>
+				</template>
 
-					<!-- 路由缓存 -->
-					<template #column-keepAlive="{ scope }">
-						<template v-if="scope.row.type == 1">
-							<i class="el-icon-check" v-if="scope.row.keepAlive"></i>
-							<i class="el-icon-close" v-else></i>
-						</template>
+				<!-- 路由缓存 -->
+				<template #column-keepAlive="{ scope }">
+					<template v-if="scope.row.type == 1">
+						<i class="el-icon-check" v-if="scope.row.keepAlive"></i>
+						<i class="el-icon-close" v-else></i>
 					</template>
+				</template>
 
-					<!-- 行新增 -->
-					<template #slot-add="{ scope }">
-						<el-button
-							type="text"
-							size="mini"
-							@click="upsertAppend(scope.row)"
-							v-if="scope.row.type != 2"
-							>新增</el-button
-						>
-					</template>
-				</cl-table>
-			</el-row>
+				<!-- 行新增 -->
+				<template #slot-add="{ scope }">
+					<el-button
+						type="text"
+						size="mini"
+						@click="upsertAppend(scope.row)"
+						v-if="scope.row.type != 2"
+						>新增</el-button
+					>
+				</template>
+			</cl-table>
+		</el-row>
 
-			<!-- 编辑 -->
-			<cl-upsert ref="upsert" v-bind="upsert" @open="onUpsertOpen"></cl-upsert>
-		</cl-crud>
-	</div>
+		<!-- 编辑 -->
+		<cl-upsert ref="upsert" v-bind="upsert"></cl-upsert>
+	</cl-crud>
 </template>
 
 <script>
@@ -255,7 +246,7 @@ export default {
 						prop: "router",
 						label: "节点路由",
 						span: 24,
-						hidden: true,
+						hidden: ({ scope }) => scope.type != 1,
 						component: {
 							name: "el-input",
 							attrs: {
@@ -268,6 +259,7 @@ export default {
 						value: true,
 						label: "路由缓存",
 						span: 24,
+						hidden: ({ scope }) => scope.type != 1,
 						component: {
 							name: "el-radio-group",
 							options: [
@@ -287,7 +279,7 @@ export default {
 						label: "是否显示",
 						span: 24,
 						value: true,
-						hidden: false,
+						hidden: ({ scope }) => scope.type == 2,
 						flex: false,
 						component: {
 							name: "el-switch"
@@ -297,7 +289,7 @@ export default {
 						prop: "viewPath",
 						label: "文件路径",
 						span: 24,
-						hidden: true,
+						hidden: ({ scope }) => scope.type != 1,
 						component: {
 							name: "cl-menu-file"
 						}
@@ -306,6 +298,7 @@ export default {
 						prop: "icon",
 						label: "节点图标",
 						span: 24,
+						hidden: ({ scope }) => scope.type == 2,
 						component: {
 							name: "cl-menu-icons"
 						}
@@ -329,7 +322,7 @@ export default {
 						prop: "perms",
 						label: "权限",
 						span: 24,
-						hidden: true,
+						hidden: ({ scope }) => scope.type != 2,
 						component: {
 							name: "cl-menu-perms"
 						}
@@ -341,14 +334,12 @@ export default {
 
 	methods: {
 		onLoad({ ctx, app }) {
-			ctx.service(this.$service.system.menu)
-				.set("dict", { api: { page: "list" } })
-				.done();
+			ctx.service(this.$service.system.menu).done();
 
 			app.refresh();
 		},
 
-		onRefresh(params, { render }) {
+		onRefresh(_, { render }) {
 			this.$service.system.menu.list().then(list => {
 				list.map(e => {
 					e.permList = e.perms ? e.perms.split(",") : [];
@@ -364,10 +355,6 @@ export default {
 			}
 		},
 
-		onUpsertOpen(isEdit, data) {
-			this.changeType(data ? data.type : 0);
-		},
-
 		upsertAppend({ type, id }) {
 			this.$refs["crud"].rowAppend({
 				parentId: id,
@@ -375,16 +362,6 @@ export default {
 			});
 		},
 
-		changeType(index) {
-			const { toggleItem } = this.$refs["upsert"];
-			toggleItem("router", index == 1);
-			toggleItem("viewPath", index == 1);
-			toggleItem("keepAlive", index == 1);
-			toggleItem("icon", index != 2);
-			toggleItem("perms", index == 2);
-			toggleItem("isShow", index != 2);
-		},
-
 		setPermission({ id }) {
 			this.$refs["crud"].rowAppend({
 				parentId: id,

+ 18 - 5
src/cool/modules/base/views/user.vue

@@ -104,12 +104,11 @@
 </template>
 
 <script>
-import { isPc } from "cl-admin/utils";
-
+import { mapGetters } from "vuex";
 export default {
 	data() {
 		return {
-			isExpand: isPc(),
+			isExpand: true,
 			selects: {
 				dept: {},
 				ids: []
@@ -377,6 +376,19 @@ export default {
 		};
 	},
 
+	computed: {
+		...mapGetters(["browser"])
+	},
+
+	watch: {
+		"browser.isMini": {
+			immediate: true,
+			handler(val) {
+				this.isExpand = !val;
+			}
+		}
+	},
+
 	methods: {
 		refresh(params) {
 			this.$refs["crud"].refresh(params);
@@ -406,7 +418,7 @@ export default {
 			this.$refs["upsert"].toggleItem("tips", !isEdit);
 		},
 
-		onUpsertSubmit(isEdit, data, { next }) {
+		onUpsertSubmit(_, data, { next }) {
 			let departmentId = data.departmentId;
 
 			if (!departmentId) {
@@ -435,7 +447,8 @@ export default {
 				departmentIds: ids
 			});
 
-			if (!isPc()) {
+			// 收起
+			if (this.browser.isMini) {
 				this.isExpand = false;
 			}
 		},

+ 31 - 33
src/cool/modules/chat/components/chat.vue

@@ -6,18 +6,33 @@
 			:title="title"
 			:height="height"
 			:width="width"
-			:props="conf"
+			:props="{
+				modal: true,
+				customClass: 'cl-chat__dialog',
+				'append-to-body': true,
+				'close-on-click-modal': false
+			}"
+			:controls="['slot-session', 'cl-flex1', 'fullscreen', 'close']"
 		>
 			<div class="cl-chat">
-				<!-- 会话区域 -->
 				<chat-session />
 
-				<!-- 会话详情 -->
 				<div class="cl-chat__detail" v-if="session">
 					<chat-message />
 					<chat-input />
 				</div>
 			</div>
+
+			<template #slot-session>
+				<button v-if="session">
+					<i
+						class="el-icon-notebook-2"
+						v-if="sessionVisible"
+						@click="CLOSE_SESSION()"
+					></i>
+					<i class="el-icon-arrow-left" v-else @click="OPEN_SESSION()"></i>
+				</button>
+			</template>
 		</cl-dialog>
 
 		<!-- MP3 -->
@@ -29,18 +44,14 @@
 
 <script>
 import dayjs from "dayjs";
-import { mapGetters } from "vuex";
-import { parseContent } from "../utils";
-
+import { mapGetters, mapMutations } from "vuex";
 import io from "socket.io-client";
 import { socketUrl } from "@/config/env";
-
 import Session from "./session";
 import Message from "./message";
 import Input from "./input";
 import eventBus from "../utils/event-bus";
-
-// 消息模式
+import { parseContent } from "../utils";
 
 export default {
 	name: "cl-chat",
@@ -65,24 +76,18 @@ export default {
 	data() {
 		return {
 			visible: false,
-			socket: null,
-			conf: {
-				modal: true,
-				customClass: "cl-chat__dialog",
-				"append-to-body": true,
-				"close-on-click-modal": false
-			}
+			socket: null
 		};
 	},
 
 	provide() {
 		return {
-			socket: this.socket
+			chat: this
 		};
 	},
 
 	computed: {
-		...mapGetters(["token", "session", "sessionList"]),
+		...mapGetters(["token", "session", "sessionList", "sessionVisible"]),
 
 		title() {
 			return this.session ? `与 ${this.session.nickname} 聊天中` : "聊天对话框";
@@ -90,7 +95,7 @@ export default {
 	},
 
 	created() {
-		// this.socket = io(`${socketUrl}?isAdmin=true&token=${this.token}`);
+		// this.socket = io(`${socketUrl}/?isAdmin=true&token=${token}`);
 		// this.socket.on("connect", () => {
 		// 	console.log("socket connect");
 		// });
@@ -112,6 +117,8 @@ export default {
 	},
 
 	methods: {
+		...mapMutations(["OPEN_SESSION", "CLOSE_SESSION", "UPDATE_SESSION"]),
+
 		open() {
 			this.visible = true;
 		},
@@ -136,7 +143,7 @@ export default {
 
 				if (same) {
 					// 更新消息
-					this.$store.commit("UPDATE_SESSION", {
+					this.UPDATE_SESSION({
 						contentType,
 						content
 					});
@@ -148,10 +155,10 @@ export default {
 						type: 1
 					});
 
-					// 读消息
+					// 读消息
 					this.$service.im.message.read({
 						ids: [msgId],
-						session: this.session.current.id
+						session: this.session.id
 					});
 				}
 
@@ -217,32 +224,23 @@ export default {
 
 <style lang="scss">
 .cl-chat__dialog {
-	margin-bottom: 0 !important;
-	min-width: 1000px;
-
 	.el-dialog__body {
 		padding: 0;
 	}
-
-	&.is-fullscreen {
-		.cl-dialog__container {
-			height: calc(100vh - 46px) !important;
-		}
-	}
 }
 
 .cl-chat {
 	display: flex;
 	height: 100%;
 	background-color: #f7f7f7;
+	padding: 5px;
+	box-sizing: border-box;
 
 	&__detail {
 		display: flex;
 		flex-direction: column;
 		flex: 1;
 		height: 100%;
-		padding: 5px;
-		box-sizing: border-box;
 	}
 }
 </style>

+ 58 - 29
src/cool/modules/chat/components/emoji.vue

@@ -1,15 +1,32 @@
 <template>
-	<div class="chat-emoji">
-		<div class="scroller">
-			<div class="block" v-for="(item, index) in list" :key="index" @click="select(item)">
-				<img :src="item" />
+	<el-popover
+		v-model="visible"
+		placement="top"
+		:width="popoverWidth"
+		trigger="click"
+		popper-class="popover-emoji"
+	>
+		<div class="tool-emoji">
+			<div class="tool-emoji__scroller scroller1">
+				<div
+					class="tool-emoji__item"
+					v-for="(item, index) in list"
+					:key="index"
+					@click="select(item)"
+				>
+					<img :src="item" />
+				</div>
 			</div>
 		</div>
-	</div>
+
+		<img slot="reference" src="../static/images/emoji.png" alt="" />
+	</el-popover>
 </template>
 
 <script>
-let emoji = {
+import { mapGetters } from "vuex";
+// 表情列表
+const emoji = {
 	url: "https://cool-comm.oss-cn-shenzhen.aliyuncs.com/show/imgs/chat/",
 	list: [
 		"angry-face.png",
@@ -103,54 +120,66 @@ let emoji = {
 	]
 };
 
-emoji.list = emoji.list.map(e => emoji.url + e);
-
 export default {
 	data() {
 		return {
-			list: emoji.list
+			visible: false,
+			list: emoji.list.map(e => emoji.url + e)
 		};
 	},
 
-	methods: {
-		close() {},
+	computed: {
+		...mapGetters(["browser"]),
 
+		popoverWidth() {
+			return (this.browser.width > 500 ? 500 : this.browser.width) - 24;
+		}
+	},
+
+	methods: {
 		select(e) {
 			this.$emit("select", e);
+			this.visible = false;
 		}
 	}
 };
 </script>
 
+<style lang="scss">
+.popover-emoji {
+	padding: 5px;
+}
+</style>
+
 <style lang="scss" scoped>
-.chat-emoji {
+.tool-emoji {
 	height: 250px;
 	box-sizing: border-box;
 
-	.scroller {
+	&__scroller {
 		display: flex;
 		flex-wrap: wrap;
 		height: 100%;
 		overflow: auto;
+	}
 
-		.block {
-			display: flex;
-			justify-content: center;
-			align-items: center;
-			height: 50px;
-			width: 50px;
-			cursor: pointer;
+	&__item {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		height: 50px;
+		width: 50px;
+		cursor: pointer;
 
-			&:hover,
-			&:active {
-				background-color: #f7f7f7;
-			}
+		&:hover,
+		&:active {
+			background-color: #f7f7f7;
+		}
 
-			img {
-				display: inline-block;
-				height: 25px;
-				width: 25px;
-			}
+		img {
+			display: inline-block;
+			height: 25px;
+			width: 25px;
 		}
 	}
 }

+ 9 - 22
src/cool/modules/chat/components/input.vue

@@ -5,15 +5,7 @@
 			<ul>
 				<!-- 表情 -->
 				<li>
-					<el-popover
-						v-model="emoji.visible"
-						placement="top-start"
-						width="470"
-						trigger="click"
-					>
-						<emoji @select="onEmojiSelect" />
-						<img slot="reference" src="../static/images/emoji.png" alt="" />
-					</el-popover>
+					<emoji @select="onEmojiSelect" />
 				</li>
 				<!-- 图片上传 -->
 				<li hidden>
@@ -50,6 +42,7 @@
 				v-model="value"
 				placeholder="请描述您想咨询的问题"
 				type="textarea"
+				resize="none"
 				:rows="5"
 				@keyup.enter.native="onTextSend"
 			></el-input>
@@ -71,7 +64,7 @@ export default {
 		Emoji
 	},
 
-	inject: ["socket"],
+	inject: ["chat"],
 
 	data() {
 		return {
@@ -193,22 +186,15 @@ export default {
 			const { id, userId } = this.session;
 
 			// 更新消息
-			// this.updateSession({
-			// 	contentType,
-			// 	content
-			// });
+			this.$store.commit("UPDATE_SESSION", data);
 
-			if (this.socket) {
-				this.socket.emit(`user@${userId}`, {
+			if (this.chat.socket) {
+				this.chat.socket.emit(`user@${userId}`, {
 					contentType: data.contentType,
 					type: 0,
 					content: JSON.stringify(data.content),
 					sessionId: id
 				});
-
-				if (isAppend) {
-					this.append(data);
-				}
 			}
 
 			if (isAppend) {
@@ -235,6 +221,7 @@ export default {
 
 		ul {
 			display: flex;
+
 			li {
 				list-style: none;
 				margin-right: 10px;
@@ -244,7 +231,7 @@ export default {
 					opacity: 0.7;
 				}
 
-				img {
+				/deep/ img {
 					height: 26px;
 					width: 26px;
 				}
@@ -257,7 +244,7 @@ export default {
 
 		.el-button {
 			position: absolute;
-			right: 10px;
+			right: 15px;
 			bottom: 10px;
 		}
 	}

+ 2 - 0
src/cool/modules/chat/components/message.vue

@@ -27,11 +27,13 @@
 					</div>
 
 					<div class="main">
+						<!-- 头像 -->
 						<div class="avatar" @tap="toUserDetail(item)">
 							<img :src="item.avatarUrl" />
 						</div>
 
 						<div class="det">
+							<!-- 昵称 -->
 							<span class="name">{{ item.nickName }}</span>
 
 							<div

+ 74 - 28
src/cool/modules/chat/components/session.vue

@@ -1,5 +1,12 @@
 <template>
-	<div class="cl-chat-session">
+	<div
+		class="cl-chat-session"
+		:class="{
+			'is-position': browser.isMini,
+			'is-show': sessionVisible
+		}"
+	>
+		<!-- 关键字搜索 -->
 		<div class="cl-chat-session__search">
 			<el-input
 				v-model="keyWord"
@@ -46,10 +53,11 @@
 </template>
 
 <script>
-import { mapGetters } from "vuex";
+import { mapGetters, mapMutations } from "vuex";
+import { isEmpty } from "cl-admin/utils";
+import { ContextMenu } from "cl-admin-crud";
 import { parseContent } from "../utils";
 import eventBus from "../utils/event-bus";
-import { ContextMenu } from "cl-admin-crud";
 
 export default {
 	data() {
@@ -65,8 +73,9 @@ export default {
 	},
 
 	computed: {
-		...mapGetters(["sessionList", "session"]),
+		...mapGetters(["sessionList", "session", "browser", "sessionVisible"]),
 
+		// 列表数据
 		list() {
 			return this.sessionList
 				.map(e => {
@@ -81,11 +90,20 @@ export default {
 	},
 
 	created() {
+		// 监听列表刷新
 		eventBus.$on("session-refresh", this.refresh);
-		this.refresh();
+
+		// PC 端下首次请求读取第一个消息
+		this.refresh().then(res => {
+			if (!isEmpty(res.list) && !this.browser.isMini) {
+				this.SET_SESSION(res.list[0]);
+			}
+		});
 	},
 
 	methods: {
+		...mapMutations(["SET_SESSION_LIST", "SET_SESSION", "CLEAR_SESSION", "CLOSE_SESSION"]),
+
 		// 右键菜单
 		openCM(e, id, index) {
 			ContextMenu.open(e, {
@@ -115,24 +133,29 @@ export default {
 		refresh(params) {
 			this.loading = true;
 
-			this.$service.im.session
-				.page({
-					...this.pagination,
-					keyWord: this.keyWord,
-					params,
-					order: "updateTime",
-					sort: "desc"
-				})
-				.then(res => {
-					this.$store.commit("SET_SESSION_LIST", res.list);
-					this.pagination = res.pagination;
-				})
-				.catch(err => {
-					this.$message.error(err);
-				})
-				.done(() => {
-					this.loading = false;
-				});
+			return new Promise((resolve, reject) => {
+				this.$service.im.session
+					.page({
+						...this.pagination,
+						keyWord: this.keyWord,
+						params,
+						order: "updateTime",
+						sort: "desc"
+					})
+					.then(res => {
+						this.SET_SESSION_LIST(res.list);
+						this.pagination = res.pagination;
+
+						resolve(res);
+					})
+					.catch(err => {
+						this.$message.error(err);
+						reject(err);
+					})
+					.done(() => {
+						this.loading = false;
+					});
+			});
 		},
 
 		// 搜索关键字
@@ -143,11 +166,15 @@ export default {
 		// 会话详情
 		toDetail(item) {
 			if (item) {
+				// 点击关闭弹窗
+				if (this.browser.isMini) this.CLOSE_SESSION();
+
+				// 设置为当前会话
 				if (!this.session || this.session.id != item.id) {
-					this.$store.commit("SET_SESSION", item);
+					this.SET_SESSION(item);
 				}
 			} else {
-				this.$store.commit("CLEAR_SESSION");
+				this.CLEAR_SESSION();
 			}
 		}
 	}
@@ -156,11 +183,30 @@ export default {
 
 <style lang="scss" scoped>
 .cl-chat-session {
-	height: calc(100% - 10px);
-	width: 250px;
-	margin: 5px 0 5px 5px;
+	height: 100%;
+	width: 0;
+	transition: width 0.2s ease-in-out;
 	border-radius: 5px;
 	background-color: #fff;
+	overflow: hidden;
+
+	&.is-show {
+		width: 250px;
+		max-width: 100%;
+		margin-right: 5px;
+	}
+
+	&.is-position {
+		position: absolute;
+		left: 5px;
+		top: 51px;
+		height: calc(100% - 56px);
+		z-index: 3000;
+
+		&.is-show {
+			width: calc(100% - 10px);
+		}
+	}
 
 	&__search {
 		padding: 10px;

+ 16 - 2
src/cool/modules/chat/store/session.js

@@ -1,16 +1,20 @@
 import eventBus from "../utils/event-bus";
+import { isBoolean } from "cl-admin/utils";
 
 export default {
 	state: {
 		list: [],
-		current: null
+		current: null,
+		visible: true
 	},
 
 	getters: {
 		// 当前会话
 		session: state => state.current,
 		// 会话列表
-		sessionList: state => state.list
+		sessionList: state => state.list,
+		// 是否显示会话列表
+		sessionVisible: state => state.visible
 	},
 
 	mutations: {
@@ -39,6 +43,16 @@ export default {
 		// 清空会话列表
 		CLEAR_SESSION_LIST(state) {
 			state.list = [];
+		},
+
+		// 打开会话列表
+		OPEN_SESSION(state, val) {
+			state.visible = isBoolean(val) ? val : !state.visible;
+		},
+
+		// 关闭会话列表
+		CLOSE_SESSION(state) {
+			state.visible = false;
 		}
 	}
 };

+ 0 - 9
src/cool/modules/upload/package.json

@@ -1,9 +0,0 @@
-{
-  "name": "upload",
-  "version": "1.0.0",
-  "main": "index.js",
-  "license": "MIT",
-  "dependencies": {
-    "uuid": "^8.3.2"
-  }
-}

+ 0 - 1
src/icons/svg/perf-cache.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1614441306173" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8757" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M739.50933333 332.1632v-105.92746667L512 102.4 284.49066667 226.23573333l-1.5712 105.92746667 229.1488 106.1088 227.44213333-105.92746667v106.10986667L512 544.08533333l-0.52266667 0.18133334-226.98666666-105.83466667v-106.10986667L56.88746667 438.272v269.0848L285.01333333 813.19253333 512 925.4688v-0.34133333l227.41866667-111.84426667 227.6928-105.9264V438.272z" p-id="8758"></path></svg>

+ 0 - 1
src/icons/svg/perf-connect.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1614441295630" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7916" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M336.11889778 554.09208889h348.41941333v-87.09233778H336.11889778v87.09233778zM157.53671111 510.51178667c0-100.16768 78.34851555-178.57763555 178.58104889-178.57763556h130.66467555v-82.75057778H336.11889778c-143.74456889 0-261.32707555 117.58478222-261.32707556 261.32821334 0 143.74229333 117.58250667 261.32821333 261.32707556 261.32821333h130.66467555v-82.74830222H336.11889778c-100.23253333 0-178.58104889-78.47139555-178.58104889-178.57991111M684.53831111 249.18471111H553.87363555v82.75057778h130.66467556c100.16312889 0 178.51619555 78.40995555 178.51619556 178.57763556 0 100.10737778-78.35192889 178.57991111-178.51619556 178.5799111H553.87363555v82.74830223h130.66467556c143.74343111 0 261.32821333-117.58592 261.32821334-261.32821333 0-143.74343111-117.58478222-261.32821333-261.32821334-261.32821334" p-id="7917"></path></svg>

+ 0 - 1
src/icons/svg/perf-cpu.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1614441291674" class="icon" viewBox="0 0 1099 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7636" xmlns:xlink="http://www.w3.org/1999/xlink" width="137.375" height="128"><defs><style type="text/css"></style></defs><path d="M1011.81895111 373.64622222v-73.78868147l-87.5026963 0.24272592v-114.44527408c0-29.00574815-14.92764445-45.26838518-43.93339259-45.26838518h-105.46441481V50.82074075h-74.63822223v89.56586666h-112.13937777V50.82074075h-74.63822223l-0.12136296 89.56586666h-112.13937778l0.24272592-89.56586666h-75.00231111l0.12136297 89.56586666h-98.18263704c-36.0448 0-50.85108148 16.26263703-50.60835555 53.88515556l-0.72817778 105.8285037h-89.08041482V373.64622222h89.08041482v103.03715556l-89.08041482-0.12136296v74.63822221l89.08041482 0.24272594v104.61487406h-89.08041482v73.30322964h89.08041482v100.00308148c0 41.26340741 16.62672592 58.37558518 58.0114963 58.37558518h91.50767407l-0.12136297 85.92497778h74.51685926l0.3640889-85.92497778h112.13937777v85.92497778h74.88094815l-0.12136297-85.92497778h112.13937779l-0.24272593 85.92497778h74.88094814l0.12136297-85.92497778h99.88171852c33.49617778 0 49.51608889-29.4912 49.51608889-58.37558518v-100.00308148h87.50269629v-73.30322964h-87.74542222v-104.61487406h87.5026963v-74.51685927l-87.5026963-0.24272592V373.64622222h87.5026963z m-162.26228148 439.33392593h-597.7125926V215.14619259h597.83395555V812.98014815z m-472.83010371-94.29902223h358.99164444c14.32082963 0 19.53943703-9.8304 19.53943705-22.81623703V336.0237037c0-15.29173333-10.43721482-23.78714075-22.81623705-23.78714073h-359.47709628c-18.6898963 0-24.15122963 6.91768889-24.15122964 25.72894814v352.68077037c0 18.6898963 9.22358518 28.03484445 27.91348148 28.03484444z" p-id="7637"></path></svg>

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
src/icons/svg/perf-db.svg


+ 0 - 1
src/icons/svg/perf-disk.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1614441319409" class="icon" viewBox="0 0 1099 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9737" xmlns:xlink="http://www.w3.org/1999/xlink" width="137.375" height="128"><defs><style type="text/css"></style></defs><path d="M427.85156025 795.07105396h113.36703157c13.53224006 0 23.33620992-7.87079269 23.3362099-21.1268646v-50.40069005c0-12.15139925-8.69929718-19.05560336-24.30279849-19.05560335h-113.22894749c-14.7749968 0-22.23153725 10.49439025-22.23153724 21.81728501v46.67241982c-0.13808409 10.63247434 11.46097883 22.09345317 23.06004175 22.09345317z m222.72962475 0h161.00603997c14.49882864 0 23.88854624-8.00887677 23.88854623-19.60793969v-50.40069004c0-12.01331517-8.28504494-20.57452827-24.30279849-20.57452827h-161.42029221c-14.36074457 0-23.47429398 8.28504494-23.47429398 20.43644418v44.32499042c0 14.08457639 8.42312903 25.8217234 24.30279848 25.8217234z m-342.17235594-746.20638078l-255.04130003 469.07162758v393.53963458c0 37.97312263 22.64578949 58.40956682 62.96634153 58.40956681h864.82060749c35.07335691 0 56.33830558-21.26494868 56.33830557-55.92405334V512.9652738l-255.86980452-464.10060062h-473.21415004z m424.05621675 77.18900201l214.72074799 384.14991696h-796.88323898l210.99247775-384.14991696h371.17001324z m222.17728843 765.95240454h-820.63370114V596.78231176h820.63370114v295.22376797z" p-id="9738"></path></svg>

+ 0 - 1
src/icons/svg/perf-lb.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1614441299581" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8196" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M316.2048 750.35093333h398.3808v74.66666667H316.2048z m286.86506667-441.66933333l208.5632 361.23093333-64.66133334 37.33333334-208.5632-361.232z m-183.13173334 1.72906667l64.66133334 37.33333333-210.06186667 363.8272-64.66133333-37.33333333z" p-id="8197"></path><path d="M512 377.04746667c-79.4016 0-144-64.5984-144-144s64.5984-144 144-144 144 64.5984 144 144-64.5984 144-144 144z m0-213.33333334c-38.2304 0-69.33333333 31.10293333-69.33333333 69.33333334s31.10293333 69.33333333 69.33333333 69.33333333 69.33333333-31.10293333 69.33333333-69.33333333-31.10293333-69.33333333-69.33333333-69.33333334zM211.6832 922.66666667c-79.4016 0-144-64.5984-144-144s64.5984-144 144-144 144 64.5984 144 144-64.5984 144-144 144z m0-213.33333334c-38.2304 0-69.33333333 31.10293333-69.33333333 69.33333334s31.10293333 69.33333333 69.33333333 69.33333333 69.33333333-31.10293333 69.33333333-69.33333333-31.10293333-69.33333333-69.33333333-69.33333334z m604.22293333 213.33333334c-79.4016 0-144-64.5984-144-144s64.5984-144 144-144 144 64.5984 144 144-64.59733333 144-144 144z m0-213.33333334c-38.2304 0-69.33333333 31.10293333-69.33333333 69.33333334s31.10293333 69.33333333 69.33333333 69.33333333 69.33333333-31.10293333 69.33333334-69.33333333-31.10293333-69.33333333-69.33333334-69.33333334z" p-id="8198"></path></svg>

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
src/icons/svg/perf-network.svg


+ 1 - 1
src/pages/layout/slider.vue

@@ -2,7 +2,7 @@
 	<div class="app-slider">
 		<div class="app-slider__logo" @click="toHome">
 			<img src="@/assets/icon/logo/silder-simple.png" />
-			<span v-if="!menuCollapse || browser.isMobile">{{ app.name }}</span>
+			<span v-if="!menuCollapse || browser.isMini">{{ app.name }}</span>
 		</div>
 
 		<div class="app-slider__menu">

+ 20 - 5
src/views/home/components/tab-chart.vue

@@ -17,14 +17,13 @@
 
 <script>
 import VueEcharts from "vue-echarts";
-import { isPc } from "cl-admin/utils";
-
-const barWidth = isPc() ? 25 : 15;
+import { mapGetters } from "vuex";
 
 export default {
 	components: {
 		VueEcharts
 	},
+
 	data() {
 		return {
 			chartOptions: {
@@ -78,7 +77,7 @@ export default {
 				},
 				series: [
 					{
-						barWidth,
+						barWidth: 25,
 						name: "付款笔数",
 						type: "bar",
 						data: [],
@@ -90,7 +89,7 @@ export default {
 					},
 					{
 						type: "bar",
-						barWidth,
+						barWidth: 25,
 						xAxisIndex: 0,
 						barGap: "-100%",
 						data: [],
@@ -105,6 +104,22 @@ export default {
 			}
 		};
 	},
+
+	computed: {
+		...mapGetters(["browser"])
+	},
+
+	watch: {
+		"browser.isMini": {
+			immediate: true,
+			handler(v) {
+				this.chartOptions.series.map(e => {
+					e.barWidth = v ? 15 : 25;
+				});
+			}
+		}
+	},
+
 	created() {
 		this.chartOptions.xAxis.data = new Array(12).fill(1).map((e, i) => i + 1 + "月");
 		this.chartOptions.series[0].data = new Array(12)

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно