chat.vue 23 KB

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