2022-12-28 10:08:51 +08:00
|
|
|
|
<template>
|
|
|
|
|
<div class="flex">
|
2022-12-28 18:31:26 +08:00
|
|
|
|
<el-container class="ov-hidden flex-10 full-height ">
|
2022-12-28 10:08:51 +08:00
|
|
|
|
<PanelHeader ref="panelHeader" :data="params" :online="isOnline" :keyboard="inputEvent"
|
|
|
|
|
@event="handleHeaderEvent" />
|
|
|
|
|
<!-- 主体信息 -->
|
|
|
|
|
<el-main class="main-box no-padding">
|
|
|
|
|
<div id="lumenChatPanel" class="talks-container lum-scrollbar" @scroll="talkPanelScroll($event)">
|
|
|
|
|
<!-- 数据加载状态栏 -->
|
|
|
|
|
<div class="loading-toolbar">
|
|
|
|
|
<span v-if="loadRecord.status == 0" class="color-blue">
|
|
|
|
|
<i class="el-icon-loading" /> 正在加载数据中...
|
|
|
|
|
</span>
|
|
|
|
|
<span v-if="loadRecord.status == 1" class="pointer color-blue" @click="loadChatRecords">
|
|
|
|
|
<i class="el-icon-bottom" /> 查看更多消息...
|
|
|
|
|
</span>
|
|
|
|
|
<span v-if="loadRecord.status == 2"> 没有更多消息了... </span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 消息主体 -->
|
|
|
|
|
<div v-for="(item, idx) in records" :key="idx">
|
|
|
|
|
<!-- 群消息 -->
|
|
|
|
|
<div v-if="item.messageType == 9" class="message-box">
|
|
|
|
|
<invite-message @cat="catFriendDetail" :invite="item.invite" />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 撤回消息 -->
|
|
|
|
|
<div v-else-if="item.is_revoke == 1" class="message-box">
|
|
|
|
|
<revoke-message :item="item" />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-else-if="item.messageType == 0" class="message-box">
|
|
|
|
|
<system-text-message :content="item.content" />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 其它对话消息 -->
|
|
|
|
|
<div v-else class="message-box record-box" :class="{
|
2023-01-10 18:44:39 +08:00
|
|
|
|
'direction-rt': item.float == 'right',
|
|
|
|
|
'checkbox-border': multiSelect.isOpen === true,
|
|
|
|
|
}">
|
2022-12-28 10:08:51 +08:00
|
|
|
|
<aside v-show="multiSelect.isOpen" class="checkbox-column">
|
|
|
|
|
<i class="el-icon-success" :class="{ selected: verifyMultiSelect(item.id) }"
|
|
|
|
|
@click="triggerMultiSelect(item.id)" />
|
|
|
|
|
</aside>
|
|
|
|
|
<aside class="avatar-column">
|
|
|
|
|
<div class="avatar-box" v-if="item.float == 'right'">
|
|
|
|
|
<face :text="face" v-if="face"></face>
|
|
|
|
|
<face-null :text="name" v-else></face-null>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="avatar-box" v-if="item.float == 'left'">
|
|
|
|
|
<face :text="toUser.face" v-if="toUser.face"></face>
|
|
|
|
|
<face-null :text="toUser.name" v-else></face-null>
|
|
|
|
|
</div>
|
|
|
|
|
</aside>
|
|
|
|
|
<main class="main-column">
|
|
|
|
|
<div class="talk-content">
|
|
|
|
|
<span class="nickname">
|
|
|
|
|
{{ item.float == "right" ? name : toUser.name }} |
|
|
|
|
|
{{ unixToDate(item.createTime, "MM月dd日 hh:mm") }}
|
|
|
|
|
</span>
|
|
|
|
|
<!-- 文本消息 -->
|
2023-01-10 18:44:39 +08:00
|
|
|
|
<div v-if="item.messageType == 'MESSAGE'" style="background-color: #d0e9ff;color: black;"
|
|
|
|
|
class="text-message" :class="{
|
|
|
|
|
left: item.float == 'left',
|
|
|
|
|
right: item.float == 'right',
|
|
|
|
|
}">
|
2022-12-28 10:08:51 +08:00
|
|
|
|
<div class="arrow"></div>
|
2023-01-13 10:53:39 +08:00
|
|
|
|
<pre v-if="!emojistwo.includes(item.text)" v-html="item.text" />
|
|
|
|
|
<pre v-if="emojistwo.includes(item.text)" v-html="textReplaceEmoji(item.text)" />
|
2022-12-28 10:08:51 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
2023-01-10 18:44:39 +08:00
|
|
|
|
<div v-if="item.messageType == 'GOODS' && item.text != null" class="goodsStyle " :class="{
|
|
|
|
|
left: item.float == 'left',
|
|
|
|
|
right: item.float == 'right',
|
|
|
|
|
}">
|
2022-12-28 18:31:26 +08:00
|
|
|
|
<div class="base" @click="linkToGoods(item.text.goodsId, item.text.id)">
|
|
|
|
|
<div>
|
|
|
|
|
<img :src="item.text.thumbnail" class="image" />
|
|
|
|
|
</div>
|
2023-01-10 18:44:39 +08:00
|
|
|
|
<div>
|
|
|
|
|
<div class="goods_name">
|
|
|
|
|
<el-tooltip class="item" effect="dark" :content="item.text.goodsName" placement="top-start">
|
|
|
|
|
<a> {{ item.text.goodsName }} </a>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="price">
|
|
|
|
|
<span>¥{{ item.text.price }}</span>
|
2022-12-28 10:08:51 +08:00
|
|
|
|
</div>
|
2022-12-28 18:31:26 +08:00
|
|
|
|
</div>
|
2022-12-28 10:08:51 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2023-01-10 18:44:39 +08:00
|
|
|
|
<div v-if="item.messageType == 'ORDER' && item.text != null" class="oderStyle" :class="{
|
|
|
|
|
left: item.float == 'left',
|
|
|
|
|
right: item.float == 'right',
|
|
|
|
|
}">
|
|
|
|
|
<div class="oedersn">
|
|
|
|
|
<el-tooltip class="item" effect="dark" :content="item.text.sn" placement="top-start">
|
|
|
|
|
<a> 订单号:{{ item.text.sn }} </a>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
</div>
|
2022-12-29 18:20:06 +08:00
|
|
|
|
<div class="baseTwo">
|
|
|
|
|
<img :src="item.text.groupImages" style="height: 100px;width: 100px;margin-top: 10px;" />
|
|
|
|
|
<span class="orderGoodsName" @click="linkToOrders(item.text.sn)">{{ item.text.groupName }}</span>
|
|
|
|
|
<span class="orderGoodsTime">{{ item.text.paymentTime }}</span>
|
2023-01-10 18:44:39 +08:00
|
|
|
|
<span class="orderFlowPrice">
|
|
|
|
|
订单金额:¥{{ item.text.flowPrice }}
|
|
|
|
|
</span>
|
|
|
|
|
<span class="order_status"
|
|
|
|
|
:style="{ 'color': item.text.orderStatus == 'CANCELLED' || item.text.orderStatus == 'UNPAID' || item.text.orderStatus == ' TAKE' ? '#5a606b' : '#f23030' }">{{
|
|
|
|
|
item.text.orderStatus == 'CANCELLED' ? '已取消' : item.text.orderStatus == 'UNPAID' ? '未付款' :
|
|
|
|
|
item.text.orderStatus ==
|
|
|
|
|
'PAID' ? '已付款' : item.text.orderStatus == 'UNDELIVERED' ? '待发货' : item.text.orderStatus ==
|
|
|
|
|
'DELIVERED'
|
|
|
|
|
? '已发货' : item.text.orderStatus == ' COMPLETED' ? '已完成' : item.text.orderStatus == ' TAKE' ?
|
|
|
|
|
'待校验' : ''
|
|
|
|
|
}}</span>
|
2022-12-29 18:20:06 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2022-12-28 10:08:51 +08:00
|
|
|
|
</div>
|
|
|
|
|
</main>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 消息时间 -->
|
|
|
|
|
<div v-show="compareTime(idx, item.createTime)" class="datetime no-select"
|
|
|
|
|
v-text="sendTime(unixToDate(item.createTime, 'yyyy-MM-dd hh:mm'))" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 置底按钮 -->
|
|
|
|
|
<transition name="el-fade-in-linear">
|
|
|
|
|
<div v-show="tipsBoard" class="tips-board pointer" @click="talkPanelScrollBottom">
|
|
|
|
|
<!-- <SvgMentionDown class="svg" /> -->
|
|
|
|
|
<span>回到底部</span>
|
|
|
|
|
</div>
|
|
|
|
|
</transition>
|
|
|
|
|
|
|
|
|
|
<!-- 新消息气泡 -->
|
|
|
|
|
<div v-show="tipsBoard && unreadMessage.num" class="talk-bubble pointer no-select"
|
|
|
|
|
@click="talkPanelScrollBottom">
|
|
|
|
|
<i class="el-icon-chat-dot-round" />
|
|
|
|
|
<span>新消息({{ unreadMessage.num }}条)</span>
|
|
|
|
|
<span>
|
|
|
|
|
#{{ unreadMessage.nickname }}#
|
|
|
|
|
{{ unreadMessage.content }}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</el-main>
|
|
|
|
|
|
|
|
|
|
<!-- 页脚信息 -->
|
|
|
|
|
<el-footer class="footer-box" height="180">
|
|
|
|
|
<template v-if="multiSelect.isOpen === false">
|
|
|
|
|
<MeEditor @send="submitSendMessage" @keyboard-event="onKeyboardEvent" />
|
|
|
|
|
</template>
|
|
|
|
|
<template v-else>
|
|
|
|
|
<PanelToolbar v-model="multiSelect.items.length" @event="handleMultiMode" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-footer>
|
|
|
|
|
<el-aside width="200px">
|
2022-12-28 18:31:26 +08:00
|
|
|
|
|
2022-12-28 10:08:51 +08:00
|
|
|
|
</el-aside>
|
2022-12-28 18:31:26 +08:00
|
|
|
|
|
2022-12-28 10:08:51 +08:00
|
|
|
|
</el-container>
|
|
|
|
|
|
|
|
|
|
<!-- 消息管理器 -->
|
|
|
|
|
<transition name="el-fade-in-linear">
|
|
|
|
|
<TalkSearchRecord v-if="findChatRecord" :params="{
|
2023-01-10 18:44:39 +08:00
|
|
|
|
talk_type: params.talk_type,
|
|
|
|
|
receiver_id: params.receiver_id,
|
|
|
|
|
title: params.nickname,
|
|
|
|
|
}" @close="findChatRecord = false" />
|
2022-12-28 10:08:51 +08:00
|
|
|
|
</transition>
|
|
|
|
|
|
|
|
|
|
<!-- 链接信息 -->
|
2023-02-01 15:03:40 +08:00
|
|
|
|
<OtherLink :toUser="toUser" :id="id" :goodsParams="goodsParams" class="flex-4" />
|
2022-12-28 10:08:51 +08:00
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<script>
|
|
|
|
|
import { textReplaceLink } from "@/utils/functions";
|
2023-01-13 10:53:39 +08:00
|
|
|
|
import { textReplaceEmoji, emojistwo } from "@/utils/emojis";
|
2022-12-28 10:08:51 +08:00
|
|
|
|
import OtherLink from "@/components/chat/panel/OtherLink.vue";
|
|
|
|
|
import { mapState, mapGetters } from "vuex";
|
|
|
|
|
import TalkSearchRecord from "@/components/chat/TalkSearchRecord";
|
|
|
|
|
import MeEditor from "@/components/editor/MeEditor";
|
|
|
|
|
import PanelHeader from "./PanelHeader";
|
|
|
|
|
import PanelToolbar from "./PanelToolbar";
|
|
|
|
|
import SocketInstance from "@/im-server/socket-instance";
|
|
|
|
|
import { SvgMentionDown } from "@/core/icons";
|
|
|
|
|
import { formatTime, parseTime, copyTextToClipboard } from "@/utils/functions";
|
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
ServeTalkRecords,
|
|
|
|
|
ServeForwardRecords,
|
|
|
|
|
ServeRemoveRecords,
|
|
|
|
|
ServeRevokeRecords,
|
|
|
|
|
} from "@/api/chat";
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: "TalkEditorPanel",
|
|
|
|
|
components: {
|
|
|
|
|
MeEditor,
|
|
|
|
|
OtherLink,
|
|
|
|
|
TalkSearchRecord,
|
|
|
|
|
SvgMentionDown,
|
|
|
|
|
PanelToolbar,
|
|
|
|
|
PanelHeader,
|
|
|
|
|
},
|
|
|
|
|
props: {
|
|
|
|
|
// 对话相关参数
|
|
|
|
|
params: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: function () {
|
|
|
|
|
return {
|
|
|
|
|
// 消息来源(1:好友私信 2:群聊)
|
|
|
|
|
talk_type: 0,
|
|
|
|
|
// 消息接收者ID(好友ID或者群聊ID)
|
|
|
|
|
receiver_id: 0,
|
|
|
|
|
nickname: "",
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
goodsParams: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: null,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 用户是否在线
|
|
|
|
|
isOnline: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
default: false,
|
|
|
|
|
},
|
|
|
|
|
},
|
2022-12-28 18:31:26 +08:00
|
|
|
|
data () {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
return {
|
|
|
|
|
// 记录加载相关参数
|
|
|
|
|
textReplaceEmoji,
|
2023-01-13 10:53:39 +08:00
|
|
|
|
emojistwo,
|
2022-12-28 10:08:51 +08:00
|
|
|
|
textReplaceLink,
|
|
|
|
|
loadRecord: {
|
|
|
|
|
status: 0,
|
|
|
|
|
minRecord: 0,
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
pageNumber: 0,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 多选相关操作
|
|
|
|
|
multiSelect: {
|
|
|
|
|
isOpen: false,
|
|
|
|
|
items: [],
|
|
|
|
|
mode: 0,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 群组Box
|
|
|
|
|
group: {
|
|
|
|
|
panel: false,
|
|
|
|
|
notice: false,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 键盘输入事件
|
|
|
|
|
keyboardEvent: {
|
|
|
|
|
isShow: false,
|
|
|
|
|
time: 0,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 聊天记录管理器数据
|
|
|
|
|
findChatRecord: false,
|
|
|
|
|
|
|
|
|
|
// 置底按钮是否显示
|
|
|
|
|
tipsBoard: false,
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
computed: {
|
|
|
|
|
...mapGetters(["talkItems"]),
|
|
|
|
|
...mapState({
|
|
|
|
|
name: (state) => state.user.name,
|
|
|
|
|
face: (state) => state.user.face,
|
|
|
|
|
unreadMessage: (state) => state.talks.unreadMessage,
|
|
|
|
|
inputEvent: (state) => state.notify.inputEvent,
|
|
|
|
|
id: (state) => state.user.id,
|
|
|
|
|
records: (state) => state.dialogue.records,
|
|
|
|
|
index_name: (state) => state.dialogue.index_name,
|
|
|
|
|
toUser: (state) => state.user.toUser,
|
|
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
|
|
|
|
// 监听面板传递参数
|
2022-12-28 18:31:26 +08:00
|
|
|
|
params () {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
this.loadRecord.minRecord = 0;
|
|
|
|
|
this.tipsBoard = false;
|
|
|
|
|
this.multiSelect = {
|
|
|
|
|
isOpen: false,
|
|
|
|
|
items: [],
|
|
|
|
|
mode: 0,
|
|
|
|
|
};
|
|
|
|
|
this.loadChatRecords();
|
2023-02-01 15:03:40 +08:00
|
|
|
|
|
2022-12-28 10:08:51 +08:00
|
|
|
|
},
|
|
|
|
|
},
|
2022-12-28 18:31:26 +08:00
|
|
|
|
mounted () {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
this.loadChatRecords();
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
parseTime,
|
|
|
|
|
sendTime: formatTime,
|
|
|
|
|
|
|
|
|
|
// 处理 Header 组件事件
|
2022-12-28 18:31:26 +08:00
|
|
|
|
handleHeaderEvent (event_name) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
switch (event_name) {
|
|
|
|
|
case "history":
|
|
|
|
|
this.findChatRecord = true;
|
|
|
|
|
break;
|
|
|
|
|
case "notice":
|
|
|
|
|
this.group.notice = true;
|
|
|
|
|
break;
|
|
|
|
|
case "setting":
|
|
|
|
|
this.group.panel = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// linkTo(type,val){
|
|
|
|
|
// if(type === 'GOODS'){
|
|
|
|
|
// let routeUrl = this.$router.resolve({
|
|
|
|
|
// path: '/goodsDetail',
|
|
|
|
|
// query: { skuId:val.id, goodsId:val.goodsId }
|
|
|
|
|
// });
|
|
|
|
|
// window.open(routeUrl.href, '_blank');
|
|
|
|
|
// }
|
|
|
|
|
// },
|
|
|
|
|
// #TODO 冗余代码
|
|
|
|
|
|
2022-12-28 18:31:26 +08:00
|
|
|
|
formatDateToString (date) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
var year = date.getFullYear();
|
|
|
|
|
var month = date.getMonth() + 1;
|
|
|
|
|
var day = date.getDate();
|
|
|
|
|
if (month < 10) month = "0" + month;
|
|
|
|
|
if (day < 10) day = "0" + day;
|
|
|
|
|
return year + "-" + month + "-" + day;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 将unix时间戳转换为指定格式
|
|
|
|
|
* @param unix 时间戳【秒】
|
|
|
|
|
* @param format 转换格式
|
|
|
|
|
* @returns {*|string}
|
|
|
|
|
*/
|
2022-12-28 18:31:26 +08:00
|
|
|
|
unixToDate (unix, format) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
if (!unix) return unix;
|
|
|
|
|
let _format = format || "yyyy-MM-dd hh:mm:ss";
|
|
|
|
|
const d = new Date(unix);
|
|
|
|
|
const o = {
|
|
|
|
|
"M+": d.getMonth() + 1,
|
|
|
|
|
"d+": d.getDate(),
|
|
|
|
|
"h+": d.getHours(),
|
|
|
|
|
"m+": d.getMinutes(),
|
|
|
|
|
"s+": d.getSeconds(),
|
|
|
|
|
"q+": Math.floor((d.getMonth() + 3) / 3),
|
|
|
|
|
S: d.getMilliseconds(),
|
|
|
|
|
};
|
|
|
|
|
if (/(y+)/.test(_format))
|
|
|
|
|
_format = _format.replace(
|
|
|
|
|
RegExp.$1,
|
|
|
|
|
(d.getFullYear() + "").substr(4 - RegExp.$1.length)
|
|
|
|
|
);
|
|
|
|
|
for (const k in o)
|
|
|
|
|
if (new RegExp("(" + k + ")").test(_format))
|
|
|
|
|
_format = _format.replace(
|
|
|
|
|
RegExp.$1,
|
|
|
|
|
RegExp.$1.length === 1
|
|
|
|
|
? o[k]
|
|
|
|
|
: ("00" + o[k]).substr(("" + o[k]).length)
|
|
|
|
|
);
|
|
|
|
|
return _format;
|
|
|
|
|
},
|
|
|
|
|
|
2022-12-28 18:31:26 +08:00
|
|
|
|
formateDateAndTimeToString (date) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
var hours = date.getHours();
|
|
|
|
|
var mins = date.getMinutes();
|
|
|
|
|
var secs = date.getSeconds();
|
|
|
|
|
var msecs = date.getMilliseconds();
|
|
|
|
|
if (hours < 10) hours = "0" + hours;
|
|
|
|
|
if (mins < 10) mins = "0" + mins;
|
|
|
|
|
if (secs < 10) secs = "0" + secs;
|
|
|
|
|
if (msecs < 10) secs = "0" + msecs;
|
|
|
|
|
return (
|
|
|
|
|
this.formatDateToString(date) + " " + hours + ":" + mins + ":" + secs
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
// #冗余代码结束
|
|
|
|
|
|
|
|
|
|
// 回车键发送消息回调事件
|
2022-12-28 18:31:26 +08:00
|
|
|
|
submitSendMessage (content) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
const record = {
|
|
|
|
|
operation_type: "MESSAGE",
|
|
|
|
|
to: this.params.receiver_id,
|
|
|
|
|
from: this.id,
|
|
|
|
|
message_type: "MESSAGE",
|
|
|
|
|
context: content,
|
|
|
|
|
talk_id: this.params.talkId,
|
|
|
|
|
};
|
2023-01-13 10:53:39 +08:00
|
|
|
|
// if (record.messageType == 'MESSAGE"') {
|
|
|
|
|
// record.text = this.textReplaceEmoji(record.content)
|
|
|
|
|
// }
|
2022-12-28 10:08:51 +08:00
|
|
|
|
SocketInstance.emit("event_talk", record);
|
|
|
|
|
|
|
|
|
|
this.$store.commit("UPDATE_TALK_ITEM", {
|
|
|
|
|
index_name: this.index_name,
|
|
|
|
|
draft_text: "",
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 插入数据
|
|
|
|
|
*/
|
|
|
|
|
const insterChat = {
|
|
|
|
|
createTime: this.formateDateAndTimeToString(new Date()),
|
|
|
|
|
fromUser: this.id,
|
|
|
|
|
toUser: record.to,
|
|
|
|
|
isRead: false,
|
|
|
|
|
messageType: "MESSAGE",
|
|
|
|
|
text: content,
|
|
|
|
|
float: "right",
|
|
|
|
|
};
|
|
|
|
|
// console.log("插入对话记录",'')
|
|
|
|
|
// 插入对话记录
|
|
|
|
|
this.$store.commit("PUSH_DIALOGUE", insterChat);
|
|
|
|
|
// 获取聊天面板元素节点
|
|
|
|
|
let el = document.getElementById("lumenChatPanel");
|
|
|
|
|
|
|
|
|
|
// 判断的滚动条是否在底部
|
|
|
|
|
let isBottom =
|
|
|
|
|
Math.ceil(el.scrollTop) + el.clientHeight >= el.scrollHeight;
|
|
|
|
|
|
|
|
|
|
if (isBottom || record.to == this.id) {
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
el.scrollTop = el.scrollHeight;
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
this.$store.commit("SET_TLAK_UNREAD_MESSAGE", {
|
|
|
|
|
content: content,
|
|
|
|
|
nickname: record.name,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 推送编辑事件消息
|
2022-12-28 18:31:26 +08:00
|
|
|
|
onKeyboardEvent (text) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
this.$store.commit("UPDATE_TALK_ITEM", {
|
|
|
|
|
index_name: this.index_name,
|
|
|
|
|
draft_text: text,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 判断当前对话是否属于私聊信息
|
|
|
|
|
if (this.params.talk_type == 2 || !this.isOnline) return;
|
|
|
|
|
|
|
|
|
|
// 判断是否推送键盘输入事件消息
|
|
|
|
|
if (!this.$store.state.settings.keyboardEventNotify) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let time = new Date().getTime();
|
|
|
|
|
// 判断在两秒内是否已推送事件
|
|
|
|
|
if (this.keyboardEvent.time != 0 && time - this.keyboardEvent.time < 2000)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
this.keyboardEvent.time = time;
|
|
|
|
|
|
|
|
|
|
// 调用父类Websocket组件发送消息
|
|
|
|
|
SocketInstance.emit("event_keyboard", {
|
|
|
|
|
sender_id: this.id,
|
|
|
|
|
receiver_id: this.params.receiver_id,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 加载用户聊天详情信息
|
2022-12-28 18:31:26 +08:00
|
|
|
|
loadChatRecords () {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
if (this.loadRecord.pageNumber === 0 || this.params.clickFlag) {
|
|
|
|
|
this.loadRecord.pageNumber = 1
|
|
|
|
|
this.params.clickFlag = false
|
|
|
|
|
} else {
|
|
|
|
|
this.loadRecord.pageNumber = this.loadRecord.pageNumber + 1
|
|
|
|
|
}
|
|
|
|
|
const user_id = this.id;
|
|
|
|
|
const data = {
|
2022-12-28 18:31:26 +08:00
|
|
|
|
pageNumber: this.loadRecord.pageNumber,
|
2022-12-28 10:08:51 +08:00
|
|
|
|
pageSize: this.loadChatRecords.pageSize,
|
|
|
|
|
talkId: this.params.talkId,
|
|
|
|
|
};
|
|
|
|
|
this.loadRecord.status = 0;
|
|
|
|
|
|
|
|
|
|
let el = document.getElementById('lumenChatPanel')
|
|
|
|
|
let scrollHeight = el.scrollHeight
|
|
|
|
|
ServeTalkRecords(data).then((res) => {
|
|
|
|
|
// 防止点击切换过快消息返回延迟,导致信息错误
|
|
|
|
|
// console.log("读取历史数据", res);
|
|
|
|
|
const records = res.result.map((item) => {
|
|
|
|
|
let key = new Date().getTime();
|
|
|
|
|
item.float = "center";
|
|
|
|
|
if (item.toUser > 0) {
|
|
|
|
|
item.float = item.fromUser == user_id ? "right" : "left";
|
|
|
|
|
}
|
2022-12-30 18:40:50 +08:00
|
|
|
|
if (item.messageType == 'GOODS') {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
item.text = JSON.parse(item.text)
|
|
|
|
|
}
|
2023-01-13 10:53:39 +08:00
|
|
|
|
// if (item.messageType == 'MESSAGE"') {
|
|
|
|
|
// item.text = this.textReplaceEmoji(item.text)
|
|
|
|
|
// }
|
2022-12-30 18:40:50 +08:00
|
|
|
|
if (item.messageType == 'ORDER') {
|
2022-12-29 18:20:06 +08:00
|
|
|
|
item.text = JSON.parse(item.text)
|
|
|
|
|
}
|
2022-12-28 10:08:51 +08:00
|
|
|
|
return { ...item, [key]: key };
|
|
|
|
|
});
|
|
|
|
|
this.$store.commit("UNSHIFT_DIALOGUE", records);
|
|
|
|
|
records.length
|
|
|
|
|
? (this.loadRecord.status = 1)
|
|
|
|
|
: (this.loadRecord.status = 2);
|
|
|
|
|
this.$nextTick(() => {
|
2023-01-31 17:42:36 +08:00
|
|
|
|
// if (data.record_id == 0 || !data.record_id) {
|
|
|
|
|
if (data.record_id == 0 || data.pageNumber == 1) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
el.scrollTop = el.scrollHeight
|
|
|
|
|
} else {
|
|
|
|
|
el.scrollTop = el.scrollHeight - scrollHeight
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 多选处理方式
|
2022-12-28 18:31:26 +08:00
|
|
|
|
handleMultiMode (value) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
if (value == "close") {
|
|
|
|
|
this.closeMultiSelect();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.multiSelect.items.length <= 1) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (value == "forward" || value == "merge_forward") {
|
|
|
|
|
this.multiSelect.mode = value == "forward" ? 1 : 2;
|
|
|
|
|
if (this.verifyMultiSelectType(3)) {
|
|
|
|
|
this.$notify({
|
|
|
|
|
title: "消息转发",
|
|
|
|
|
message: "会话记录不支持合并转发",
|
|
|
|
|
});
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.$contacts({
|
|
|
|
|
confirm: this.confirmSelectContacts,
|
|
|
|
|
});
|
|
|
|
|
} else if (value == "delete") {
|
|
|
|
|
this.multiSelect.mode = 3;
|
|
|
|
|
|
|
|
|
|
// 批量删除
|
|
|
|
|
let ids = this.multiSelect.items;
|
|
|
|
|
ServeRemoveRecords({
|
|
|
|
|
talk_type: this.params.talk_type,
|
|
|
|
|
receiver_id: this.params.receiver_id,
|
|
|
|
|
record_id: ids.join(","),
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
if (res.code == 200) {
|
|
|
|
|
this.delRecords(ids).closeMultiSelect();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 确认消息转发联系人事件
|
2022-12-28 18:31:26 +08:00
|
|
|
|
confirmSelectContacts (data) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
let user_ids = [];
|
|
|
|
|
let group_ids = [];
|
|
|
|
|
data.forEach((item) => {
|
|
|
|
|
if (item.type == 1) {
|
|
|
|
|
user_ids.push(item.id);
|
|
|
|
|
} else {
|
|
|
|
|
group_ids.push(item.id);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
ServeForwardRecords({
|
|
|
|
|
forward_mode: this.multiSelect.mode,
|
|
|
|
|
talk_type: this.params.talk_type,
|
|
|
|
|
receiver_id: this.params.receiver_id,
|
|
|
|
|
records_ids: this.multiSelect.items,
|
|
|
|
|
receive_user_ids: user_ids,
|
|
|
|
|
receive_group_ids: group_ids,
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
if (res.code == 200) {
|
|
|
|
|
this.closeMultiSelect();
|
|
|
|
|
this.$notify({
|
|
|
|
|
title: "消息转发",
|
|
|
|
|
message: "消息转发成功...",
|
|
|
|
|
type: "success",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 处理消息时间是否显示
|
2022-12-28 18:31:26 +08:00
|
|
|
|
compareTime (index, datetime) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
if (datetime == undefined) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (typeof datetime == "number") {
|
|
|
|
|
datetime = this.unixToDate(datetime, "yyyy-MM-dd hh:mm");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.records[index].is_revoke == 1) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
datetime = datetime.replace(/-/g, "/");
|
|
|
|
|
let time = Math.floor(Date.parse(datetime) / 1000);
|
|
|
|
|
let currTime = Math.floor(new Date().getTime() / 1000);
|
|
|
|
|
|
|
|
|
|
// 当前时间5分钟内时间不显示
|
|
|
|
|
if (currTime - time < 300) return false;
|
|
|
|
|
|
|
|
|
|
// 判断是否是最后一条消息,最后一条消息默认显示时间
|
|
|
|
|
if (index == this.records.length - 1) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let nextDate = this.records[index + 1].createTime.replace(/-/g, "/");
|
|
|
|
|
|
|
|
|
|
return !(
|
|
|
|
|
parseTime(new Date(datetime), "{y}-{m}-{d} {h}:{i}") ==
|
|
|
|
|
parseTime(new Date(nextDate), "{y}-{m}-{d} {h}:{i}")
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 查看好友用户信息
|
2022-12-28 18:31:26 +08:00
|
|
|
|
catFriendDetail (value) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
this.$user(value);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 撤回消息
|
2022-12-28 18:31:26 +08:00
|
|
|
|
revokeRecords (index, item) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
ServeRevokeRecords({
|
|
|
|
|
record_id: item.id,
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
if (res.code == 200) {
|
|
|
|
|
this.$store.commit("UPDATE_DIALOGUE", { id: item.id, is_revoke: 1 });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 删除消息
|
2022-12-28 18:31:26 +08:00
|
|
|
|
removeRecords (index, item) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
let receiver_id = item.receiver_id;
|
|
|
|
|
if (item.talk_type == 1 && item.user_id != this.id) {
|
|
|
|
|
receiver_id = item.user_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServeRemoveRecords({
|
|
|
|
|
talk_type: item.talk_type,
|
|
|
|
|
receiver_id: receiver_id,
|
|
|
|
|
record_id: item.id.toString(),
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
if (res.code == 200) {
|
|
|
|
|
this.$store.commit("DELETE_DIALOGUE", index);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 从列表中删除记录
|
2022-12-28 18:31:26 +08:00
|
|
|
|
delRecords (arr) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
this.$store.commit("BATCH_DELETE_DIALOGUE", arr);
|
|
|
|
|
return this;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 开启多选模式
|
2022-12-28 18:31:26 +08:00
|
|
|
|
openMultiSelect () {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
this.multiSelect.isOpen = true;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 关闭多选模式
|
2022-12-28 18:31:26 +08:00
|
|
|
|
closeMultiSelect () {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
this.multiSelect.isOpen = false;
|
|
|
|
|
this.multiSelect.items = [];
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 判断记录是否选中
|
2022-12-28 18:31:26 +08:00
|
|
|
|
verifyMultiSelect (records_id) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
return this.multiSelect.items.indexOf(records_id) >= 0;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 触发多选事件
|
2022-12-28 18:31:26 +08:00
|
|
|
|
triggerMultiSelect (records_id) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
let i = this.multiSelect.items.indexOf(records_id);
|
|
|
|
|
if (i >= 0) {
|
|
|
|
|
this.multiSelect.items.splice(i, 1);
|
|
|
|
|
} else {
|
|
|
|
|
if (this.multiSelect.items.length >= 30) {
|
|
|
|
|
this.$notify({
|
|
|
|
|
title: "温馨提示",
|
|
|
|
|
message: "批量操作最大支持30条数据...",
|
|
|
|
|
});
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
this.multiSelect.items.push(records_id);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 验证是否存在选择的指定类型的消息
|
2022-12-28 18:31:26 +08:00
|
|
|
|
verifyMultiSelectType (type) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
return this.records.some((item) => {
|
|
|
|
|
return this.verifyMultiSelect(item.id) && item.messageType == type;
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 消息点击右键触发自定义菜单
|
2022-12-28 18:31:26 +08:00
|
|
|
|
onCopy (idx, item, event) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
let menus = [];
|
|
|
|
|
let content = "";
|
|
|
|
|
if (document.getElementById("copy_class_" + item.id)) {
|
|
|
|
|
content = document.getElementById("copy_class_" + item.id).innerText;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (content) {
|
|
|
|
|
menus.push({
|
|
|
|
|
label: "复制",
|
|
|
|
|
icon: "el-icon-document-copy",
|
|
|
|
|
customClass: "cus-contextmenu-item",
|
|
|
|
|
onClick: () => {
|
|
|
|
|
copyTextToClipboard(content);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item.user_id == this.id) {
|
|
|
|
|
let time =
|
|
|
|
|
new Date().getTime() - Date.parse(item.createTime.replace(/-/g, "/"));
|
|
|
|
|
if (Math.floor(time / 1000 / 60) < 2) {
|
|
|
|
|
menus.push({
|
|
|
|
|
label: "撤回",
|
|
|
|
|
icon: "el-icon-s-flag",
|
|
|
|
|
customClass: "cus-contextmenu-item",
|
|
|
|
|
onClick: () => {
|
|
|
|
|
this.revokeRecords(idx, item);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
menus.push({
|
|
|
|
|
label: "删除",
|
|
|
|
|
icon: "el-icon-delete",
|
|
|
|
|
customClass: "cus-contextmenu-item",
|
|
|
|
|
onClick: () => {
|
|
|
|
|
this.removeRecords(idx, item);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
menus.push({
|
|
|
|
|
label: "引用",
|
|
|
|
|
icon: "el-icon-connection",
|
|
|
|
|
customClass: "cus-contextmenu-item",
|
|
|
|
|
onClick: () => { },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
menus.push({
|
|
|
|
|
label: "多选",
|
|
|
|
|
icon: "el-icon-finished",
|
|
|
|
|
customClass: "cus-contextmenu-item",
|
|
|
|
|
onClick: () => {
|
|
|
|
|
this.openMultiSelect();
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 判断是否是图片消息
|
|
|
|
|
if (item.messageType == 2 && item.file.file_type == 1) {
|
|
|
|
|
menus.push({
|
|
|
|
|
label: "收藏",
|
|
|
|
|
icon: "el-icon-picture",
|
|
|
|
|
customClass: "cus-contextmenu-item",
|
|
|
|
|
onClick: () => {
|
|
|
|
|
this.$store.commit("SAVE_USER_EMOTICON", {
|
|
|
|
|
record_id: item.id,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.$contextmenu({
|
|
|
|
|
items: menus,
|
|
|
|
|
event,
|
|
|
|
|
customClass: "cus-contextmenu",
|
|
|
|
|
zIndex: 3,
|
|
|
|
|
minWidth: 120,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.closeMultiSelect();
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
},
|
|
|
|
|
|
2022-12-28 18:31:26 +08:00
|
|
|
|
hideChatGroup () {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
this.group.panel = false;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 修改群聊免打扰状态
|
2022-12-28 18:31:26 +08:00
|
|
|
|
disturbChange (detail) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
this.$store.commit("UPDATE_TALK_ITEM", {
|
|
|
|
|
index_name: `2_${this.params.receiver_id}`,
|
|
|
|
|
is_disturb: parseInt(detail.status),
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 退出群聊回调事件
|
2022-12-28 18:31:26 +08:00
|
|
|
|
quitGroupSuccess () {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
this.$emit("close-talk");
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 同步群信息
|
2022-12-28 18:31:26 +08:00
|
|
|
|
syncGroupInfo (groupInfo) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
this.$refs.panelHeader.setGroupNum(groupInfo.members_num);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 对话面板滚动事件
|
2022-12-28 18:31:26 +08:00
|
|
|
|
talkPanelScroll (e) {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
if (e.target.scrollTop == 0 && this.loadRecord.status == 1) {
|
|
|
|
|
this.loadChatRecords();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const height = e.target.scrollTop + e.target.clientHeight + 5;
|
|
|
|
|
this.tipsBoard = height < e.target.scrollHeight;
|
|
|
|
|
if (this.tipsBoard == false && this.unreadMessage.num > 0) {
|
|
|
|
|
this.$store.commit("CLEAR_TLAK_UNREAD_MESSAGE");
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 聊天版本滚动到底部
|
2022-12-28 18:31:26 +08:00
|
|
|
|
talkPanelScrollBottom () {
|
2022-12-28 10:08:51 +08:00
|
|
|
|
let el = document.getElementById("lumenChatPanel");
|
|
|
|
|
el.scrollTop = el.scrollHeight;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
<style lang="less" scoped>
|
2023-01-10 18:44:39 +08:00
|
|
|
|
.order_status {
|
|
|
|
|
height: 30px;
|
|
|
|
|
width: 60px;
|
|
|
|
|
background: #ffeded;
|
|
|
|
|
margin-right: 20px;
|
|
|
|
|
text-align: center;
|
|
|
|
|
line-height: 25px;
|
|
|
|
|
margin-left: 15px;
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.oderStyle {
|
|
|
|
|
border: 1px solid #f2f2f2;
|
|
|
|
|
width: 330px;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
|
|
|
|
.oedersn {
|
|
|
|
|
margin: 10px 0 10px 5px;
|
|
|
|
|
width: 300px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.goodsStyle {
|
|
|
|
|
border: 1px solid #f2f2f2;
|
|
|
|
|
width: 300px;
|
|
|
|
|
height: 120px;
|
|
|
|
|
display: flex;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
|
|
|
|
.goods_name {
|
|
|
|
|
color: black;
|
|
|
|
|
width: 150px;
|
|
|
|
|
font-size: 15px;
|
|
|
|
|
color: #333333;
|
|
|
|
|
margin-top: 30px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image {
|
|
|
|
|
height: 70px;
|
|
|
|
|
margin-top: 3px;
|
|
|
|
|
width: 70px;
|
|
|
|
|
background-size: cover;
|
|
|
|
|
margin: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.price {
|
|
|
|
|
color: #999;
|
|
|
|
|
margin-top: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.base {
|
|
|
|
|
display: flex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-29 18:20:06 +08:00
|
|
|
|
.orderSn {
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
white-space: nowrap
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.orderGoodsName {
|
|
|
|
|
width: 200px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
2023-01-10 18:44:39 +08:00
|
|
|
|
// white-space: nowrap;
|
2022-12-29 18:20:06 +08:00
|
|
|
|
position: absolute;
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
margin-left: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.orderGoodsTime {
|
|
|
|
|
margin-left: 10px;
|
2023-01-10 18:44:39 +08:00
|
|
|
|
color: #999;
|
2022-12-29 18:20:06 +08:00
|
|
|
|
position: absolute;
|
2023-01-10 18:44:39 +08:00
|
|
|
|
margin-top: 70px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.orderFlowPrice {
|
|
|
|
|
color: #999;
|
|
|
|
|
margin-bottom: 20px;
|
2022-12-29 18:20:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-12-28 10:08:51 +08:00
|
|
|
|
.main-box {
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 面板页脚 */
|
|
|
|
|
.footer-box {
|
|
|
|
|
height: 160px !important;
|
|
|
|
|
padding: 0;
|
|
|
|
|
border-top: 1px solid #f5f5f5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 侧边栏css */
|
|
|
|
|
.sidebar-box {
|
|
|
|
|
position: absolute;
|
|
|
|
|
width: 350px;
|
|
|
|
|
height: 100%;
|
|
|
|
|
top: 0px;
|
|
|
|
|
right: -350px;
|
|
|
|
|
z-index: 1;
|
|
|
|
|
background: white;
|
|
|
|
|
transition: all 0.5s ease-in-out;
|
|
|
|
|
-moz-transition: all 0.5s ease-in-out;
|
|
|
|
|
-webkit-transition: all 0.5s ease-in-out;
|
|
|
|
|
-o-transition: all 0.5s ease-in-out;
|
|
|
|
|
|
|
|
|
|
&.show {
|
|
|
|
|
right: 0;
|
|
|
|
|
box-shadow: 0 0 14px #e2e1e1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tips-board {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
position: absolute;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
bottom: 20px;
|
|
|
|
|
height: 30px;
|
|
|
|
|
width: 100px;
|
|
|
|
|
border-radius: 20px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
box-shadow: 0 2.5px 10px 0 rgba(31, 35, 41, 0.1);
|
|
|
|
|
color: #1f2329;
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
margin-left: 5px;
|
|
|
|
|
margin-top: -2px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.svg {
|
|
|
|
|
width: 10px;
|
|
|
|
|
height: 10px;
|
|
|
|
|
color: black;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-12-28 18:31:26 +08:00
|
|
|
|
|
2022-12-29 18:20:06 +08:00
|
|
|
|
|
2023-01-10 18:44:39 +08:00
|
|
|
|
// .base {
|
|
|
|
|
// margin-top: 5px;
|
|
|
|
|
// height: 120px;
|
|
|
|
|
// display: flex;
|
2022-12-28 11:22:54 +08:00
|
|
|
|
|
2023-01-10 18:44:39 +08:00
|
|
|
|
// div {
|
|
|
|
|
// width: 100px;
|
|
|
|
|
// // overflow: hidden;
|
|
|
|
|
// // text-overflow: ellipsis;
|
|
|
|
|
// margin-top: 8px;
|
|
|
|
|
// // white-space: nowrap;
|
|
|
|
|
// }
|
2022-12-28 18:31:26 +08:00
|
|
|
|
|
2023-01-10 18:44:39 +08:00
|
|
|
|
// .image {
|
|
|
|
|
// height: 100px;
|
|
|
|
|
// margin-top: 3px;
|
|
|
|
|
// width: 100px
|
|
|
|
|
// }
|
2022-12-28 10:08:51 +08:00
|
|
|
|
|
2023-01-10 18:44:39 +08:00
|
|
|
|
// }
|
2022-12-28 18:31:26 +08:00
|
|
|
|
|
2022-12-28 10:08:51 +08:00
|
|
|
|
.talk-bubble {
|
|
|
|
|
position: absolute;
|
|
|
|
|
left: 0px;
|
|
|
|
|
bottom: 20px;
|
|
|
|
|
max-width: 300px;
|
|
|
|
|
height: 40px;
|
|
|
|
|
line-height: 40px;
|
|
|
|
|
border-radius: 0 20px 20px 0;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
color: white;
|
|
|
|
|
padding: 0 15px 0 30px;
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
background: #409eff;
|
|
|
|
|
|
|
|
|
|
i {
|
|
|
|
|
font-size: 22px;
|
|
|
|
|
position: absolute;
|
|
|
|
|
left: 5px;
|
|
|
|
|
top: 9px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.talks-container {
|
|
|
|
|
height: 100%;
|
|
|
|
|
width: 100%;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
padding: 10px 15px 30px;
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
|
|
|
|
.message-box {
|
|
|
|
|
width: 100%;
|
|
|
|
|
min-height: 30px;
|
|
|
|
|
margin-bottom: 5px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.loading-toolbar {
|
|
|
|
|
height: 30px;
|
|
|
|
|
line-height: 30px;
|
|
|
|
|
margin: 5px 0;
|
|
|
|
|
text-align: center;
|
|
|
|
|
user-select: none;
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
color: #cec4c4;
|
|
|
|
|
|
|
|
|
|
.color-blue {
|
|
|
|
|
color: #409eff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.datetime {
|
|
|
|
|
height: 30px;
|
|
|
|
|
line-height: 30px;
|
|
|
|
|
color: #ccc9c9;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
text-align: center;
|
|
|
|
|
margin: 5px 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.record-box {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
transition: 0.5s ease;
|
|
|
|
|
|
|
|
|
|
.checkbox-column {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
flex-basis: 40px;
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
order: 1;
|
|
|
|
|
user-select: none;
|
|
|
|
|
padding-top: 25px;
|
|
|
|
|
|
|
|
|
|
i {
|
|
|
|
|
color: #ccc;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
font-size: 22px;
|
|
|
|
|
|
|
|
|
|
&.selected {
|
|
|
|
|
color: #409eff !important;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.avatar-column {
|
|
|
|
|
width: 40px;
|
|
|
|
|
flex-basis: 40px;
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
order: 2;
|
|
|
|
|
user-select: none;
|
|
|
|
|
padding-top: 22px;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.main-column {
|
|
|
|
|
flex: 1 auto;
|
|
|
|
|
order: 3;
|
|
|
|
|
position: relative;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
padding: 5px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
|
|
|
|
.talk-title {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
height: 15px;
|
|
|
|
|
margin-bottom: 2px;
|
|
|
|
|
font-size: 10px;
|
|
|
|
|
user-select: none;
|
|
|
|
|
color: #a7a0a0;
|
|
|
|
|
opacity: 0;
|
|
|
|
|
transition: 0.5s ease;
|
|
|
|
|
|
|
|
|
|
&.show {
|
|
|
|
|
opacity: 1 !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
transform: scale(0.9);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.talk-content {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
|
|
.nickname {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #a7a0a0;
|
|
|
|
|
margin: -4px 0 4px -8px;
|
|
|
|
|
transform: scale(0.9);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
.talk-title {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.direction-rt {
|
|
|
|
|
.avatar-column {
|
|
|
|
|
order: 3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.main-column {
|
|
|
|
|
order: 2;
|
|
|
|
|
|
|
|
|
|
.talk-title {
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.talk-content {
|
|
|
|
|
align-items: flex-end;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.checkbox-border {
|
|
|
|
|
border: 1px dashed #c4c4ec;
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
border-color: #409eff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@bg-left-color: #f5f5f5;
|
2023-01-10 18:44:39 +08:00
|
|
|
|
@bg-right-color: #ffffff;
|
2022-12-28 10:08:51 +08:00
|
|
|
|
|
|
|
|
|
.text-message {
|
|
|
|
|
position: relative;
|
|
|
|
|
min-width: 30px;
|
|
|
|
|
min-height: 30px;
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
padding: 5px;
|
|
|
|
|
|
|
|
|
|
.arrow {
|
|
|
|
|
position: absolute;
|
|
|
|
|
width: 0;
|
|
|
|
|
height: 0;
|
|
|
|
|
font-size: 0;
|
|
|
|
|
border: 5px solid;
|
|
|
|
|
top: 6px;
|
|
|
|
|
left: -10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.max-width {
|
|
|
|
|
max-width: calc(100% - 50px);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.left {
|
|
|
|
|
color: #3a3a3a;
|
|
|
|
|
background: @bg-left-color;
|
|
|
|
|
|
|
|
|
|
.arrow {
|
|
|
|
|
border-color: transparent @bg-left-color transparent transparent;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.right {
|
|
|
|
|
color: #fff;
|
|
|
|
|
background: @bg-right-color;
|
|
|
|
|
|
|
|
|
|
.arrow {
|
|
|
|
|
right: -10px;
|
|
|
|
|
left: unset;
|
|
|
|
|
border-color: transparent transparent transparent @bg-right-color;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pre {
|
|
|
|
|
white-space: pre-wrap;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
word-break: break-word;
|
|
|
|
|
word-wrap: break-word;
|
|
|
|
|
font-size: 15px;
|
|
|
|
|
padding: 3px 10px;
|
|
|
|
|
font-family: "Microsoft YaHei";
|
|
|
|
|
line-height: 25px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|