chat.vue 22 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
  1. <template>
  2. <view class="chat-box" :style="colorStyle">
  3. <!-- #ifdef MP -->
  4. <view class="head-box">
  5. <view class="system-head" :style="{ height: sysHead }"></view>
  6. <view class="title-hd">
  7. <view class="iconfont icon-fanhui" @click="goBack"></view>
  8. <view>{{ titleName }}</view>
  9. </view>
  10. </view>
  11. <!-- #endif -->
  12. <view class="broadcast-details_order">
  13. <!-- 商品信息 -->
  14. <view class="broadcast-details_box" v-if="productId && productInfo.id">
  15. <view class="broadcast_details_img">
  16. <image class="goods-img" :src="productInfo.image" />
  17. </view>
  18. <view class="broadcast_details_picBox">
  19. <view class="broadcast_details_tit" v-text="productInfo.store_name"></view>
  20. <view class="bottom acea-row row-between">
  21. <view class="broadcast_details_pic">
  22. ¥{{ productInfo.price }}
  23. <text class="broadcast_details_pic_num"
  24. v-if="productInfo.ot_price">¥{{ productInfo.ot_price }}</text>
  25. </view>
  26. <view class="broadcast_details_btn" @click="sendProduct">发送客服</view>
  27. </view>
  28. </view>
  29. </view>
  30. <!-- 订单信息 -->
  31. <view class="broadcast_box" v-if="orderId && orderInfo.id">
  32. <view class="broadcast-details_num broadcast_num">
  33. <text>订单号:{{ orderInfo.order_id }}</text>
  34. <text>{{ orderInfo.add_time_y }} {{ orderInfo.add_time_h }}</text>
  35. </view>
  36. <view class="broadcast-details_box" v-if="orderInfo.cartInfo">
  37. <view class="broadcast_details_img">
  38. <image class="goods-img"
  39. :src="orderInfo.cartInfo[0].productInfo.attrInfo?orderInfo.cartInfo[0].productInfo.attrInfo.image:orderInfo.cartInfo[0].productInfo.image" />
  40. <view class="broadcast_details_model">
  41. {{ orderInfo.cartInfo ? orderInfo.cartInfo.length : 0 }}件商品
  42. </view>
  43. </view>
  44. <view class="broadcast_details_picBox">
  45. <view class="broadcast_details_tit">{{ orderInfo.cartInfo[0].productInfo.store_name }}</view>
  46. <view class="bottom acea-row row-between">
  47. <view class="broadcast_details_pic">
  48. ¥{{ orderInfo.cartInfo[0].productInfo.attrInfo?orderInfo.cartInfo[0].productInfo.attrInfo.price:orderInfo.cartInfo[0].productInfo.price }}
  49. <text class="broadcast_details_pic_num">¥{{ orderInfo.cartInfo[0].costPrice }}</text>
  50. </view>
  51. <view class="broadcast_details_btn" @click="sendOrder">发送客服</view>
  52. </view>
  53. </view>
  54. </view>
  55. </view>
  56. </view>
  57. <view class="chat-scroll-box">
  58. <scroll-view scroll-y="true" style="height: 100%;" :scroll-top="scrollTop" @scrolltoupper="scrollToTop">
  59. <Loading :loaded="status" :loading="loading"></Loading>
  60. <view id="box" class="chat" ref="chat">
  61. <view v-for="(item, index) in records" :key="index" :id="`msg-${item.id}`" class="msgItem">
  62. <view class="day-box" v-if="item.show">{{item._add_time}}</view>
  63. <view class="chat-item" :class="{ 'right-box': item.uid == myUid }">
  64. <image class="avatar" :src="item.avatar" mode=""></image>
  65. <!-- 消息 -->
  66. <view class="msg-box" v-if="item.msn_type <= 2" v-html="item.msn"></view>
  67. <!-- 图片 -->
  68. <view class="img-box" v-if="item.msn_type == 3">
  69. <image :src="item.msn" mode="widthFix" @tap="previewImage(item.msn)"></image>
  70. </view>
  71. <!-- 商品 -->
  72. <view class="product-box" v-if="item.msn_type == 5" @click="goProduct(item)">
  73. <image
  74. :src="item.productInfo.cartInfo?item.productInfo.cartInfo.image:item.productInfo.image"
  75. mode="widthFix"></image>
  76. <view class="info">
  77. <view class="price">
  78. <text>¥</text>
  79. {{ item.productInfo.cartInfo?item.productInfo.cartInfo.price:item.productInfo.price }}
  80. </view>
  81. <view class="name line2">{{ item.productInfo.store_name }}</view>
  82. </view>
  83. </view>
  84. <!-- 订单 -->
  85. <view class="order-box"
  86. v-if="(item.msn_type == 6 || item.msn_type == 7) && item.orderInfo.cartInfo"
  87. @click="goOrder(item)">
  88. <view class="title">订单号: {{ item.orderInfo.order_id }}</view>
  89. <view class="info">
  90. <image
  91. :src="item.orderInfo.cartInfo[0].productInfo.attrInfo?item.orderInfo.cartInfo[0].productInfo.attrInfo.image:item.orderInfo.cartInfo[0].productInfo.image">
  92. </image>
  93. <view class="product-info">
  94. <view class="name line2">{{ item.orderInfo.cartInfo[0].productInfo.store_name }}
  95. </view>
  96. <view class="price">
  97. ¥{{ item.orderInfo.cartInfo[0].productInfo.attrInfo?item.orderInfo.cartInfo[0].productInfo.attrInfo.price:item.orderInfo.cartInfo[0].productInfo.price }}
  98. </view>
  99. </view>
  100. </view>
  101. </view>
  102. </view>
  103. </view>
  104. </view>
  105. </scroll-view>
  106. </view>
  107. <view class="footer-box">
  108. <view class="words" @click="uploadImg"><text class="iconfont icon-tupian2"></text></view>
  109. <view class="input-box">
  110. <input type="text" placeholder="请输入内容" v-model="con" confirm-type="send" @confirm="sendText" />
  111. <text class="iconfont icon-fasong" @click="sendText" :class="{ isSend: isSend }"></text>
  112. </view>
  113. <view class="emoji" @click="isSwiper = !isSwiper"><span class="iconfont icon-biaoqing2"></span></view>
  114. </view>
  115. <!-- 表情 -->
  116. <view class="banner slider-banner" v-if="isSwiper && httpUrl">
  117. <swiper class="swiper-wrapper" :autoplay="autoplay" :circular="circular" :interval="interval"
  118. :duration="duration" v-if="emojiGroup.length > 0">
  119. <block v-for="(emojiList, index) in emojiGroup" :key="index">
  120. <swiper-item><i class="em" :class="emoji" :style="'background-image:url('+ httpUrl +')'"
  121. v-for="emoji in emojiList" :key="emoji" @click="addEmoji(emoji)"></i></swiper-item>
  122. </block>
  123. </swiper>
  124. </view>
  125. <canvas canvas-id="canvas" v-if="canvasStatus"
  126. :style="{width: canvasWidth + 'px', height: canvasHeight + 'px',position: 'absolute',left:'-100000px',top:'-100000px'}"></canvas>
  127. </view>
  128. </template>
  129. <script>
  130. const app = getApp();
  131. import {
  132. HTTP_REQUEST_URL
  133. } from "@/config/app.js";
  134. import {
  135. getChatRecord
  136. } from '@/api/user';
  137. import {
  138. getProductDetail
  139. } from '@/api/store';
  140. import {
  141. getOrderDetail,
  142. getRefundOrderDetail
  143. } from '@/api/order';
  144. let statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px';
  145. const chunk = function(arr, num) {
  146. num = num * 1 || 1;
  147. var ret = [];
  148. arr.forEach(function(item, i) {
  149. if (i % num === 0) {
  150. ret.push([]);
  151. }
  152. ret[ret.length - 1].push(item);
  153. });
  154. return ret;
  155. };
  156. import emojiList from '@/utils/emoji';
  157. import Loading from '@/components/Loading';
  158. import colors from "@/mixins/color";
  159. export default {
  160. name: 'adminChat_index',
  161. data() {
  162. return {
  163. httpUrl: '',
  164. status: false,
  165. loading: false,
  166. sysHead: statusBarHeight,
  167. isTool: false,
  168. isSwiper: false,
  169. isWords: false,
  170. autoplay: false,
  171. circular: true,
  172. interval: 3000,
  173. duration: 500,
  174. emojiGroup: chunk(emojiList, 21),
  175. wordsList: [],
  176. con: '',
  177. toUid: 0,
  178. limit: 15,
  179. upperId: 0,
  180. chatList: [],
  181. kefuInfo: {},
  182. scrollTop: 0,
  183. active: true,
  184. isScroll: true,
  185. oldHeight: 0,
  186. myUid: 0,
  187. productId: 0,
  188. productInfo: {},
  189. orderId: 0,
  190. page: 1,
  191. orderInfo: {},
  192. uidTo: 0,
  193. titleName: '',
  194. chatStatus: false,
  195. userType: 0,
  196. canvasWidth: "",
  197. canvasHeight: "",
  198. canvasStatus: false,
  199. isReturen: 0
  200. };
  201. },
  202. mixins: [colors],
  203. components: {
  204. Loading
  205. },
  206. computed: {
  207. isSend() {
  208. if (this.con.length == 0) {
  209. return false;
  210. } else {
  211. return true;
  212. }
  213. },
  214. records() {
  215. return this.chatList.map((item, index) => {
  216. if (index) {
  217. if (item.add_time - this.chatList[index - 1].add_time >= 300) {
  218. item.show = true;
  219. } else {
  220. item.show = false;
  221. }
  222. } else {
  223. item.show = true;
  224. }
  225. return item;
  226. });
  227. }
  228. },
  229. onLoad(options) {
  230. this.isReturen = options.isReturen;
  231. this.myUid = this.$store.state.app.uid;
  232. this.toUid = options.to_uid
  233. this.productId = parseInt(options.productId) || 0;
  234. this.orderId = options.orderId || 0;
  235. this.userType = options.type
  236. this.getproductInfo();
  237. this.getOrderInfo();
  238. this.getChatList();
  239. },
  240. onUnload() {
  241. this.$socket.clearPing();
  242. app.globalData.isWsOpen = false;
  243. uni.$off()
  244. },
  245. onReady() {
  246. this.httpUrl = `${HTTP_REQUEST_URL}/statics/images/look.png`;
  247. // #ifdef H5
  248. let dom = document.querySelector(".chat-box");
  249. dom.style.height = window.innerHeight + 'px'
  250. // #endif
  251. // 监听客服转接
  252. uni.$on('to_transfer', data => {
  253. this.toUid = data.toUid;
  254. this.$socket.send({
  255. data: {
  256. id: this.toUid
  257. },
  258. type: 'to_chat'
  259. });
  260. this.chatList.forEach(el => {
  261. if (el.uid != this.myUid) {
  262. el.avatar = data.avatar
  263. }
  264. })
  265. });
  266. // 链接成功
  267. uni.$on('success', () => {
  268. app.globalData.isWsOpen = true;
  269. uni.hideLoading();
  270. this.$socket.send({
  271. data: {
  272. id: this.toUid
  273. },
  274. type: 'to_chat'
  275. });
  276. });
  277. // 消息接收
  278. uni.$on(['reply', 'chat'], data => {
  279. if (data.msn_type == 1) {
  280. data.msn = this.replace_em(data.msn);
  281. }
  282. data._add_time = data._add_time.substring(0, data._add_time.length - 3);
  283. this.chatList.push(data);
  284. this.$nextTick(() => {
  285. this.height();
  286. });
  287. });
  288. uni.$on('socket_error', () => {
  289. this.$util.Tips({
  290. title: '连接失败'
  291. });
  292. });
  293. uni.$on('err_tip', (e) => {
  294. this.$util.Tips({
  295. title: e.msg
  296. });
  297. });
  298. uni.$on('online', data => {
  299. if (data.online == 0) {
  300. uni.showModal({
  301. title: '提示',
  302. content: '客服已下线,是否需要反馈?',
  303. success: function(res) {
  304. if (res.confirm) {
  305. uni.redirectTo({
  306. url: '/pages/columnGoods/HotNewGoods/feedback'
  307. });
  308. } else if (res.cancel) {}
  309. }
  310. });
  311. }
  312. });
  313. this.$nextTick(() => {
  314. this.height();
  315. });
  316. },
  317. onShow(){
  318. uni.removeStorageSync('form_type_cart');
  319. },
  320. methods: {
  321. previewImage(n) {
  322. uni.previewImage({
  323. urls: [n]
  324. });
  325. },
  326. // 返回
  327. goBack() {
  328. uni.navigateBack({
  329. delta: 1,
  330. fail(){
  331. uni.switchTab({
  332. url: '/pages/index/index'
  333. })
  334. }
  335. });
  336. },
  337. // 商品信息
  338. getproductInfo() {
  339. let that = this;
  340. if (!this.productId) return;
  341. getProductDetail(this.productId).then(res => {
  342. that.productInfo = res.data.storeInfo;
  343. });
  344. },
  345. // 商品信息
  346. goProduct(item) {
  347. uni.navigateTo({
  348. url: `/pages/goods_details/index?id=${item.msn}`
  349. });
  350. },
  351. // 订单详情
  352. goOrder(item) {
  353. if (this.userType) {
  354. if (item.msn_type == 7) {
  355. uni.navigateTo({
  356. url: `/pages/admin/orderDetail/index?id=${item.msn}&isReturen=1`
  357. });
  358. } else {
  359. uni.navigateTo({
  360. url: `/pages/admin/orderDetail/index?id=${item.msn}`
  361. });
  362. }
  363. } else {
  364. if (item.msn_type == 7) {
  365. uni.navigateTo({
  366. url: `/pages/goods/order_details/index?order_id=${item.msn}&isReturen=1`
  367. });
  368. } else {
  369. uni.navigateTo({
  370. url: `/pages/goods/order_details/index?order_id=${item.msn}`
  371. });
  372. }
  373. }
  374. },
  375. // 订单消息
  376. getOrderInfo() {
  377. if (!this.orderId) return;
  378. let obj = '';
  379. if (this.isReturen == 1) {
  380. obj = getRefundOrderDetail(this.orderId);
  381. } else {
  382. obj = getOrderDetail(this.orderId);
  383. }
  384. obj.then(res => {
  385. this.orderInfo = res.data;
  386. if (this.orderInfo.add_time_h) {
  387. this.orderInfo.add_time_h = this.orderInfo.add_time_h.substring(0, this.orderInfo
  388. .add_time_h.lastIndexOf(':'));
  389. }
  390. if (this.orderInfo.cartInfo.length) {
  391. this.cartInfo = this.orderInfo.cartInfo[0];
  392. }
  393. });
  394. },
  395. // 表情点击
  396. addEmoji(item) {
  397. let val = `[${item}]`;
  398. this.con += val;
  399. },
  400. // 聊天表情转换
  401. replace_em(str) {
  402. str = str.replace(/\[em-([\s\S]*)\]/g, "<span class='em em-$1' style='background-image:url(" + this
  403. .httpUrl + ")'></span>");
  404. return str;
  405. },
  406. // 获取聊天列表
  407. getChatList() {
  408. let self = this;
  409. getChatRecord({
  410. limit: this.limit,
  411. uidTo: this.uidTo,
  412. toUid: this.toUid
  413. })
  414. .then(res => {
  415. let selector = '';
  416. if (res.data.serviceList.length) {
  417. if (this.uidTo == 0) {
  418. selector = `#msg-${res.data.serviceList[res.data.serviceList.length - 1].id}`;
  419. } else {
  420. selector = `#msg-${this.chatList[0].id}`;
  421. }
  422. }
  423. let arr = [];
  424. var sH = 0;
  425. uni.hideLoading();
  426. uni.setNavigationBarTitle({
  427. title: res.data.nickname
  428. });
  429. this.titleName = res.data.nickname;
  430. this.toUid = res.data.uid;
  431. res.data.serviceList.forEach(el => {
  432. el._add_time = el._add_time.substring(0, el._add_time.length - 3);
  433. if (el.msn_type == 1 || el.msn_type == 2) {
  434. el.msn = this.replace_em(el.msn);
  435. }
  436. });
  437. this.loading = false;
  438. this.chatList = [...res.data.serviceList, ...this.chatList];
  439. if (!app.globalData.isWsOpen) {
  440. uni.showLoading({
  441. title: '客服连接中...',
  442. });
  443. this.$socket.startConnect();
  444. //5秒后还是没有连接自动关闭
  445. setTimeout(() => {
  446. uni.hideLoading();
  447. }, 5000);
  448. }
  449. this.$nextTick(() => {
  450. this.setPageScrollTo(selector);
  451. this.isScroll = res.data.serviceList.length >= this.limit;
  452. });
  453. })
  454. .catch(error => {
  455. uni.hideLoading();
  456. this.$util.Tips({
  457. title: error
  458. });
  459. this.loading = false;
  460. this.isScroll = false
  461. uni.redirectTo({
  462. url: '/pages/columnGoods/HotNewGoods/feedback'
  463. });
  464. });
  465. },
  466. // 设置页面滚动位置
  467. setPageScrollTo(selector) {
  468. try {
  469. if (this.chatList.length) {
  470. let view = uni
  471. .createSelectorQuery()
  472. .in(this)
  473. .select(selector);
  474. view.boundingClientRect(res => {
  475. this.scrollTop = parseFloat(res.top) - 60;
  476. }).exec();
  477. }
  478. } catch (e) {
  479. console.log(e);
  480. }
  481. },
  482. // 发送消息
  483. sendText() {
  484. if (!this.isSend || this.con.trim() === '') {
  485. return this.$util.Tips({
  486. title: '请输入内容'
  487. });
  488. }
  489. this.sendMsg(this.con, 1);
  490. this.con = '';
  491. },
  492. // ws发送
  493. sendMsg(msn, type) {
  494. this.$socket.send({
  495. data: {
  496. msn,
  497. type,
  498. to_uid: this.toUid
  499. },
  500. //#ifdef MP || APP-PLUS
  501. form_type: 2,
  502. //#endif
  503. //#ifdef H5
  504. form_type: this.$wechat.isWeixin() ? 1 : 3,
  505. //#endif
  506. type: 'chat'
  507. });
  508. },
  509. uploadImg() {
  510. let self = this;
  511. self.canvasStatus = true
  512. self.$util.uploadImageChange('upload/image', function(res) {
  513. if (res.status == 200) {
  514. self.sendMsg(res.data.url, 3);
  515. }
  516. }, (res) => {
  517. this.canvasStatus = false
  518. }, (res) => {
  519. this.canvasWidth = res.w
  520. this.canvasHeight = res.h
  521. });
  522. },
  523. // 发送商品
  524. sendProduct() {
  525. this.sendMsg(this.productId, 5);
  526. this.productId = 0;
  527. this.productInfo = {};
  528. },
  529. // 发送订单
  530. sendOrder() {
  531. let num = 0;
  532. if (this.isReturen == 1) {
  533. num = 7;
  534. } else {
  535. num = 6;
  536. }
  537. this.sendMsg(this.orderId, num);
  538. this.orderId = 0;
  539. this.orderInfo = {};
  540. },
  541. // 滚动到底部
  542. height() {
  543. let self = this;
  544. var scrollTop = 0;
  545. let info = uni.createSelectorQuery().select('.chat');
  546. setTimeout(res => {
  547. info.boundingClientRect(function(data) {
  548. //data - 各种参数
  549. scrollTop = data.height;
  550. if (self.active) {
  551. self.scrollTop = parseInt(scrollTop) + 500;
  552. } else {
  553. self.scrollTop = parseInt(scrollTop) + 100;
  554. }
  555. }).exec();
  556. }, 200);
  557. },
  558. // 滚动到顶部
  559. scrollToTop() {
  560. let self = this;
  561. if (this.isScroll) {
  562. this.loading = true;
  563. this.uidTo = this.chatList[0].id;
  564. this.isScroll = false;
  565. setTimeout(res => {
  566. this.getChatList();
  567. }, 800);
  568. }
  569. }
  570. }
  571. };
  572. </script>
  573. <style>
  574. /* #ifdef MP || APP-PLUS || H5 */
  575. page,
  576. uni-page-body,
  577. html,
  578. body {
  579. height: 100%;
  580. }
  581. /* #endif */
  582. </style>
  583. <style lang="scss">
  584. .chat-box {
  585. display: flex;
  586. flex-direction: column;
  587. height: 100%;
  588. background: #f0f1f2;
  589. /* #ifdef H5 */
  590. height: 100vh;
  591. /* #endif */
  592. .head-box {
  593. /* #ifdef H5 */
  594. height: 86rpx;
  595. /* #endif */
  596. background: linear-gradient(85deg, $kf-star 0%, $kf-end 100%);
  597. .title-hd {
  598. display: flex;
  599. align-items: center;
  600. justify-content: center;
  601. position: relative;
  602. height: 43px;
  603. padding: 0 30rpx;
  604. color: #fff;
  605. .icon-fanhui {
  606. position: absolute;
  607. left: 30rpx;
  608. top: 50%;
  609. transform: translateY(-50%);
  610. }
  611. .icon-gengduo2 {
  612. /* #ifdef MP */
  613. position: absolute;
  614. right: 210rpx;
  615. top: 50%;
  616. transform: translateY(-50%);
  617. /* #endif */
  618. }
  619. }
  620. }
  621. .scroll-box {
  622. flex: 1;
  623. }
  624. .footer-box {
  625. display: flex;
  626. align-items: center;
  627. padding: 0 30rpx;
  628. color: rgba(0, 0, 0, 0.8);
  629. background: #f7f7f7;
  630. height: 100rpx;
  631. height: calc(100rpx+ constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
  632. height: calc(100rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
  633. .words .icon-tupian2 {
  634. font-size: 50rpx;
  635. }
  636. .input-box {
  637. display: flex;
  638. align-items: center;
  639. flex: 1;
  640. height: 64rpx;
  641. padding-right: 5rpx;
  642. margin-left: 18rpx;
  643. background-color: #fff;
  644. border-radius: 32rpx;
  645. input {
  646. flex: 1;
  647. padding-left: 20rpx;
  648. height: 100%;
  649. font-size: 28rpx;
  650. font-weight: normal;
  651. }
  652. .icon-fasong {
  653. font-size: 50rpx;
  654. color: #ccc;
  655. font-weight: normal;
  656. }
  657. .isSend {
  658. color: $kf-theme;
  659. }
  660. }
  661. .emoji .icon-biaoqing2 {
  662. margin-left: 18rpx;
  663. font-size: 50rpx;
  664. }
  665. .more .icon-gengduozhankai {
  666. margin-left: 18rpx;
  667. font-size: 50rpx;
  668. }
  669. }
  670. }
  671. .tool-wrapper {
  672. display: flex;
  673. justify-content: space-between;
  674. padding: 45rpx 60rpx;
  675. background: #fff;
  676. font-size: 24rpx;
  677. .tool-item {
  678. text-align: center;
  679. image {
  680. width: 104rpx;
  681. height: 104rpx;
  682. }
  683. }
  684. }
  685. .slider-banner {
  686. background: #fff;
  687. }
  688. .words-mask {
  689. z-index: 50;
  690. position: fixed;
  691. left: 0;
  692. top: 0;
  693. right: 0;
  694. bottom: 0;
  695. background: rgba(0, 0, 0, 0.5);
  696. .content {
  697. position: absolute;
  698. left: 0;
  699. right: 0;
  700. top: 114rpx;
  701. bottom: 0;
  702. display: flex;
  703. flex-direction: column;
  704. padding: 0 30rpx;
  705. background: #fff;
  706. border-radius: 6rpx 6rpx 0px 0px;
  707. .title-box {
  708. position: relative;
  709. height: 125rpx;
  710. line-height: 125rpx;
  711. text-align: center;
  712. font-size: 32rpx;
  713. .icon-cha1 {
  714. position: absolute;
  715. right: 0;
  716. top: 50%;
  717. transform: translateY(-50%);
  718. }
  719. }
  720. .scroll-box {
  721. flex: 1;
  722. overflow: hidden;
  723. .msg-item {
  724. padding: 25rpx 0;
  725. border-bottom: 1px solid #eceff8;
  726. }
  727. }
  728. }
  729. }
  730. .chat-scroll-box {
  731. flex: 1;
  732. padding: 0 30rpx 0;
  733. overflow: hidden;
  734. .chat-item {
  735. display: flex;
  736. margin-bottom: 16rpx;
  737. padding-bottom: 20rpx;
  738. .avatar {
  739. width: 80rpx;
  740. height: 80rpx;
  741. border-radius: 50%;
  742. }
  743. .msg-box {
  744. display: flex;
  745. align-items: center;
  746. max-width: 452rpx;
  747. margin-left: 22rpx;
  748. padding: 10rpx 24rpx;
  749. background: #fff;
  750. border-radius: 14rpx;
  751. word-break: break-all;
  752. }
  753. .img-box {
  754. width: 270rpx;
  755. margin-left: 22rpx;
  756. image {
  757. width: 270rpx;
  758. }
  759. }
  760. .product-box {
  761. width: 452rpx;
  762. margin-left: 22rpx;
  763. background-color: #fff;
  764. border-radius: 14rpx;
  765. overflow: hidden;
  766. image {
  767. width: 452rpx;
  768. }
  769. .info {
  770. padding: 16rpx 26rpx;
  771. .price {
  772. font-size: 36rpx;
  773. color: var(--view-priceColor);
  774. text {
  775. font-size: 28rpx;
  776. }
  777. }
  778. }
  779. }
  780. .order-box {
  781. width: 452rpx;
  782. margin-left: 22rpx;
  783. background-color: #fff;
  784. border-radius: 14rpx;
  785. .title {
  786. padding: 15rpx 20rpx;
  787. font-size: 26rpx;
  788. color: #282828;
  789. border-bottom: 1px solid #eceff8;
  790. }
  791. .info {
  792. display: flex;
  793. padding: 20rpx;
  794. image {
  795. width: 124rpx;
  796. height: 124rpx;
  797. border-radius: 6rpx;
  798. }
  799. .product-info {
  800. flex: 1;
  801. display: flex;
  802. flex-direction: column;
  803. justify-content: space-between;
  804. margin-left: 16rpx;
  805. .name {
  806. font-size: 26rpx;
  807. }
  808. .price {
  809. font-size: 30rpx;
  810. color: var(--view-priceColor);
  811. }
  812. }
  813. }
  814. }
  815. &.right-box {
  816. flex-direction: row-reverse;
  817. .msg-box {
  818. margin-left: 0;
  819. margin-right: 22rpx;
  820. background-color: #9cec60;
  821. }
  822. .img-box {
  823. margin-left: 0;
  824. margin-right: 22rpx;
  825. }
  826. .product-box {
  827. margin-left: 0;
  828. margin-right: 22rpx;
  829. }
  830. .order-box {
  831. margin-left: 0;
  832. margin-right: 22rpx;
  833. }
  834. }
  835. .em {
  836. margin: 0;
  837. }
  838. }
  839. }
  840. .broadcast-details_box {
  841. display: flex;
  842. background: #fff;
  843. border-radius: 6px;
  844. padding: 24rpx;
  845. }
  846. .broadcast_details_img {
  847. width: 140rpx;
  848. height: 140rpx;
  849. border-radius: 8px;
  850. overflow: hidden;
  851. position: relative;
  852. }
  853. .broadcast_details_img .goods-img {
  854. width: 100%;
  855. height: 100%;
  856. }
  857. .broadcast_details_picBox {
  858. width: 75%;
  859. margin-left: 24rpx;
  860. .bottom {
  861. margin-top: 12rpx;
  862. }
  863. }
  864. .broadcast_details_tit {
  865. font-size: 28rpx;
  866. color: #333333;
  867. height: 76rpx;
  868. font-weight: 800;
  869. overflow: hidden;
  870. text-overflow: ellipsis;
  871. display: -webkit-box;
  872. -webkit-line-clamp: 2;
  873. -webkit-box-orient: vertical;
  874. text-align: left !important;
  875. }
  876. .broadcast_details_pic {
  877. font-size: 36rpx;
  878. color: var(--view-priceColor);
  879. text-align: left;
  880. }
  881. .broadcast_details_pic_num {
  882. text-decoration: line-through;
  883. font-size: 28rpx;
  884. color: rgba(0, 0, 0, 0.5);
  885. margin-left: 0.1rem;
  886. }
  887. .broadcast_details_btn {
  888. width: 130rpx;
  889. height: 50rpx;
  890. background: var(--view-theme);
  891. opacity: 1;
  892. border-radius: 125rpx;
  893. color: #fff;
  894. font-size: 24rpx;
  895. text-align: center;
  896. line-height: 50rpx;
  897. }
  898. .broadcast-details_num {
  899. width: 100%;
  900. height: 80rpx;
  901. line-height: 80rpx;
  902. color: #000000;
  903. font-size: 26rpx;
  904. display: flex;
  905. justify-content: space-between;
  906. background: #fff;
  907. border-bottom: 1px dashed rgba(0, 0, 0, 0.2);
  908. padding: 0 24rpx;
  909. }
  910. .day-box {
  911. font-size: 24rpx;
  912. color: #999;
  913. text-align: center;
  914. margin-bottom: 36rpx;
  915. }
  916. .msgItem {
  917. &:first-child {
  918. .day-box {
  919. padding-top: 30rpx;
  920. }
  921. }
  922. }
  923. </style>
  924. <style>
  925. .em {
  926. display: inline-block;
  927. width: 50rpx;
  928. height: 50rpx;
  929. margin: 40rpx 0 0 50rpx;
  930. /* background-size: 4100%!important;
  931. background-position: 2.5% 62.5%!important; */
  932. }
  933. .emoji-outer {
  934. position: absolute;
  935. right: 50rpx;
  936. bottom: 30rpx;
  937. width: 50rpx;
  938. height: 50rpx;
  939. }
  940. </style>