chat.vue 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500
  1. <template>
  2. <div class="body">
  3. <div class="chat-box">
  4. <!-- 消息盒子左侧栏 -->
  5. <div class="chat-box-left">
  6. <!-- 左侧顶部 -->
  7. <div class="user-name">
  8. <img src="../assets/images/chat/userImg.jpg" v-if="!userImg" />
  9. <img :src="userImg" v-if="userImg" />
  10. <span v-if="!userName" class="user-name1">{{
  11. $t('chat.userName')
  12. }}</span>
  13. <span v-else class="user-name1">{{ userName }}</span>
  14. </div>
  15. <!-- 左侧商家栏 -->
  16. <!-- v-infinite-scroll="scrollShopList"
  17. infinite-scroll-disabled="shopDisabled" -->
  18. <ul class="shop-list"
  19. >
  20. <li
  21. :class="['shop-item',(item.shopId == selectedF && item.chatType == chatType)?'changeUser':'',item.message? 'newMessage':'']"
  22. v-for="(item, index) in shopList"
  23. :key="index"
  24. @click="changeImContent(item.shopId, item.chatType , index, item)"
  25. >
  26. <img
  27. :src="item.pic ? item.pic : chatImg "
  28. class="shop-icon"
  29. />
  30. <div class="shop-info">
  31. <span class="shop-info-name">{{ item.friendName }}</span>
  32. <span
  33. class="shop-info-icon"
  34. :style="{ width: $t('language') === 'en' ? '50px' : '' }"
  35. v-if="item.chatType === 1"
  36. >{{ $t('chat.official') }}</span
  37. >
  38. <span
  39. class="shop-info-icon"
  40. :style="{
  41. width: $t('language') === 'en' ? '50px' : '',
  42. backgroundColor: '#FFC267',
  43. }"
  44. v-if="item.chatType !== 1 && item.shopId !== 1"
  45. >{{ $t('index.shop') }}</span
  46. >
  47. <span
  48. class="shop-info-icon"
  49. :style="{
  50. width: $t('language') === 'en' ? '50px' : '',
  51. backgroundColor: '#FFC267',
  52. }"
  53. v-if="item.chatType !== 1 && item.shopId === 1"
  54. >{{ $t('prodDetail.selfEmployed') }}</span
  55. >
  56. </div>
  57. </li>
  58. </ul>
  59. </div>
  60. <!-- 消息盒子右侧信息回复栏 -->
  61. <div class="chat-box-right">
  62. <div class="shop-name-tittle" v-if="shopList[totalUserUnreadsIndex]">{{ chatType==1?$t('chat.mallCustomerService'):shopName}}
  63. <span :class="['shopStatus', shopList[totalUserUnreadsIndex].isOnline?'in':'out']">{{shopList[totalUserUnreadsIndex].isOnline?$t('chat.onLine'):$t('chat.offLine')}}</span></div>
  64. <div class="im-box">
  65. <div class="im-main">
  66. <div class="chat-main-form">
  67. <div class="display-infor">
  68. <div
  69. class="more"
  70. @click="moreInfo()"
  71. v-if="moreMess && chatMessagePages > 1"
  72. >
  73. {{ $t('chat.clickToLoadMore') }}
  74. </div>
  75. <div class="more" v-if="!moreMess && chatMessagePages > 1">
  76. {{ $t('chat.noMore') }}
  77. </div>
  78. <div class="row" v-for="(row, index) in msgList" :key="index">
  79. <!-- 用户消息 -->
  80. <div class="topTime" >{{ row.timeStr }}</div>
  81. <!-- 自己发出的消息 -->
  82. <div class="my" v-if="row.source == 2">
  83. <!-- 左-消息 -->
  84. <div class="left">
  85. <div class="username">
  86. <div class="name">{{ row.userName }}</div>
  87. </div>
  88. <div class="message-box">
  89. <div class="unread" v-if="row.employeeUnread">{{ $t('chat.read') }}</div>
  90. <div class="unread" v-if="!row.employeeUnread">
  91. {{ $t('chat.unRead') }}
  92. </div>
  93. </div>
  94. <!-- 文字消息 -->
  95. <div v-if="row.type == 0 && !row.prodInfo" class="bubble">
  96. <span>{{ row.content }}</span>
  97. </div>
  98. <!-- 图片消息 -->
  99. <div
  100. v-if="row.type == 1 && !row.prodInfo"
  101. class="bubble"
  102. @tap="showPic(row.content)"
  103. >
  104. <!-- <img :src="row.content" class="longimage" @click="onBigImg(row.content)"/> -->
  105. <el-image :src="row.content" class="longimage" :preview-src-list="[row.content]"></el-image>
  106. </div>
  107. <!-- 商品链接 -->
  108. <div
  109. class="prod-link"
  110. v-if="row.prodInfo"
  111. >
  112. <div class="prod-number" v-if="row.prodInfo.orderFlag" @click="toProdDetail(row.prodInfo,1)">{{ $t('orderNumberT') }}:{{row.prodInfo.orderNumber}}</div>
  113. <div class="link-prod prod-no" @click="toProdDetail(row.prodInfo,0,row.prodInfo.orderType)">
  114. <img :src="row.prodInfo.imgs" alt="" />
  115. <div class="link-detail">
  116. <div class="prod-name">
  117. {{ row.prodInfo.prodName }}
  118. </div>
  119. <div class="prod-price">
  120. <!-- <span class= 'payment-amount' v-if="row.prodInfo.orderFlag">{{$t('chat.paymentAmount')+':'}}{{ row.prodInfo.actualTotal?'¥'+row.prodInfo.actualTotal:'' }}<span v-if="row.prodInfo.useScore">+{{row.prodInfo.useScore}} {{$t('prodDetail.points')}}</span></span> -->
  121. <span>{{row.prodInfo.actualTotal?'¥':''}}{{row.prodInfo.actualTotal?row.prodInfo.actualTotal:''}}{{(row.prodInfo.actualTotal && row.prodInfo.useScore)?'+':''}}<span v-if="row.prodInfo.useScore">{{row.prodInfo.useScore}} {{$t('prodDetail.points')}}</span></span>
  122. <!-- <span class= 'prod-status' v-if="row.prodInfo.orderFlag">
  123. {{
  124. [
  125. '',
  126. $t('obligation'),
  127. $t('pendingDelivery'),
  128. $t('pendingReceipt'),
  129. $t('pendinEvaluation'),
  130. $t('completed'),
  131. $t('canceled'),
  132. $t('grouping')
  133. ][row.prodInfo.status]
  134. }}
  135. </span> -->
  136. </div>
  137. </div>
  138. </div>
  139. </div>
  140. </div>
  141. <!-- 右-头像 -->
  142. <div class="right">
  143. <img
  144. src="../assets/images/chat/userImg.jpg"
  145. class="avatar"
  146. v-if="!row.userHeadUrl"
  147. />
  148. <img :src="row.userHeadUrl" class="avatar" v-else />
  149. </div>
  150. </div>
  151. <!-- 别人发出的消息 -->
  152. <div
  153. class="other"
  154. v-if="
  155. (row.source == 0 || row.source == 1) &&
  156. row.forwardCode != 1
  157. "
  158. >
  159. <!-- 左-头像 -->
  160. <div class="left">
  161. <img :src="row.shopLogo?row.shopLogo:chatImg" class="avatar" />
  162. </div>
  163. <!-- 右-用户名称-时间-消息 -->
  164. <div class="right">
  165. <div class="username">
  166. <div class="name">{{ row.shopName }}</div>
  167. </div>
  168. <!-- 文字消息 -->
  169. <div v-if="row.type == 0" class="bubble">
  170. <span>{{ row.content }}</span>
  171. </div>
  172. <!-- 图片消息 -->
  173. <div
  174. v-if="row.type == 1"
  175. class="bubble"
  176. @tap="showPic(row.content)"
  177. >
  178. <!-- <img
  179. :src="row.content"
  180. class="longimage"
  181. @click="onBigImg(row.content)"
  182. /> -->
  183. <el-image :src="row.content" class="longimage" :preview-src-list="[row.content]"></el-image>
  184. </div>
  185. </div>
  186. </div>
  187. <!-- 发送链接 -->
  188. <div class="link-box" v-if="row.source == 3">
  189. <div class="prod-number" v-if="row.prodInfo.orderFlag" @click="toProdDetail(row.prodInfo,1)">{{ $t('chat.orderNumber') }}:{{row.prodInfo.orderNumber}}</div>
  190. <div
  191. class="link-prod"
  192. @click="toProdDetail(row.prodInfo,0,row.prodInfo.orderType)"
  193. >
  194. <img :src="row.prodInfo.imgs" alt="" />
  195. <div class="link-detail">
  196. <div class="prod-name">{{ row.prodInfo.prodName }}</div>
  197. <span>{{row.prodInfo.actualTotal?'¥':''}}{{row.prodInfo.actualTotal?row.prodInfo.actualTotal:''}}{{(row.prodInfo.actualTotal && row.prodInfo.useScore)?'+':''}}<span v-if="row.prodInfo.useScore">{{row.prodInfo.useScore}} {{$t('prodDetail.points')}}</span></span>
  198. </div>
  199. </div>
  200. <div class="link-send" @click="sendText(2)">
  201. {{ $t('chat.sendLink') }} <i class="link-send-right"></i>
  202. </div>
  203. </div>
  204. <!-- 系统提示: 客服接入/转接、客户离线、用户状态异常-->
  205. <div
  206. class="sys-tips"
  207. v-if="(row.source == -1 && row.tipsType) || row.type == 2"
  208. >
  209. <span class="tips-content" v-if="row.type == 2">{{
  210. row.content
  211. }}</span>
  212. <span class="tips-content" v-else>{{
  213. row.tipsType == 1
  214. ? $t('chat.customerOffline')
  215. : row.tipsType == 2
  216. ? $t('chat.loginOtherSide')
  217. : ''
  218. }}</span>
  219. </div>
  220. </div>
  221. </div>
  222. <div class="reply">
  223. <div class="upload"></div>
  224. <label for="iii" class="imgUp"
  225. ><a class="upload" style="cursor: pointer"></a
  226. ></label>
  227. <input
  228. accept="image/png, image/jpeg"
  229. type="file"
  230. ref="file"
  231. @change="toolEvent"
  232. class="search-btnn"
  233. id="iii"
  234. />
  235. <div class="reply-area">
  236. <textarea
  237. name=""
  238. id=""
  239. cols="20"
  240. rows="4"
  241. @keydown="messageSendlisten($event)"
  242. v-model="textMsg"
  243. >
  244. </textarea>
  245. </div>
  246. <div class="send" @click="sendText(1)">
  247. {{ $t('chat.send') }}
  248. </div>
  249. </div>
  250. <!-- 未读消息提醒-->
  251. <!-- <div v-if="">
  252. <div class="un-read-tips" v-if="shopList[totalUserUnreadsIndex].unread>0">
  253. <img src="../assets/images/chat/unread-up.png" class="un-read-icon"/>
  254. {{`${shopList[totalUserUnreadsIndex].unread}条新消息`}}
  255. </div>
  256. </div> -->
  257. </div>
  258. </div>
  259. <!-- 右侧我的浏览和我的订单栏 -->
  260. <div class="order-column">
  261. <div class="tab-switch">
  262. <span
  263. :class="['inquiry', tabIndex ? '' : 'active']"
  264. @click="tabSwitch(0)"
  265. >{{ $t('chat.recentlyViewed') }}</span
  266. >
  267. <span
  268. :class="['my-order', !tabIndex ? '' : 'active']"
  269. @click="tabSwitch(1)"
  270. >{{ $t('chat.myOrders') }}</span
  271. >
  272. </div>
  273. <!-- 最近浏览 -->
  274. <!-- <div class="browse" v-show="!tabIndex">
  275. <div
  276. class="text"
  277. :style="{ width: $t('language') === 'en' ? '115px' : '' }"
  278. >
  279. {{ $t('chat.recentlyViewed') }}
  280. </div>
  281. </div> -->
  282. <ul class="recent-list" v-show="!tabIndex">
  283. <li class="prod-item" v-for="(recent,index) in reBrowseList" :key="index">
  284. <img
  285. :src="recent.pic"
  286. class="prod-img"
  287. />
  288. <div class="prod-detail">
  289. <div class="prod-name" @click="toProdDetail(recent)">
  290. {{recent.prodName}}
  291. </div>
  292. <div class="prod-b">
  293. <div class="prod-price">¥{{recent.price}}</div>
  294. <div class="prod-send" @click="sendText(3, recent)">{{ $t('chat.send') }}{{ $t('products') }}</div>
  295. </div>
  296. </div>
  297. </li>
  298. <div v-if="!noMoreRe" class="bottom-tips">{{ $t('chat.noRecord') }}</div>
  299. </ul>
  300. <!-- 我的订单 -->
  301. <ul
  302. class="order-list"
  303. v-infinite-scroll="scrollOrderList"
  304. infinite-scroll-disabled="disabled"
  305. v-show="tabIndex"
  306. >
  307. <li
  308. class="prod-item botl"
  309. v-for="(item, index) in orderList"
  310. :key="index"
  311. :style="{
  312. paddingBottom: item.orderItemDtos.length <= 1 ? '18px' : '0',
  313. }"
  314. >
  315. <div class="order-number">
  316. <span class="number"
  317. @click="toProdDetail(item,1)"
  318. >{{ $t('chat.orderNumber') }}: {{ item.orderNumber }}</span
  319. >
  320. <!-- <div class="send-number" @click="sendText(4,item.orderItemDtos[0],item.status,item.actualTotal)">
  321. {{ $t('chat.sendOrder') }}
  322. </div> -->
  323. <!-- <span class="time">时 间: {{ 1342585896 }}</span> -->
  324. </div>
  325. <div
  326. class="order-box"
  327. v-for="(prod, index) in item.orderItemDtos"
  328. :key="index"
  329. :style="{
  330. paddingBottom: item.orderItemDtos.length > 1 ? '20px' : '0',
  331. }"
  332. >
  333. <img v-if="prod.pic" :src="prod.pic" class="prod-img" />
  334. <img v-else src="~/assets/img/def.png" alt />
  335. <div class="prod-detail">
  336. <div class="prod-name" >{{ prod.prodName }}</div>
  337. <div class="prod-b">
  338. <div class="prod-price">¥{{ prod.price }}</div>
  339. <div class="prod-send" @click="sendText(4, prod, item.orderType,item.actualTotal)">
  340. {{ $t('chat.send') }}{{ $t('products') }}
  341. </div>
  342. </div>
  343. </div>
  344. </div>
  345. </li>
  346. <p v-if="loading" class="bottom-tips">
  347. {{ $t('chat.loading') }}...
  348. </p>
  349. <p v-if="noMore" class="bottom-tips">{{ $t('chat.noMore') }}</p>
  350. </ul>
  351. </div>
  352. </div>
  353. </div>
  354. </div>
  355. <!-- 重新登录提示弹窗 -->
  356. <div class="login-baBox" v-if="isPopup">
  357. <div class="popup-box">
  358. <div class="tit">
  359. <div class="text">{{ $t('tips') }}</div>
  360. <div class="close" @click="closePopup()"></div>
  361. </div>
  362. <div class="con">
  363. <div class="tip">
  364. <div class="tip-info">
  365. <div class="result">{{ $t('chat.pleaseLoginAgain') }}</div>
  366. <div class="btns" style="justify-content: center">
  367. <a href="JavaScript:;" class="btn-r" @click="goToLogin()">{{
  368. $t('register.goToLogin')
  369. }}</a>
  370. </div>
  371. </div>
  372. </div>
  373. </div>
  374. </div>
  375. </div>
  376. <!-- 放大图片栏 -->
  377. <!--   <div class="img-layer" v-if="bigImg" @click="bigImg=null">
  378.   <div class="img" v-if="bigImg">
  379.     <img :src="bigImg" mode="widthFix" />
  380.   </div>
  381. </div> -->
  382. </div>
  383. </template>
  384. <script>
  385. import util from '../plugins/util'
  386. import config from '../plugins/config'
  387. import Cookie from 'js-cookie'
  388. import { Base64 } from 'js-base64'
  389. export default {
  390. data() {
  391. return {
  392. tabIndex: 0, // 0 正在浏览 1我的订单
  393. centerDialogVisible: true,
  394. userName: null,
  395. shopName: null,
  396. userImg: null,
  397. userId: this.$store.state.user.userId,
  398. bigImg: null, //选择要放大的图片
  399. selectedF: null, //选中的店家
  400. isPopup: false, // 显示登录弹窗
  401. picDomain: config.picDomain,
  402. img: require('../assets/images/chat/upload.png'),
  403. chatImg: require('../assets/images/chat/imAvatar.png'), //官方头像
  404. chatType: null, // 1是平台 2 是商家 发送消息的对象
  405. shopList: [],
  406. orderList: [],
  407. reBrowseList: [], //最近浏览列表
  408. selectFileobj:null, // 上传图片对象
  409. merchants: null, //左侧商家栏
  410. shopCurrent: 1, //左侧商家联系栏页吗数
  411. shopPages: 1, //左侧商家联系栏
  412. orderCurrent: 1, //我的订单当前页
  413. orderPages: 1, //我的订单
  414. chatMessageCurrent: 1, //主体聊天信息页码
  415. totalUserUnreads: [],// 有多少条未读新消息
  416. totalUserUnreadsIndex: 0, //选中的店家下标
  417. chatMessagePages: null,
  418. moreMess: null, //主体聊天信息判断有无更多
  419. currentShopId: null, //商家id
  420. isOnline: false,//
  421. prodInfo: null, //商品详情
  422. size: 10, //我的订单 每页显示多少条
  423. loading: false,
  424. shopLoading: false, //左侧商家联系栏是否禁止滚动判断
  425. imSocketTask: null,
  426. textMsg: null, //用户输入内容
  427. conversations: [],
  428. msgList: [], //聊天记录
  429. messageInfo: {}, // 商家发送的文本消息
  430. lockReconnect: false, //websock 是否是链接状态
  431. userSend: false,
  432. userRead: true, // 用户的已读未读判断
  433. plooTime: 0
  434. }
  435. },
  436. created() {},
  437. mounted() {
  438. if(!Cookie.get('token') || !this.$store.state.user.nickName){
  439. this.isPopup = true
  440. return
  441. }
  442. this.userName = this.$store.state.user.nickName
  443. //json格式转换,应对图片为null时出现的判断失效
  444. this.userImg = this.$store.state.user.userAvatar
  445. if (this.$route.query.shopId == 'null') {
  446. this.currentShopId = 1
  447. } else {
  448. this.currentShopId = Number(this.$route.query.shopId)
  449. }
  450. if (this.$route.query.chatType) {
  451. this.chatType = this.$route.query.chatType
  452. } else {
  453. this.chatType = 2
  454. }
  455. this.getConversations() //左侧商家栏信息
  456. document.title = this.$t('chat.onlineCustomerService')
  457. },
  458. computed: {
  459. noMore() {
  460. return this.orderCurrent >= this.orderPages
  461. },
  462. noMoreRe() {
  463. return this.reBrowseList.length>0
  464. },
  465. shopDisabled () {
  466. return this.shopLoading
  467. },
  468. disabled() {
  469. return this.loading || this.noMore
  470. }
  471. },
  472. methods: {
  473. /**
  474. * 最近浏览我的订单tab切换
  475. */
  476. tabSwitch(status) {
  477. this.tabIndex = status
  478. if (status == 1) {
  479. this.getOrderList() //我的订单
  480. }
  481. },
  482. /**
  483. * 隐藏登录弹窗
  484. */
  485. hideLoginPop() {
  486. this.showLogin = false
  487. },
  488. //开启webscokt
  489. openWs() {
  490. var ths = this
  491. this.imSocketTask = new WebSocket(
  492. config.imWsPath + '/im/websocket/user/' + Base64.encode(Cookie.get('token')) + '/' + this.userId
  493. )
  494. ths.imSocketTask.onopen = function (openRes) {
  495. heartCheck.reset().start() // 成功建立连接后,重置心跳检测
  496. ths.lockReconnect = true
  497. ths.getMsgItems()
  498. ths.getOnlineStatus()
  499. }
  500. this.imSocketTask.onmessage = function (res) {
  501. heartCheck.reset().start() // 收到信息重置心跳检测
  502. let result = JSON.parse(res.data)
  503. if (result.code !== '00000') {
  504. result.code = Number(result.code)
  505. }
  506. // 聊天记录
  507. if (result.code === 2) {
  508. let msgIds = []
  509. let index = null
  510. if (result && result.data.pages) {
  511. result.data.records = result.data.records.reverse()
  512. if (ths.shopList.length) {
  513. ths.shopList.some((item,indexx)=>{
  514. if ( item.userId == result.data.records[0].userId ) {
  515. index = indexx
  516. return
  517. }
  518. })
  519. }
  520. // 进行是否是商品链接的判断
  521. result.data.records.forEach((item) => {
  522. let a = ths.isJSON(item.content)
  523. if (a && JSON.parse(item.content) instanceof Object) {
  524. item.prodInfo = JSON.parse(item.content)
  525. }
  526. item.timeStr = util.tsToDate(item.timestamp, 'M月D日 h:m')
  527. if (item.type === 1 && !a) {
  528. item.content =
  529. item.content.indexOf(config.picDomain) === 0
  530. ? item.content
  531. : config.picDomain + item.content
  532. }
  533. if (!item.userUnread) {
  534. ths.shopList[index].unread = ths.shopList[index].unread - 1
  535. msgIds.push(item.itemId)
  536. }
  537. })
  538. let readed = {
  539. read: 1,
  540. msgIds,
  541. toId: ths.currentShopId,
  542. sendType: ths.chatType
  543. }
  544. ths.imSocketTask.send(JSON.stringify(readed))
  545. result.data.records.reduce((prev, cur) => {
  546. // 将时间更换为某某月某某日 要是是当天即去掉月日
  547. let now = util.tsToDate(prev.timestamp, 'M月D日 h:m')
  548. let next = util.tsToDate(cur.timestamp, 'M月D日 h:m')
  549. if (
  550. now.slice(0, now.indexOf(' ')) ===
  551. next.slice(0, next.indexOf(' '))
  552. ) {
  553. cur.timeStr = util.tsToDate(cur.timestamp, 'h:m')
  554. }
  555. // 历史记录进行时间段显示判断
  556. if (result.data.records.length > 2) {
  557. let timeFlag = ths.timeBeApart(prev.timestamp, cur.timestamp)
  558. if (timeFlag) {
  559. delete cur.timeStr
  560. }
  561. }
  562. return cur
  563. })
  564. // 新的商家新的聊天记录
  565. if (ths.chatMessageCurrent === 1) {
  566. ths.msgList = result.data.records
  567. ths.chatMessagePages = result.data.pages
  568. ths.scrollToBottom()
  569. }
  570. // 查看更多的消息的逻辑判断
  571. if (ths.chatMessageCurrent !== 1) {
  572. result.data.records = result.data.records.reverse()
  573. // 数组反转拼接
  574. result.data.records.forEach((item) => {
  575. ths.msgList.unshift(item)
  576. })
  577. }
  578. // 有无查看更多
  579. if (result.data.pages > 1) {
  580. ths.moreMess = true
  581. } else {
  582. ths.moreMess = false
  583. }
  584. ths.chatMessagePages = result.data.pages
  585. } else {
  586. //新的商家联系人
  587. ths.msgList = []
  588. ths.chatMessagePages = 0
  589. }
  590. // 进行商品订单链接的判断
  591. if (ths.$route.query.prodId && ths.currentShopId == ths.$route.query.shopId ) {
  592. ths.sendProd(ths.$route.query.prodId,1)
  593. }
  594. if (ths.$route.query.orderNumber && ths.currentShopId == ths.$route.query.shopId ) {
  595. ths.sendProd(ths.$route.query.orderNumber,2)
  596. }
  597. ths.selectedF = ths.currentShopId
  598. }
  599. /**
  600. * 未读信息转成已读
  601. */
  602. if (result.code === 5) {
  603. // if (ths.userSend) {
  604. // ths.userRead = false
  605. // ths.userSend = false
  606. // let msgItem = ths.messageInfo
  607. // ths.msgList.push(msgItem)
  608. // ths.lastTime = msgItem.timeStr
  609. // }
  610. ths.msgList.forEach((item) => {
  611. ths.$set(item, 'employeeUnread', 1)
  612. })
  613. ths.scrollToBottom()
  614. }
  615. if (result.code == 10 || result.code == 11 || result.code == 12) {
  616. ths.$confirm(ths.$i18n.t('chat.reConsultation'), {
  617. confirmButtonText: ths.$i18n.t('chat.reconsultationBtn'),
  618. cancelButtonText: ths.$i18n.t('chat.close')
  619. }).then(() => {
  620. location.reload()
  621. }).catch(() => {
  622. window.close()
  623. })
  624. return
  625. }
  626. if (result.code === 16) {
  627. ths.shopList.forEach(item=>{
  628. if (item.chatType === result.data.chatType && item.shopId === result.data.shopId ) {
  629. item.isOnline = result.data.onlineOrOffline
  630. }
  631. })
  632. }
  633. if (!result.data) {
  634. return
  635. }
  636. // 新的聊天信息
  637. if (result.code === '00000' || result.code === 4) {
  638. let index = null
  639. // 进行未读消息的加减
  640. if (ths.shopList.length && result.code !== 4) {
  641. ths.shopList.some((item, indexx) => {
  642. console.log(item.userId, result.data.userId, 'result.data.userId', item.userId === result.data.userId)
  643. if (item.userId === result.data.userId) {
  644. index = indexx
  645. }
  646. })
  647. if (index != null && ths.selectedF !== result.data.userId && result.data.userUnread) {
  648. ths.shopList[index].unread = Number(ths.shopList[index].unread) + 1
  649. }
  650. }
  651. if (ths.msgList.length) {
  652. // 时间转换
  653. let prevTime = util.tsToDate(
  654. ths.msgList[ths.msgList.length - 1].timestamp,
  655. 'M月D日 h:m'
  656. )
  657. let nowTime = util.tsToDate(result.data.timestamp, 'M月D日 h:m')
  658. if (
  659. prevTime.slice(0, prevTime.indexOf(' ')) ===
  660. nowTime.slice(0, nowTime.indexOf(' '))
  661. ) {
  662. result.data.timeStr = util.tsToDate(new Date().getTime(), 'h:m')
  663. } else {
  664. result.data.timeStr = util.tsToDate(
  665. new Date().getTime(),
  666. 'M月D日 h:m'
  667. )
  668. }
  669. }
  670. if (result.data.shopId === Number(ths.currentShopId)){
  671. let readed = {
  672. read: 1,
  673. msgIds: [result.data.itemId],
  674. toId: ths.currentShopId,
  675. sendType: ths.chatType,
  676. readNoticeEmployeeId:result.data.employeeId
  677. }
  678. ths.imSocketTask.send(JSON.stringify(readed))
  679. }
  680. ths.changeFriendsWhenMsg(result.data)
  681. if (result.data.shopId === Number(ths.currentShopId) && result.data.chatType === Number(ths.chatType)) {
  682. ths.pushMsgItem(1, result.data)
  683. }
  684. }
  685. }
  686. // 心跳检测, 每隔一段时间检测连接状态,如果处于连接中,就向server端主动发送消息,来重置server端与客户端的最大连接时间,如果已经断开了,发起重连。
  687. var heartCheck = {
  688. timeout: 19000, // 19s发一次心跳,比server端设置的连接时间稍微小一点,在接近断开的情况下以通信的方式去重置连接时间。 尽量一个小时发送三次
  689. serverTimeoutObj: null,
  690. reset: function () {
  691. clearTimeout(this.serverTimeoutObj)
  692. return this
  693. },
  694. start: function () {
  695. this.serverTimeoutObj = setTimeout(function () {
  696. if (!ths.imSocketTask) {
  697. return
  698. }
  699. if (ths.imSocketTask.readyState == 1) {
  700. console.log('连接状态,发送消息保持连接')
  701. ths.getOnlineStatus()
  702. ths.imSocketTask.send(
  703. JSON.stringify({
  704. sendType: ths.chatType,
  705. content: 'HEART_BEAT',
  706. msgType: 0,
  707. toId: ths.currentShopId,
  708. })
  709. )
  710. heartCheck.reset().start() // 如果获取到消息,说明连接是正常的,重置心跳检测
  711. } else {
  712. ths.imSocketTask.close()
  713. ths.imSocketTask = null
  714. ths.lockReconnect = false
  715. // ths.$message.error(ths.$i18n.t('chat.sorryYouHaveBeenDisconnected'))
  716. console.log('断开状态,尝试重连')
  717. ths.openWs()
  718. }
  719. }, this.timeout)
  720. },
  721. }
  722. this.imSocketTask.onclose = (res) => {
  723. if (this.plooTime < 3) {
  724. this.plooTime++
  725. if(this.lockReconnect) return;
  726. this.lockReconnect = true;
  727. setTimeout(()=>{ //没连接上会一直重连,设置延迟避免请求过多
  728. this.openWs()
  729. this.lockReconnect = false;
  730. }, 2000);
  731. } else {
  732. this.$confirm(ths.$i18n.t('chat.connetBroken'), ths.$i18n.t('chat.tips'), {
  733. confirmButtonText: ths.$i18n.t('chat.confirm'),
  734. cancelButtonText: ths.$i18n.t('chat.cancel'),
  735. type: 'warning'
  736. }).then(() => {
  737. location.reload()
  738. }).catch(() => {
  739. })
  740. }
  741. }
  742. },
  743. // websock断线重连
  744. reconnect() {
  745. if(this.lockReconnect) return;
  746. this.lockReconnect = true;
  747. setTimeout(()=>{ //没连接上会一直重连,设置延迟避免请求过多
  748. this.openWs()
  749. this.lockReconnect = false;
  750. }, 2000);
  751. },
  752. /**
  753. * 获取左侧商家栏信息
  754. */
  755. getConversations() {
  756. this.$axios
  757. .post('/p/user/conversations?current=' + this.shopCurrent + '&size=20')
  758. .then(({ data }) => {
  759. if (data.records && data.records.length) {
  760. data.records.forEach((item, index) => {
  761. // this.totalUserUnreads.push({
  762. // shopId:item.shopId,
  763. // unread:item.unread
  764. // })
  765. let a = this.isJSON(item.latestMsg)
  766. if (item.type === 1) {
  767. item.latestMsg = '[' + this.$i18n.t('publics.image') + ']'
  768. } else if (a && JSON.parse(item.latestMsg) instanceof Object) {
  769. item.latestMsg = '[' + this.$i18n.t('publics.image') + ']'
  770. }
  771. //判读商家有无在记录栏里
  772. if (item.shopId == this.currentShopId && item.chatType == this.chatType) {
  773. this.shopName = item.friendName
  774. this.isOnline = item.isOnline
  775. data.records.splice(index, 1)
  776. }
  777. })
  778. //sort按时间正序排序 最新的消息在前面
  779. data.records.sort(function(a,b){
  780. return b.timestamp - a.timestamp
  781. });
  782. }
  783. if (this.shopList.length >= 1) {
  784. this.shopList.forEach(item => {
  785. data.records = data.records.filter(itemInde => {
  786. return item.shopId !== itemInde.shopId && item.chatType === itemInde.chatType
  787. })
  788. }) // 过滤左侧已存在的店家
  789. this.shopList = this.shopList.concat(data.records)
  790. } else {
  791. this.shopList = data.records
  792. this.selectedF = this.currentShopId
  793. console.log(data.records,'sho');
  794. this.openWs()
  795. }
  796. this.shopPages = data.pages
  797. if(data.pages==1 || data.pages==0){
  798. this.getNewShop()
  799. }
  800. // this.getOnlineStatus()
  801. })
  802. },
  803. // 添加新的商家栏到左侧
  804. getNewShop(){
  805. if(this.$route.query.chatType==1){
  806. let data={
  807. shopId:1,
  808. chatType:1,
  809. unread:0,
  810. isOnline: this.isOnline,
  811. friendName:this.shopName?this.shopName:'admin'
  812. }
  813. this.shopList.unshift(data)
  814. }else{
  815. this.$axios
  816. .get('/shop/headInfo', {
  817. params: {
  818. shopId: this.currentShopId,
  819. },
  820. })
  821. .then(({ data }) => {
  822. data.pic = data.shopLogo
  823. data.chatType = 2
  824. data.unread = 0
  825. data.friendName = data.shopName
  826. data.isOnline = this.isOnline
  827. this.shopName = data.shopName
  828. this.shopList.unshift(data)
  829. })
  830. }
  831. this.getRecentBrowse()
  832. },
  833. /**
  834. * 有消息过来的时候,改变左边历史联系人列表(先删除消息对应联系人的信息,再将联系人放到第一个)
  835. */
  836. changeFriendsWhenMsg(msgItem) {
  837. // 消息内容
  838. let msgContent = ''
  839. // 图片消息
  840. if (msgItem.type === 1) {
  841. msgContent = '[' + this.$i18n.t('publics.image') + ']'
  842. } else {
  843. msgContent = msgItem.content
  844. }
  845. for (var i = 0; i < this.shopList.length; i++) {
  846. var item = this.shopList[i]
  847. // 更新最新消息
  848. if (msgItem.shopId == item.shopId && msgItem.chatType == item.chatType) {
  849. item.latestMsg = msgContent
  850. item.timeStr = msgItem.timeStr
  851. this.shopName = item.friendName
  852. msgItem.unread = item.unread
  853. this.shopList.splice(i, 1)
  854. break
  855. }
  856. }
  857. // 新消息
  858. this.shopList.unshift({
  859. chatType: msgItem.chatType,
  860. pic: msgItem.shopLogo,
  861. friendName: msgItem.shopName,
  862. latestMsg: msgContent,
  863. isOnline: true,
  864. shopId: msgItem.shopId,
  865. userId: msgItem.userId,
  866. unread: msgItem.unread,
  867. message: (msgItem.shopId === this.currentShopId && msgItem.chatType === this.chatType) ? 0 : 1
  868. })
  869. },
  870. /**
  871. * 换个商家聊条
  872. */
  873. changeImContent(itemUserId, chatType, index , item) {
  874. console.log(item,'这是切换联系商家');
  875. if (this.currentShopId === itemUserId && this.chatType === chatType) {
  876. return
  877. }
  878. this.shopList[index].message = 0
  879. this.shopName = this.shopList[index].friendName
  880. this.currentShopId = itemUserId
  881. this.selectedF = itemUserId
  882. this.totalUserUnreadsIndex = index
  883. this.chatType = chatType
  884. this.shopCurrent = 1
  885. //切换商家 我的订单变更
  886. this.orderList = []
  887. this.orderCurrent = 1
  888. this.chatMessageCurrent = 1
  889. this.loading = false
  890. // 有多少条未读消息
  891. // this.totalUserUnreadsIndex = index
  892. this.tabSwitch(0)
  893. this.getOnlineStatus()
  894. let time = setTimeout(() => {
  895. this.getMsgItems()
  896. this.getRecentBrowse() //获取最近浏览商品
  897. clearTimeout(time)
  898. }, 100)
  899. },
  900. //判断是否为JSON格式
  901. isJSON(str) {
  902. if (typeof str == 'string') {
  903. try {
  904. JSON.parse(str)
  905. return true
  906. } catch (e) {
  907. return false
  908. }
  909. }
  910. },
  911. /**
  912. * 获取聊天记录
  913. */
  914. getMsgItems() {
  915. let messageInfo = {
  916. history: true,
  917. current: this.chatMessageCurrent,
  918. size: 10,
  919. sendType: this.chatType, // 1是平台 2 是商家
  920. toId: this.currentShopId,
  921. }
  922. try {
  923. this.imSocketTask.send(JSON.stringify(messageInfo))
  924. } catch (error) {
  925. this.$message({
  926. message: '连接已断开请刷新一下页面',
  927. type: 'error',
  928. duration: 1000
  929. })
  930. }
  931. },
  932. // 获取当前商家在线离线状态
  933. getOnlineStatus() {
  934. let status = {
  935. onlineOrOffline: true,
  936. sendType: this.chatType,
  937. toId: this.currentShopId
  938. }
  939. try {
  940. this.imSocketTask.send(JSON.stringify(status))
  941. } catch (error) {
  942. this.$message({
  943. message: '连接已断开请刷新一下页面',
  944. type: 'error',
  945. duration: 1000
  946. })
  947. }
  948. },
  949. /**
  950. * 获取我的订单列表
  951. */
  952. getOrderList() {
  953. let params = {
  954. current: this.orderCurrent,
  955. size: this.size,
  956. status: 0,
  957. shopId: this.chatType==1?'':this.currentShopId,
  958. orderName: '',
  959. orderTimeStatus: this.orderTimeStatus || '',
  960. orderType: '',
  961. orderNumber: '',
  962. orderMold: -1
  963. }
  964. this.$axios
  965. .get('/p/myOrder/myOrderSearch', {
  966. params,
  967. })
  968. .then(({ data }) => {
  969. data.records.forEach((order) => {
  970. order.useScoreTotal = 0
  971. order.orderItemDtos.forEach((orderItem) => {
  972. if (orderItem.useScore) {
  973. order.useScoreTotal += orderItem.useScore
  974. }
  975. orderItem.status = order.status
  976. })
  977. })
  978. if (this.orderList.length >= 1) {
  979. this.orderList = this.orderList.concat(data.records)
  980. let obj = {}
  981. this.orderList = this.orderList.reduce((cur,next) => {
  982. obj[next.orderNumber] ? "" : obj[next.orderNumber] = true && cur.push(next);
  983. return cur;
  984. },[]) //设置cur默认类型为数组,并且初始值为空的数组
  985. } else {
  986. this.orderList = data.records
  987. }
  988. this.orderPages = data.pages
  989. })
  990. },
  991. // 获取最近浏览信息
  992. getRecentBrowse(){
  993. //最近浏览功能
  994. const params = new URLSearchParams();
  995. params.append('shopId', this.currentShopId);
  996. this.$axios({
  997. method: 'post',
  998. url:'/p/user/recentBrowse',
  999. data:params
  1000. })
  1001. .then(({ data }) => {
  1002. this.reBrowseList = data
  1003. this.reBrowseList.forEach(item=>{
  1004. item.pic = this.picDomain + item.pic
  1005. })
  1006. })
  1007. },
  1008. /**
  1009. * textarea回车事件
  1010. */
  1011. messageSendlisten(event) {
  1012. if (event.keyCode === 13) {
  1013. this.sendText(1) // 发送文本
  1014. event.preventDefault() // 阻止浏览器默认换行操作
  1015. return false
  1016. }
  1017. },
  1018. /**
  1019. * 发送消息
  1020. */
  1021. sendText(type, prod, orderType, actualTotal) {
  1022. // type 1 = 发送消息 type 2 = 发送商品链接 type 3 = 右侧我的订单发送 type 4 = 发送订单号
  1023. let orderProd = null
  1024. let product = prod?JSON.parse(JSON.stringify(prod)):null //避免接下来的操作改变原数组
  1025. if (type === 1 ) {
  1026. if (this.textMsg === '' || this.textMsg.match(/^\s+$/)) {
  1027. return
  1028. }
  1029. }
  1030. if (type === 3) {
  1031. product.imgs = product.pic
  1032. product.actualTotal = product.price
  1033. // product.orderFlag = true
  1034. orderProd = JSON.stringify(product)
  1035. }
  1036. if (type === 4) {
  1037. product.imgs = product.pic
  1038. product.orderFlag = true
  1039. product.orderType = orderType
  1040. product.actualTotal = actualTotal
  1041. // product.status = status
  1042. // product.actualTotal = actualTotal
  1043. orderProd = JSON.stringify(product)
  1044. }
  1045. let messageInfo = {
  1046. toId: this.currentShopId,
  1047. content: type == 1 ? this.textMsg : JSON.stringify(this.prodInfo),
  1048. msgType: 0,
  1049. sendType: this.chatType, // 1发给平台 2发给商家
  1050. }
  1051. // 避免发送订单发送内容覆盖商品发送链接
  1052. if ( type!==2&&type!==1 ){
  1053. messageInfo.content=orderProd
  1054. }
  1055. this.userRead = true
  1056. this.userSend = true
  1057. this.addMessage(messageInfo)
  1058. this.textMsg = ''
  1059. },
  1060. /**
  1061. * @param {Object} messageInfo
  1062. * 将新发送的消息添加至页面
  1063. */
  1064. addMessage(messageInfo) {
  1065. this.userRead = true
  1066. this.userSend = true
  1067. this.imSocketTask.send(JSON.stringify(messageInfo))
  1068. if (messageInfo.msgType === 1) {
  1069. messageInfo.content = config.picDomain + messageInfo.content
  1070. }
  1071. // 发送商品链接需要由JSON格式转换为对象
  1072. let a = this.isJSON(messageInfo.content)
  1073. if (a && JSON.parse(messageInfo.content) instanceof Object) {
  1074. messageInfo.prodInfo = JSON.parse(messageInfo.content)
  1075. }
  1076. let msgItem = {
  1077. userName: this.userName,
  1078. userHeadUrl: this.userImg,
  1079. type: messageInfo.msgType,
  1080. source: 2,
  1081. timestamp: new Date().getTime(),
  1082. content: messageInfo.content,
  1083. prodInfo: messageInfo.prodInfo,
  1084. }
  1085. if (this.msgList.length) {
  1086. let prevTime = util.tsToDate(
  1087. this.msgList[this.msgList.length - 1].timestamp,
  1088. 'M月D日 h:m'
  1089. )
  1090. let nowTime = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
  1091. if (
  1092. prevTime.slice(0, prevTime.indexOf(' ')) ==
  1093. nowTime.slice(0, nowTime.indexOf(' '))
  1094. ) {
  1095. msgItem.timeStr = util.tsToDate(new Date().getTime(), 'h:m')
  1096. } else {
  1097. msgItem.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
  1098. }
  1099. let timeFlag = this.timeBeApart(this.msgList[this.msgList.length - 1].timestamp, new Date().getTime())
  1100. if (timeFlag) {
  1101. delete msgItem.timeStr
  1102. }
  1103. }
  1104. this.messageInfo = msgItem // 发送的信息存储起来,用于已读未读
  1105. msgItem.timestamp = new Date().getTime()
  1106. this.msgList.push(msgItem)
  1107. // this.lastTime = msgItem.timeStr
  1108. this.scrollToBottom()
  1109. // let time = setTimeout(() => {
  1110. // if (this.msgList.length) {
  1111. // let prevTime = util.tsToDate(
  1112. // this.msgList[this.msgList.length - 1].timestamp,
  1113. // 'M月D日 h:m'
  1114. // )
  1115. // let nowTime = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
  1116. // if (
  1117. // prevTime.slice(0, prevTime.indexOf(' ')) ==
  1118. // nowTime.slice(0, nowTime.indexOf(' '))
  1119. // ) {
  1120. // msgItem.timeStr = util.tsToDate(new Date().getTime(), 'h:m')
  1121. // } else {
  1122. // msgItem.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
  1123. // }
  1124. // }
  1125. // if ( this.userRead ) {
  1126. // this.userSend = false
  1127. // }; clearTimeout(time) }, 100)
  1128. },
  1129. /**
  1130. * 添加联系人发送过来的消息内容
  1131. */
  1132. pushMsgItem(msgList, msgItem) {
  1133. if (msgItem.type === 1) {
  1134. msgItem.content = config.picDomain + msgItem.content
  1135. }
  1136. let a = this.isJSON(msgItem.content)
  1137. if (a && JSON.parse(msgItem.content) instanceof Object) {
  1138. msgItem.prodInfo = JSON.parse(msgItem.content)
  1139. }
  1140. if (this.msgList.length) {
  1141. let prevTime = util.tsToDate(this.msgList[this.msgList.length - 1].timestamp, 'M月D日 h:m')
  1142. let nowTime = util.tsToDate(msgItem.timestamp, 'M月D日 h:m')
  1143. if (prevTime.slice(0, prevTime.indexOf(' ')) === nowTime.slice(0, nowTime.indexOf(' '))) {
  1144. msgItem.timeStr = util.tsToDate(new Date().getTime(), 'h:m')
  1145. } else {
  1146. msgItem.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
  1147. }
  1148. let timeFlag = this.timeBeApart(this.msgList[this.msgList.length - 1].timestamp, new Date().getTime())
  1149. if (timeFlag) {
  1150. delete msgItem.timeStr
  1151. }
  1152. } else {
  1153. msgItem.timeStr = this.tsToDate(new Date().getTime(), 'M月D日 h:m')
  1154. }
  1155. msgItem.timestamp = new Date().getTime()
  1156. this.msgList.push(msgItem)
  1157. this.scrollToBottom()
  1158. },
  1159. // 发送商品或订单链接
  1160. sendProd(id,type) {
  1161. // type 1 = 商品链接 type 2 = 订单链接
  1162. let prodInfo = null
  1163. this.$axios
  1164. .get(type==1?"/prod/prodInfo?prodId="+id:"/p/myOrder/orderDetail?orderNumber="+id).then(res=>{
  1165. var res = res.data
  1166. console.log(res,'这是请求来的数据');
  1167. if ( type == 1 ){
  1168. prodInfo = {
  1169. imgs: res.pic,
  1170. prodId: res.prodId,
  1171. prodName: res.prodName,
  1172. skuName: res.skuName,
  1173. price: res.price,
  1174. prodId: res.prodId,
  1175. shopId: res.shopId?res.shopId:1,
  1176. orderType: res.prodType,
  1177. actualTotal: res.price
  1178. }
  1179. } else {
  1180. let orderItem = res.orderItemDtos[0]
  1181. console.log(res.orderItemDtos.length);
  1182. prodInfo = {
  1183. imgs: orderItem.pic,
  1184. prodId: orderItem.prodId,
  1185. orderNumber: this.$route.query.orderNumber,
  1186. skuName: orderItem.skuName,
  1187. prodName: orderItem.prodName,
  1188. price: res.actualTotal,
  1189. prodId: orderItem.prodId,
  1190. shopId: orderItem.shopId?Number(orderItem.shopId):1,
  1191. orderType: res.orderType,
  1192. actualTotal:res.actualTotal,
  1193. useScore:res.orderScore,
  1194. status:res.status,
  1195. orderType: res.orderType,
  1196. orderFlag:true // 订单判断
  1197. }
  1198. }
  1199. this.prodInfo = prodInfo
  1200. let msgItem = {
  1201. source: 3, //表示产品链接
  1202. timestamp: new Date().getTime(),
  1203. toId: this.shopId,
  1204. prodInfo, //产品链接详情
  1205. msgType: 0,
  1206. sendType: this.sendType // 1发给平台 2发给商家
  1207. }
  1208. msgItem.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
  1209. this.msgList.push(msgItem)
  1210. if (this.chatMessageCurrent === 1) {
  1211. this.scrollToBottom()
  1212. }
  1213. })
  1214. },
  1215. // 发送图片
  1216. toolEvent() {
  1217. if (this.$refs['file'].files[0]) {
  1218. this.selectFileobj = this.$refs['file'].files[0]
  1219. }
  1220. if (this.selectFileobj) {
  1221. const formData = new FormData();
  1222. formData.append("file",this.selectFileobj)
  1223. this.$axios({
  1224. url: '/p/file/uploadImFile',
  1225. method: 'post',
  1226. data: formData
  1227. }).then(({ data }) => {
  1228. let messageInfo = {
  1229. toId: this.currentShopId,
  1230. content: data.filePath,
  1231. sendType: this.chatType,
  1232. msgType: 1,
  1233. }
  1234. this.$refs['file'].value = null //解决上传同一图片不显示bug
  1235. this.addMessage(messageInfo)
  1236. })
  1237. }
  1238. },
  1239. /**
  1240. * 链接点击去往商品详情
  1241. */
  1242. toProdDetail(prodInfo,type,orderType) {
  1243. // type 1 点击订单跳转 type
  1244. let routeUrl = null
  1245. if (Cookie.get('token')) {
  1246. if (type) {
  1247. console.log(1111);
  1248. routeUrl = this.$router.resolve({
  1249. path: '/order-detail?orderNumber=' + prodInfo.orderNumber
  1250. })
  1251. }
  1252. // 秒杀商品
  1253. else if (this.$route.query.seckill) {
  1254. routeUrl = this.$router.resolve({
  1255. path: '/secdetail/' + this.$route.query.seckill
  1256. })
  1257. }
  1258. // 积分商品
  1259. else if(orderType===3){
  1260. routeUrl = this.$router.resolve({
  1261. path: '/member-center/integral-det/' + prodInfo.prodId
  1262. })
  1263. }
  1264. // 普通商品
  1265. else {
  1266. routeUrl = this.$router.resolve({
  1267. path: '/detail/' + prodInfo.prodId
  1268. })
  1269. }
  1270. window.open(routeUrl.href, '_blank')
  1271. } else {
  1272. this.showLogin = true
  1273. }
  1274. },
  1275. /**
  1276. * 进行相隔时间判断
  1277. *
  1278. * true 删除显示时间
  1279. * false 保留显示时间
  1280. */
  1281. timeBeApart (uppTime, preTime) {
  1282. if (!uppTime) {
  1283. return false
  1284. }
  1285. var dateDiff = preTime - uppTime// 时间差的毫秒数
  1286. var dayDiff = Math.floor(dateDiff / (24 * 3600 * 1000))// 计算出相差天数
  1287. var leave1 = dateDiff % (24 * 3600 * 1000) // 计算天数后剩余的毫秒数
  1288. var hours = Math.floor(leave1 / (3600 * 1000))// 计算出小时数
  1289. // 计算相差分钟数
  1290. var leave2 = leave1 % (3600 * 1000) // 计算小时数后剩余的毫秒数
  1291. var minutes = Math.floor(leave2 / (60 * 1000))// 计算相差分钟数
  1292. // console.log('相差' + dayDiff + '天')
  1293. // console.log('相差' + hours + '小时')
  1294. // console.log('相差' + minutes + '分钟')
  1295. if (dayDiff >= 1 || hours >= 1 || minutes > 4) {
  1296. return false
  1297. } else {
  1298. return true
  1299. }
  1300. },
  1301. /**
  1302. * 滚动条自动到底部
  1303. */
  1304. scrollToBottom() {
  1305. this.$nextTick(() => {
  1306. let msg = document.getElementsByClassName('display-infor')[0] // 获取对象
  1307. msg.scrollTop = msg.scrollHeight // 滚动高度
  1308. })
  1309. },
  1310. /**
  1311. * 主体消息点击加载更多
  1312. */
  1313. moreInfo() {
  1314. this.chatMessageCurrent += 1
  1315. if (this.chatMessageCurrent > this.chatMessagePages) {
  1316. this.moreMess = false
  1317. } else {
  1318. this.getMsgItems()
  1319. }
  1320. },
  1321. /**
  1322. * 滚动加载订单
  1323. */
  1324. scrollOrderList() {
  1325. this.orderCurrent += 1
  1326. if (this.orderCurrent > this.orderPages) {
  1327. this.loading = true
  1328. } else {
  1329. this.getOrderList()
  1330. this.loading = false
  1331. }
  1332. },
  1333. /**
  1334. * 滚动加载左侧商家联系
  1335. */
  1336. scrollShopList() {
  1337. this.shopCurrent +=1
  1338. if (this.shopCurrent > this.shopPages) {
  1339. this.shopLoading = true
  1340. } else {
  1341. this.getConversations()
  1342. this.shopLoading = false
  1343. }
  1344. },
  1345. // 点击放大图片
  1346. // onBigImg (img) {
  1347. // this.bigImg = img
  1348. // },
  1349. /**
  1350. * 账号下线前往登录
  1351. */
  1352. goToLogin() {
  1353. Cookie.remove('token')
  1354. this.$router.push('/login')
  1355. this.isPopup = false
  1356. }
  1357. },
  1358. beforeDestroy () {
  1359. if (this.imSocketTask != null) {
  1360. this.imSocketTask.close()
  1361. }
  1362. },
  1363. }
  1364. </script>
  1365. <style scoped>
  1366. .body {
  1367. width: 100%;
  1368. height: 100vh;
  1369. background-color: #2e2f3d;
  1370. position: fixed;
  1371. }
  1372. .base {
  1373. min-height: 535px;
  1374. padding-bottom: 0rem !important;
  1375. flex-direction: column;
  1376. }
  1377. .body .chat-box {
  1378. width: 1200px;
  1379. height: 797px;
  1380. display: flex;
  1381. background: #ffffff;
  1382. opacity: 1;
  1383. margin: 61px auto 0 auto;
  1384. }
  1385. /* 左侧用户名和商家栏样式 */
  1386. .body .chat-box .chat-box-left {
  1387. width: 287px;
  1388. height: 100%;
  1389. background: #ffffff;
  1390. opacity: 1;
  1391. border-right: 1px solid #eceef0;
  1392. overflow: auto;
  1393. }
  1394. .chat-box-left .user-name {
  1395. display: flex;
  1396. width: 100%;
  1397. height: 61px;
  1398. background: #e1251b;
  1399. opacity: 1;
  1400. }
  1401. .chat-box-left .user-name1 {
  1402. overflow: hidden;
  1403. text-overflow: ellipsis;
  1404. display: -webkit-box;
  1405. /* -webkit-line-clamp: 3; */
  1406. -webkit-box-orient: vertical;
  1407. position: relative;
  1408. line-height: 1.5;
  1409. word-wrap: break-word;
  1410. word-break: break-all;
  1411. }
  1412. .chat-box-left .user-name img {
  1413. width: 43px;
  1414. height: 43px;
  1415. background: #f3f6fa;
  1416. margin: 8px 11px 8px 15px;
  1417. opacity: 1;
  1418. border-radius: 3px;
  1419. }
  1420. .chat-box-left .user-name span {
  1421. display: inline-block;
  1422. width: 187px;
  1423. overflow: hidden;
  1424. vertical-align: bottom;
  1425. line-height: 4;
  1426. font-size: 16px;
  1427. color: #fff;
  1428. font-family: Microsoft YaHei;
  1429. font-weight: 400;
  1430. overflow: hidden;
  1431. white-space: nowrap;
  1432. text-overflow: ellipsis;
  1433. }
  1434. .chat-box-left .shop-list {
  1435. height: 736px;
  1436. overflow-y: auto;
  1437. }
  1438. .chat-box-left .shop-list .shop-item {
  1439. display: flex;
  1440. align-items: center;
  1441. background-color: #f2f5f9;
  1442. cursor: pointer;
  1443. }
  1444. .chat-box-left .shop-list .shop-item:hover {
  1445. background-color: #d2e6f9;
  1446. }
  1447. .chat-box-left .shop-item img {
  1448. width: 36px;
  1449. height: 36px;
  1450. margin: 12px 12px 12px 15px;
  1451. }
  1452. .chat-box-left .shop-item .shop-info {
  1453. width: 100%;
  1454. display: flex;
  1455. justify-content: space-between;
  1456. }
  1457. .chat-box-left .shop-item .shop-info .shop-info-name {
  1458. width: 70%;
  1459. display: -webkit-box;
  1460. -webkit-box-orient: vertical;
  1461. -webkit-line-clamp: 2;
  1462. overflow: hidden;
  1463. text-overflow: ellipsis;
  1464. word-break: break-word;
  1465. word-break: break-all;
  1466. }
  1467. .chat-box-left .shop-item .shop-info .shop-info-icon {
  1468. /* width: 32px;
  1469. height: 16px; */
  1470. width: 24%;
  1471. height: 50%;
  1472. padding: 1px 2px;
  1473. text-align: center;
  1474. font-size: 12px;
  1475. font-family: Microsoft YaHei;
  1476. font-weight: 400;
  1477. line-height: 16px;
  1478. color: #ffffff;
  1479. opacity: 1;
  1480. background: #e1251b;
  1481. margin-right: 15px;
  1482. opacity: 1;
  1483. border-radius: 2px;
  1484. }
  1485. .chat-box-left .shop-item .shop-info .ye {
  1486. background-color: #ffc267;
  1487. }
  1488. /* 右侧主要信息聊天栏 */
  1489. .body .chat-box .chat-box-right {
  1490. width: 100%;
  1491. height: 100%;
  1492. }
  1493. .chat-box-right .shop-name-tittle {
  1494. line-height: 20px;
  1495. padding: 20px 0px 21px 21px;
  1496. font-size: 14px;
  1497. font-family: Microsoft YaHei;
  1498. font-weight: 400;
  1499. color: #333333;
  1500. border-bottom: 1px solid #ebedf0;
  1501. }
  1502. .shop-name-tittle .shopStatus {
  1503. margin: 5px;
  1504. }
  1505. .shop-name-tittle .in {
  1506. color: red
  1507. }
  1508. .shop-name-tittle .out {
  1509. color: #999
  1510. }
  1511. .chat-box-right .im-box {
  1512. display: flex;
  1513. }
  1514. .chat-box-right .im-main {
  1515. width: 602px;
  1516. height: 735px;
  1517. border-right: 1px solid #ebedf0;
  1518. }
  1519. .im-main .chat-main-form {
  1520. position: relative;
  1521. display: flex;
  1522. flex-direction: column;
  1523. }
  1524. .im-main .chat-main-form .display-infor {
  1525. height: 588px;
  1526. padding-top: 15px;
  1527. overflow-y: auto;
  1528. box-sizing: border-box;
  1529. }
  1530. .im-main .chat-main-form .reply {
  1531. width: 100%;
  1532. height: 147px;
  1533. border-top: 1px solid #ebedf0;
  1534. position: relative;
  1535. }
  1536. .im-main .chat-main-form .reply .upload {
  1537. width: 22px;
  1538. height: 18px;
  1539. background-image: url('../assets/images/chat/upload.png');
  1540. margin: 17px 0 8px 22px;
  1541. cursor: pointer;
  1542. }
  1543. .im-main .chat-main-form .reply .upload:hover {
  1544. background-image: url('../assets/images/chat/upload-on.png');
  1545. }
  1546. .im-main .chat-main-form .reply .reply-area textarea {
  1547. margin-left: 12px;
  1548. border: none;
  1549. resize: none;
  1550. width: 98%;
  1551. }
  1552. .im-main .chat-main-form .reply .send {
  1553. width: 62px;
  1554. height: 26px;
  1555. line-height: 26px;
  1556. position: absolute;
  1557. right: 20px;
  1558. bottom: 16px;
  1559. text-align: center;
  1560. background: #e1251b;
  1561. color: #fff;
  1562. cursor: pointer;
  1563. opacity: 1;
  1564. border-radius: 13px;
  1565. }
  1566. /* 主要聊天信息栏 */
  1567. .row {
  1568. padding: 30rpx;
  1569. }
  1570. .row:first-child {
  1571. margin-top: 20upx;
  1572. }
  1573. .row .my .left,
  1574. .row .other .right {
  1575. width: 100%;
  1576. display: flex;
  1577. margin-bottom: 20px;
  1578. }
  1579. .row .my .left .bubble,
  1580. .row .other .right .bubble {
  1581. max-width: 70%;
  1582. font-size: 14px;
  1583. min-height: 42px;
  1584. padding: 12px 14px 11px 16px;
  1585. word-break: break-word;
  1586. box-sizing: border-box;
  1587. }
  1588. .row .my .left .bubble .longimage,
  1589. .row .other .right .bubble .longimage {
  1590. width: 100px;
  1591. height: 100px;
  1592. }
  1593. .row .my .left .bubble .squareimage,
  1594. .row .other .right .bubble .squareimage {
  1595. width: 300rpx;
  1596. height: 300rpx;
  1597. }
  1598. .row .my .left .bubble.red-envelope .blessing,
  1599. .row .other .right .bubble.red-envelope .blessing {
  1600. position: absolute;
  1601. bottom: 14%;
  1602. color: #e9b874;
  1603. width: 80%;
  1604. text-align: center;
  1605. overflow: hidden;
  1606. display: -webkit-box;
  1607. -webkit-box-orient: vertical;
  1608. -webkit-line-clamp: 2;
  1609. }
  1610. .row .my .right,
  1611. .row .other .left {
  1612. flex-shrink: 0;
  1613. width: 80upx;
  1614. height: 80upx;
  1615. margin-top: 20px;
  1616. margin-left: 12px;
  1617. }
  1618. .row .my .right .avatar,
  1619. .row .other .left .avatar {
  1620. width: 34px;
  1621. height: 34px;
  1622. margin-right: 20px;
  1623. }
  1624. .row .my .right image,
  1625. .row .other .left image {
  1626. width: 80upx;
  1627. height: 80upx;
  1628. border-radius: 10upx;
  1629. }
  1630. .row .my {
  1631. width: 100%;
  1632. display: flex;
  1633. justify-content: flex-end;
  1634. }
  1635. .row .my .left {
  1636. min-height: 80upx;
  1637. justify-content: flex-end;
  1638. flex-wrap: wrap;
  1639. }
  1640. .row .my .left .bubble {
  1641. background-color: #d0e9ff;
  1642. color: #000;
  1643. opacity: 1;
  1644. border-radius: 8px 0rem 8px 8px;
  1645. }
  1646. .row .other .right .bubble {
  1647. opacity: 1;
  1648. border-radius: 0rem 8px 8px 8px;
  1649. }
  1650. .row .my .left .no-bg {
  1651. background-color: none;
  1652. }
  1653. @keyframes my-play {
  1654. 0% {
  1655. transform: translateX(80%);
  1656. }
  1657. 100% {
  1658. transform: translateX(0%);
  1659. }
  1660. }
  1661. .row .my .left .bubble.play .icon:after {
  1662. border-left: solid 10upx rgba(240, 108, 122, 0.5);
  1663. animation: my-play 1s linear infinite;
  1664. }
  1665. .phone-icon {
  1666. width: 60rpx;
  1667. height: 60rpx;
  1668. }
  1669. .row .my .right {
  1670. margin-left: 15upx;
  1671. }
  1672. .row .other {
  1673. width: 100%;
  1674. display: flex;
  1675. }
  1676. .row .other .left {
  1677. margin-right: 15upx;
  1678. }
  1679. .row .other .right {
  1680. flex-wrap: wrap;
  1681. margin-left: -8px;
  1682. }
  1683. .row .other .right .username,
  1684. .row .my .left .username {
  1685. width: 100%;
  1686. font-size: 12px;
  1687. font-family: Microsoft YaHei;
  1688. font-weight: 400;
  1689. margin-bottom: 5px;
  1690. color: #a1a6af;
  1691. color: #999;
  1692. display: flex;
  1693. align-items: center;
  1694. }
  1695. .row .my .left .username {
  1696. justify-content: flex-end;
  1697. }
  1698. .row .my .left .username .name {
  1699. max-width: 70%;
  1700. overflow: hidden;
  1701. text-overflow: ellipsis;
  1702. white-space: nowrap;
  1703. }
  1704. .row .my .left .username .time {
  1705. text-align: center;
  1706. margin-left: 40rpx;
  1707. }
  1708. .row .other .right .username .name {
  1709. max-width: 70%;
  1710. overflow: hidden;
  1711. text-overflow: ellipsis;
  1712. white-space: nowrap;
  1713. }
  1714. .row .other .right .bubble {
  1715. background-color: #f3f3f3;
  1716. color: #333;
  1717. }
  1718. @keyframes other-play {
  1719. 0% {
  1720. transform: translateX(-80%);
  1721. }
  1722. 100% {
  1723. transform: translateX(0%);
  1724. }
  1725. }
  1726. .row .other .right .bubble.play .icon:after {
  1727. border-right: solid 10upx rgba(255, 255, 255, 0.8);
  1728. animation: other-play 1s linear infinite;
  1729. }
  1730. .windows .mask {
  1731. position: fixed;
  1732. top: 100%;
  1733. width: 100%;
  1734. height: 100%;
  1735. z-index: 1000;
  1736. background-color: rgba(0, 0, 0, 0.6);
  1737. opacity: 0;
  1738. transition: opacity 0.2s ease-out;
  1739. }
  1740. .windows .layer {
  1741. position: fixed;
  1742. width: 80%;
  1743. height: 70%;
  1744. left: 10%;
  1745. z-index: 1001;
  1746. border-radius: 20upx;
  1747. overflow: hidden;
  1748. top: 100%;
  1749. transform: scale3d(0.5, 0.5, 1);
  1750. transition: all 0.2s ease-out;
  1751. }
  1752. .windows.show {
  1753. display: block;
  1754. }
  1755. .windows.show .mask {
  1756. top: 0;
  1757. opacity: 1;
  1758. }
  1759. .windows.show .layer {
  1760. transform: translate3d(0, -85vh, 0) scale3d(1, 1, 1);
  1761. }
  1762. .windows.hide {
  1763. display: block;
  1764. }
  1765. .windows.hide .mask {
  1766. top: 0;
  1767. opacity: 0;
  1768. }
  1769. .open-redenvelope {
  1770. width: 100%;
  1771. height: 70vh;
  1772. background-color: #cf3c35;
  1773. position: relative;
  1774. }
  1775. .open-redenvelope .top {
  1776. width: 100%;
  1777. background-color: #fe5454;
  1778. display: flex;
  1779. justify-content: center;
  1780. flex-wrap: wrap;
  1781. border-radius: 0 0 100% 100%;
  1782. box-shadow: inset 0 -20upx 0 #9c1712;
  1783. margin-bottom: 65upx;
  1784. }
  1785. .open-redenvelope .top .close-btn {
  1786. width: 100%;
  1787. height: 80upx;
  1788. display: flex;
  1789. justify-content: flex-end;
  1790. margin-bottom: 30upx;
  1791. }
  1792. .open-redenvelope .top .close-btn .icon {
  1793. color: #9c1712;
  1794. margin-top: 10upx;
  1795. margin-right: 10upx;
  1796. }
  1797. .open-redenvelope .top image {
  1798. width: 130upx;
  1799. height: 130upx;
  1800. border: solid 12upx #cf3c35;
  1801. border-radius: 100%;
  1802. margin-bottom: -65upx;
  1803. }
  1804. .open-redenvelope .from,
  1805. .open-redenvelope .blessing,
  1806. .open-redenvelope .money,
  1807. .open-redenvelope .showDetails {
  1808. width: 90%;
  1809. padding: 5upx 5%;
  1810. display: flex;
  1811. justify-content: center;
  1812. font-size: 32upx;
  1813. color: #fff;
  1814. }
  1815. .open-redenvelope .money {
  1816. font-size: 100upx;
  1817. color: #f8d757;
  1818. display: flex;
  1819. padding-top: 20upx;
  1820. }
  1821. .open-redenvelope .showDetails {
  1822. position: absolute;
  1823. bottom: 20upx;
  1824. align-items: center;
  1825. font-size: 28upx;
  1826. color: #f8d757;
  1827. }
  1828. .open-redenvelope .showDetails .icon {
  1829. font-size: 26upx;
  1830. color: #f8d757;
  1831. }
  1832. .flex-wrap {
  1833. flex: auto;
  1834. }
  1835. /* 返回图标 */
  1836. .back-icon {
  1837. position: absolute;
  1838. left: 0;
  1839. top: 36rpx;
  1840. width: 50rpx;
  1841. height: 30rpx;
  1842. transform: rotate(90deg);
  1843. }
  1844. .shop-tit {
  1845. text-align: center;
  1846. max-width: 80%;
  1847. margin: 0 auto;
  1848. overflow: hidden;
  1849. white-space: nowrap;
  1850. text-overflow: ellipsis;
  1851. }
  1852. /* 系统提示 */
  1853. .sys-tips {
  1854. display: flex;
  1855. justify-content: center;
  1856. margin-bottom: 20px;
  1857. }
  1858. .tips-content {
  1859. color: #999999;
  1860. font-size: 28rpx;
  1861. }
  1862. /* 中间时间样式 */
  1863. .topTime {
  1864. text-align: center;
  1865. margin-bottom: 15px;
  1866. height: 28rpx;
  1867. font-size: 10px;
  1868. font-family: PingFang SC;
  1869. font-weight: 400;
  1870. line-height: 28rpx;
  1871. color: #aaaaaa;
  1872. opacity: 1;
  1873. }
  1874. /* 右侧正在查询和我的订单 */
  1875. .order-column {
  1876. flex: 1;
  1877. }
  1878. .order-column .tab-switch {
  1879. display: flex;
  1880. height: 37px;
  1881. }
  1882. .order-column .inquiry,
  1883. .order-column .my-order {
  1884. flex: 1;
  1885. text-align: center;
  1886. line-height: 37px;
  1887. cursor: pointer;
  1888. font-size: 12px;
  1889. border-bottom: 1px solid #eceef0;
  1890. background: #f8f8f8;
  1891. font-family: Microsoft YaHei;
  1892. font-weight: 400;
  1893. color: #999999;
  1894. opacity: 1;
  1895. }
  1896. .order-column .active {
  1897. color: #e1251b;
  1898. background-color: #fff;
  1899. border: none;
  1900. }
  1901. .order-column .browse {
  1902. width: 100%;
  1903. border-bottom: 1px solid #eceef0;
  1904. text-align: center;
  1905. font-size: 14px;
  1906. font-family: Microsoft YaHei;
  1907. font-weight: 400;
  1908. line-height: 14px;
  1909. color: #666666;
  1910. opacity: 1;
  1911. }
  1912. .order-column .text {
  1913. width: 100px;
  1914. padding: 11px 0 5px 0rem;
  1915. margin: auto;
  1916. border-bottom: 2px solid #e1251b;
  1917. }
  1918. /* 订单商品详情 */
  1919. .recent-list,
  1920. .order-list {
  1921. padding-left: 12px;
  1922. height: 660px;
  1923. overflow-y: auto;
  1924. }
  1925. .prod-item {
  1926. display: flex;
  1927. padding: 18px 0;
  1928. border-bottom: 1px solid #eceef0;
  1929. border-top: 1px solid #eceef0;
  1930. margin-top: -1px;
  1931. }
  1932. .order-column .order-list .botl {
  1933. border-bottom: 9px solid #faf9f9;
  1934. flex-direction: column;
  1935. padding-bottom: 0;
  1936. }
  1937. .prod-item .prod-detail {
  1938. padding-right: 12px;
  1939. flex: 1;
  1940. }
  1941. /* .prod-detail .prod-name {
  1942. cursor: pointer;
  1943. } */
  1944. .prod-item img {
  1945. width: 60px;
  1946. height: 60px;
  1947. margin-right: 12px;
  1948. }
  1949. .prod-item .prod-name {
  1950. font-size: 12px;
  1951. font-family: Microsoft YaHei;
  1952. font-weight: 400;
  1953. line-height: 18px;
  1954. color: #333333;
  1955. opacity: 1;
  1956. word-break: break-word;
  1957. }
  1958. .prod-item .interval {
  1959. width: 100%;
  1960. height: 10px;
  1961. background: #faf9f9;
  1962. opacity: 1;
  1963. }
  1964. .prod-b {
  1965. display: flex;
  1966. justify-content: space-between;
  1967. margin-top: 10px;
  1968. }
  1969. .prod-b .prod-price {
  1970. margin-top: 5px;
  1971. font-size: 12px;
  1972. font-family: Microsoft YaHei;
  1973. font-weight: 400;
  1974. line-height: 18px;
  1975. color: #e1251b;
  1976. opacity: 1;
  1977. }
  1978. .prod-b .prod-send {
  1979. padding: 0 5px;
  1980. /* width: 46px; */
  1981. height: 24px;
  1982. cursor: pointer;
  1983. text-align: center;
  1984. border: 1px solid #e9eaec;
  1985. opacity: 1;
  1986. border-radius: 12px;
  1987. font-size: 12px;
  1988. font-family: Microsoft YaHei;
  1989. font-weight: 400;
  1990. line-height: 24px;
  1991. color: #333333;
  1992. opacity: 1;
  1993. }
  1994. .prod-b .prod-send:hover {
  1995. border: 1px solid #e1251b;
  1996. color: #e1251b;
  1997. }
  1998. /* 我的订单样式 */
  1999. .order-box {
  2000. display: flex;
  2001. }
  2002. .order-number {
  2003. display: flex;
  2004. font-size: 12px;
  2005. justify-content: space-between;
  2006. padding-bottom: 6px;
  2007. border-bottom: 1px solid #ebedf0;
  2008. margin-bottom: 12px;
  2009. }
  2010. .order-box .number,
  2011. .order-box .time {
  2012. font-size: 12px;
  2013. font-family: Microsoft YaHei;
  2014. font-weight: 400;
  2015. line-height: 14px;
  2016. color: #666666;
  2017. opacity: 1;
  2018. }
  2019. .order-number .number {
  2020. cursor: pointer;
  2021. display: inline-block;
  2022. margin-right: 16px;
  2023. }
  2024. .order-number .send-number {
  2025. display: inline-block;
  2026. margin-right: 22px;
  2027. cursor: pointer;
  2028. }
  2029. .order-number .send-number:hover {
  2030. color:#e1251b
  2031. }
  2032. .order-list .bottom-tips, .recent-list .bottom-tips {
  2033. text-align: center;
  2034. padding-top: 20px;
  2035. }
  2036. /* 发送链接样式 */
  2037. .link-box {
  2038. padding: 10px 10px 0 10px;
  2039. margin: 0 90px 20px 90px;
  2040. background: #ffffff;
  2041. border: 1px solid #f2f2f2;
  2042. opacity: 1;
  2043. }
  2044. .link-box .prod-number {
  2045. margin-bottom: 2px;
  2046. cursor: pointer;
  2047. }
  2048. .link-prod {
  2049. display: flex;
  2050. padding-bottom: 9px;
  2051. border-bottom: 1px solid #eeeeee;
  2052. cursor: pointer;
  2053. }
  2054. .link-prod img {
  2055. width: 88px;
  2056. height: 88px;
  2057. }
  2058. .link-prod .link-detail {
  2059. width: 100%;
  2060. display: flex;
  2061. flex-direction: column;
  2062. justify-content: space-between;
  2063. margin-top: 1px;
  2064. margin-left: 13px;
  2065. }
  2066. .link-detail .prod-name {
  2067. font-size: 10px;
  2068. font-family: PingFang SC;
  2069. padding-top: 5px;
  2070. font-weight: 400;
  2071. color: #333333;
  2072. opacity: 1;
  2073. word-break: break-word;
  2074. cursor: pointer;
  2075. }
  2076. .link-prod .prod-price {
  2077. display: flex;
  2078. justify-content: space-between;
  2079. font-size: 10px;
  2080. font-family: PingFang SC;
  2081. padding-bottom: 5px;
  2082. font-weight: 400;
  2083. color: #999999;
  2084. opacity: 1;
  2085. word-break: break-all;
  2086. }
  2087. .link-prod .payment-amount {
  2088. flex: 1;
  2089. }
  2090. .link-prod .prod-status {
  2091. width: 35%;
  2092. text-align: end;
  2093. }
  2094. .link-send {
  2095. font-size: 12px;
  2096. font-family: PingFang SC;
  2097. font-weight: 400;
  2098. line-height: 49px;
  2099. text-align: center;
  2100. color: #e43130;
  2101. cursor: pointer;
  2102. }
  2103. .link-send-right {
  2104. width: 5px;
  2105. height: 9px;
  2106. margin-left: 7px;
  2107. display: inline-block;
  2108. background: url('../assets/images/chat/link-send.png');
  2109. }
  2110. /* 商品链接样式 */
  2111. .prod-link {
  2112. width: 75%;
  2113. background: #ffffff;
  2114. border: 1px solid #f2f2f2;
  2115. -webkit-box-sizing: border-box;
  2116. box-sizing: border-box;
  2117. padding: 15px 13px 0px 12px;
  2118. cursor: pointer;
  2119. }
  2120. .prod-number{
  2121. cursor: pointer;
  2122. }
  2123. .prod-link .prod-number{
  2124. margin-top: -7px;
  2125. margin-bottom: 5px;
  2126. border-bottom: 1px solid #eceef0;
  2127. padding-bottom: 5px;
  2128. }
  2129. .prod-link .prod-number:hover{
  2130. color: #9c1712;
  2131. }
  2132. .prod-no {
  2133. padding: none;
  2134. border-bottom: none;
  2135. }
  2136. .left .message-box {
  2137. display: flex;
  2138. justify-content: flex-end;
  2139. align-items: center;
  2140. }
  2141. /* 已读未读 */
  2142. .unread {
  2143. font-size: 12px;
  2144. color: #aaaaaa;
  2145. margin-right: 9px;
  2146. }
  2147. /* 图片上传 */
  2148. .search-btnn {
  2149. position: absolute;
  2150. opacity: 0;
  2151. width: 0;
  2152. height: 0;
  2153. }
  2154. .imgUp {
  2155. display: inline-block;
  2156. position: absolute;
  2157. height: 18px;
  2158. left: 22px;
  2159. top: 17px;
  2160. }
  2161. .imgUp:hover {
  2162. background-image: url('../assets/images/chat/upload-on.png');
  2163. cursor: pointer;
  2164. }
  2165. /* 图片放大 */
  2166. /*遮罩层样式*/
  2167. .img-layer {
  2168. position: fixed;
  2169. z-index: 999;
  2170. top: 0;
  2171. left: 0;
  2172. background: rgba(0, 0, 0, 0.7);
  2173. width: 100%;
  2174. height: 100%;
  2175. overflow: hidden;
  2176. }
  2177. /*不限制图片大小,实现居中*/
  2178. /* .img-layer .img {
  2179. max-width: 70%;
  2180. max-height: 70%;
  2181. display: block;
  2182. position: absolute;
  2183. left: 0;
  2184. right: 0;
  2185. top: 0;
  2186. bottom: 0;
  2187. margin: auto;
  2188. z-index: 1000;
  2189. cursor: pointer;
  2190. }
  2191. .img-layer img {
  2192. width: 100%;
  2193. height: 100%;
  2194. cursor: pointer;
  2195. object-fit: contain
  2196. } */
  2197. /* 点击加载更多 */
  2198. .display-infor .more {
  2199. font-size: 12px;
  2200. color: #5a606b;
  2201. text-align: center;
  2202. margin-bottom: 12px;
  2203. cursor: pointer;
  2204. -moz-user-select: none; /*火狐*/
  2205. -webkit-user-select: none; /*webkit浏览器*/
  2206. -ms-user-select: none; /*IE10*/
  2207. -khtml-user-select: none; /*早期浏览器*/
  2208. user-select: none;
  2209. }
  2210. /* 重新登录提示弹窗 */
  2211. .login-baBox {
  2212. position: fixed;
  2213. top: 0;
  2214. width: 100%;
  2215. height: 100%;
  2216. background: #2e2f3d;
  2217. }
  2218. .un-read-tips {
  2219. background-color: #fff;
  2220. padding: 15px;
  2221. padding: 5px 10px 5px 10px;
  2222. font-size: 12px;
  2223. border-radius: 20px 20px 20px 20px;
  2224. position: absolute;
  2225. color: #E43130;
  2226. top: 10px;
  2227. right: 100px;
  2228. display: -webkit-box;
  2229. display: -ms-flexbox;
  2230. display: flex;
  2231. align-items: center;
  2232. -webkit-box-shadow: 1px 1px 5px 0 #aaa;
  2233. box-shadow: 1px 1px 5px 0 #aaa;
  2234. }
  2235. .un-read-icon {
  2236. width: 12px;
  2237. height: 12px;
  2238. margin-right: 5px;
  2239. margin-bottom: 1px;
  2240. }
  2241. @media screen and ( max-width: 1680px ){
  2242. .body .chat-box {
  2243. opacity: 1;
  2244. /* width: 960px; */
  2245. margin: 20px auto 20px auto;
  2246. }
  2247. .body{
  2248. position: absolute;
  2249. height: calc(100vh + 200px)
  2250. /* height: auto; */
  2251. }
  2252. }
  2253. /* 新消息过来 背景颜色 以及 选中的背景颜色 */
  2254. .chat-box-left .shop-list .newMessage{
  2255. background-color: #FFF9cd;
  2256. }
  2257. .chat-box-left .shop-list .changeUser{
  2258. background-color: #D2E6F9;
  2259. }
  2260. /* 放大图片的右侧关闭图标 */
  2261. .bubble /deep/ .el-image-viewer__close{
  2262. color:red !important
  2263. }
  2264. </style>