info.vue 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205
  1. <template>
  2. <mobile-frame>
  3. <view class="main">
  4. <view class="one">
  5. <!-- 聊天内容 -->
  6. <scroll-view class="scroll-view" scroll-y="true" scroll-with-animation="true"
  7. :scroll-into-view="scrollToView" refresher-enabled="true" :refresher-triggered="triggered"
  8. @refresherrefresh="getFresh">
  9. <view class="list-scroll-view">
  10. <view class="chat-ls" v-for="(item,index) in msgList" :key="index" :id="'msg'+ item._id">
  11. <view class="chat-time" v-if="item.time != ''">
  12. {{item.time}}
  13. </view>
  14. <view class="msg-m msg-left" v-if="item.speaker !=  user._id">
  15. <image @tap="toShop()" class="user-img"
  16. :src="shop.logo&&shop.logo.length>0?shop.logo[0].url:''">
  17. </image>
  18. <!-- 文字 -->
  19. <view class="message" v-if="item.msg_type =='0'">                           
  20. <view class="msg-text">{{item.content}}</view>
  21. </view>
  22. <!-- 图像 -->
  23. <view class="message img" v-else-if="item.msg_type =='1'"
  24. @tap="previewImg(item.content)">
  25. <image :src="item.content" class="msg-img" mode="widthFix"></image>
  26. </view>
  27. <!-- 商品 -->
  28. <view class="message img" v-else-if="item.msg_type =='2'" @tap="toView(item)">
  29. <view class="msg-goods">
  30. <image :src="item.goodsInfo&&item.goodsInfo.file" class="image"
  31. mode="scaleToFill">
  32. </image>
  33. <view class="goods_1">
  34. <view class="name textOver">{{item.goodsInfo&&item.goodsInfo.name}}</view>
  35. <view class="money">
  36. <text class="money_1"
  37. v-if="item.goodsInfo&&item.goodsInfo.spec&&item.goodsInfo.spec.leader_price"><text>团长价¥</text>{{item.goodsInfo.spec.leader_price||0}}</text>
  38. <text class="money_2"
  39. v-else-if="item.goodsInfo&&item.goodsInfo.spec&&item.goodsInfo.spec.price"><text>特价¥</text>{{item.goodsInfo.spec.price||0}}</text>
  40. <text class="money_2"
  41. v-else><text>¥</text>{{item.goodsInfo.spec.sell_money||0}}</text>
  42. <text
  43. class="money_2"><text>¥</text>{{item.goodsInfo.spec.flow_money||0}}</text>
  44. </view>
  45. <view class="act" v-if="item.goodsInfo&&item.goodsInfo.act">
  46. <text class="label" v-for="(tag,index) in item.goodsInfo.act"
  47. :key="index">{{tag}}</text>
  48. </view>
  49. <view class="button" @tap.stop="toSend(item)" v-if="item.is_send=='0'">
  50. <text>发送连接</text>
  51. </view>
  52. </view>
  53. </view>
  54. </view>
  55. <!-- 订单 -->
  56. <view class="message img" v-else-if="item.msg_type =='3'" @tap="toView(item)">
  57. <view class="msg-order">
  58. <view class="order_1">
  59. <view class="image" v-for="(tago,index) in item.ordernfo.goods"
  60. :key="index">
  61. <image v-if="tago.file.length>0" :src="tago.file&&tago.file[0].url"
  62. class="image" mode="scaleToFill">
  63. </image>
  64. <image v-else :src="tago.goods&&tago.goods.file[0].url" class="image"
  65. mode="scaleToFill">
  66. </image>
  67. </view>
  68. </view>
  69. <view class="order_2">
  70. <view class="no">订单号:{{item.ordernfo.no}}</view>
  71. <view class="status">
  72. <text>{{item.ordernfo.status}}</text>
  73. <view class="button" @tap.stop="toSend(item)" v-if="item.is_send=='0'">
  74. <text>发送连接</text>
  75. </view>
  76. </view>
  77. </view>
  78. </view>
  79. </view>
  80. </view>
  81. <view class="msg-m msg-right" v-else-if="item.speaker == user._id">
  82. <image class="user-img" :src="user.icon&&user.icon.length>0?user.icon[0].url:''">
  83. </image>
  84. <!-- 文字 -->
  85. <view class="message" v-if="item.msg_type =='0'">
  86. <view class="msg-text">{{item.content}}</view>
  87. </view>
  88. <!-- 图像 -->
  89. <view class="message img" v-else-if="item.msg_type =='1'"
  90. @tap="previewImg(item.content)">
  91. <image :src="item.content" class="msg-img" mode="widthFix"></image>
  92. </view>
  93. <!-- 商品 -->
  94. <view class="message img" v-else-if="item.msg_type =='2'" @tap="toView(item)">
  95. <view class="msg-goods">
  96. <image :src="item.goodsInfo&&item.goodsInfo.file" class="image"
  97. mode="scaleToFill">
  98. </image>
  99. <view class="goods_1">
  100. <view class="name textOver">{{item.goodsInfo&&item.goodsInfo.name}}</view>
  101. <view class="money">
  102. <text class="money_1"
  103. v-if="item.goodsInfo&&item.goodsInfo.spec&&item.goodsInfo.spec.leader_price"><text>团长价¥</text>{{item.goodsInfo.spec.leader_price||0}}</text>
  104. <text class="money_2"
  105. v-else-if="item.goodsInfo&&item.goodsInfo.spec&&item.goodsInfo.spec.price"><text>特价¥</text>{{item.goodsInfo.spec.price||0}}</text>
  106. <text class="money_2"
  107. v-else><text>¥</text>{{item.goodsInfo.spec.sell_money||0}}</text>
  108. <text
  109. class="money_2"><text>¥</text>{{item.goodsInfo.spec.flow_money||0}}</text>
  110. </view>
  111. <view class="act" v-if="item.goodsInfo&&item.goodsInfo.act">
  112. <text class="label" v-for="(tag,index) in item.goodsInfo.act"
  113. :key="index">{{tag}}</text>
  114. </view>
  115. <view class="button" @tap.stop="toSend(item)" v-if="item.is_send=='0'">
  116. <text>发送连接</text>
  117. </view>
  118. </view>
  119. </view>
  120. </view>
  121. <!-- 订单 -->
  122. <view class="message img" v-else-if="item.msg_type =='3'" @tap="toView(item)">
  123. <view class="msg-order">
  124. <view class="order_1">
  125. <view class="images" v-for="(tago,index) in item.ordernfo.goods"
  126. :key="index">
  127. <image v-if="tago.file.length>0" :src="tago.file&&tago.file[0].url"
  128. class="image" mode="scaleToFill">
  129. </image>
  130. <image v-else :src="tago.goods&&tago.goods.file[0].url" class="image"
  131. mode="scaleToFill">
  132. </image>
  133. </view>
  134. </view>
  135. <view class="order_2">
  136. <view class="no">订单号:{{item.ordernfo.no}}</view>
  137. <view class="status">
  138. <text>{{item.ordernfo.status}}</text>
  139. <view class="button" @tap.stop="toSend(item)" v-if="item.is_send=='0'">
  140. <text>发送连接</text>
  141. </view>
  142. </view>
  143. </view>
  144. </view>
  145. </view>
  146. </view>
  147. </view>
  148. </view>
  149. </scroll-view>
  150. </view>
  151. <view class="two">
  152. <submit_1 @choseImg="choseImg" @inputs="inputs" @heights="heights" @sendGoods="sendGoods"
  153. @sendOrder="sendOrder"></submit_1>
  154. </view>
  155. </view>
  156. <!-- 规格 -->
  157. <uni-popup ref="specShow" background-color="#fff" type="bottom" :is-mask-click="false">
  158. <view class="popup">
  159. <view class="close">
  160. <text @click="toClose" class="iconfont icon-shanchu"></text>
  161. </view>
  162. <view class="info_1" v-if="popupShow=='1'">
  163. <goods_1 :marketList="list" @toPage="toPage" @toSend="toGoods"></goods_1>
  164. </view>
  165. <view class="info_1" v-else-if="popupShow=='2'">
  166. <order_1 :tabs="tabs" :status="status" :orderList="list" @toPage="toPage" @toSend="toOrder"
  167. @tabsChange="tabsChange">
  168. </order_1>
  169. </view>
  170. </view>
  171. </uni-popup>
  172. </mobile-frame>
  173. </template>
  174. <script>
  175. import moment from 'moment';
  176. import submit_1 from './components/submit_1.vue';
  177. import goods_1 from './components/goods_1.vue';
  178. import order_1 from './components/order_1.vue';
  179. export default {
  180. components: {
  181. submit_1,
  182. goods_1,
  183. order_1,
  184. },
  185. data() {
  186. return {
  187. // 用户信息
  188. user: {},
  189. // 房间号id
  190. id: '',
  191. // 店铺信息
  192. shop: {},
  193. shop_id: "",
  194. // 商品或订单信息条件
  195. goods: {},
  196. // 订单状态
  197. statusList: [],
  198. // 历史记录
  199. msgList: [],
  200. // 订单列表
  201. list: [],
  202. status: '0',
  203. tabs: {
  204. active: '0',
  205. menu: []
  206. },
  207. // 聊天记录
  208. total: 0,
  209. skip: 0,
  210. limit: 6,
  211. page: 0,
  212. // 判断是否跳到最后一条
  213. is_bottom: true,
  214. // 判断是否下拉刷新复位
  215. triggered: false,
  216. scrollToView: '', //滑动最后一条信息
  217. // 规格弹框
  218. popupShow: '1',
  219. // 判断是否是选择图片刷新
  220. is_img: false
  221. };
  222. },
  223. onShow: async function() {
  224. const that = this;
  225. // 判断是否是选择图片刷新
  226. if (!that.is_img) {
  227. if (that.id) {
  228. await that.clearPage();
  229. await that.search()
  230. }
  231. await that.searchOther();
  232. }
  233. },
  234. onLoad: async function(e) {
  235. const that = this;
  236. that.$set(that, `goods`, e);
  237. that.$set(that, `id`, e.id);
  238. that.$set(that, `shop_id`, e.shop);
  239. that.watchlogin();
  240. },
  241. computed: {
  242. listenWebsocket() {
  243. return this.$store.state.websocketData;
  244. }
  245. },
  246. watch: {
  247. listenWebsocket: async function(newstr) {
  248. if (newstr && newstr.type == 'chat' && newstr.room == this.id) {
  249. if (newstr.msg_type == '2') {
  250. // 商品
  251. res = await that.$api(`/viewGoods/goodsDetail`, `POST`, {
  252. id: newstr.content
  253. });
  254. if (res.errcode == '0') {
  255. let indexSpecs;
  256. // 显示最低价格的规格信息,不考虑库存问题
  257. if (res.data.specs && res.data.specs.length > 0) {
  258. // 规格排序
  259. indexSpecs = res.data.specs.sort(function(a, b) {
  260. let i, j;
  261. if (a.price) i = 'price'
  262. else i = 'sell_money'
  263. if (b.price) j = 'price'
  264. else j = 'sell_money'
  265. return a[i] - b[j];
  266. })
  267. }
  268. let act = res.data.act.map(i => {
  269. return i.tag
  270. })
  271. let goodsInfo = {
  272. "file": res.data && res.data.goods && res.data.goods.file && res.data.goods
  273. .file[0]
  274. .url,
  275. "name": res.data && res.data.goods && res.data.goods.name,
  276. "spec": indexSpecs[0],
  277. "act": act,
  278. }
  279. newstr.goodsInfo = goodsInfo
  280. newstr.is_send = '1'
  281. }
  282. } else if (newstr.msg_type == '3') {
  283. // 订单
  284. res = await that.$api(`/viewOrder/getOrder/${newstr.content}`)
  285. if (res.errcode == '0') {
  286. let status = that.statusList.find(i => i.value == res.data.status)
  287. // 过滤店铺订单
  288. let shop_goods;
  289. if (res.data.status != '0') {
  290. // 已支付订单
  291. shop_goods = res.data.goods
  292. } else {
  293. // 未支付订单
  294. if (!that.id) shop_goods = res.data.goods.filter(i => i.shop == that.shop_id)
  295. else shop_goods = res.data.goods.filter(i => i.shop == that.shop._id)
  296. if (shop_goods.length > 0) shop_goods = shop_goods[0].goods
  297. }
  298. let ordernfo = {
  299. "no": res.data && res.data.no,
  300. "goods": shop_goods,
  301. "status": status.label || '暂无',
  302. "is_status": res.data.status
  303. }
  304. newstr.ordernfo = ordernfo
  305. newstr.is_send = '1'
  306. }
  307. }
  308. this.msgList.push(newstr);
  309. this.goBottom();
  310. }
  311. }
  312. },
  313. methods: {
  314. // 监听用户是否登录
  315. watchlogin() {
  316. const that = this;
  317. uni.getStorage({
  318. key: 'token',
  319. success: async function(res) {
  320. let user = that.$jwt(res.data);
  321. if (user) {
  322. // 查询状态
  323. let arr = await that.$api(`/dictData`, 'GET', {
  324. code: 'order_process'
  325. })
  326. if (arr.errcode == '0') that.$set(that, `statusList`, arr.data);
  327. that.$set(that, `user`, user)
  328. }
  329. }
  330. })
  331. },
  332. // 查询商品或订单信息
  333. async searchOther() {
  334. const that = this;
  335. let res;
  336. let statusList = that.statusList.filter((i) => {
  337. return i.value != '-2' && i.value != '-3';
  338. });
  339. var menu = statusList.map((item) => {
  340. return {
  341. title: item.label,
  342. active: item.value
  343. }
  344. })
  345. that.$set(that.tabs, `menu`, menu)
  346. // 发送商品信息
  347. if (that.goods && that.goods.goods) {
  348. // 商品
  349. res = await that.$api(`/viewGoods/goodsDetail`, `POST`, {
  350. id: that.goods.goods
  351. });
  352. if (res.errcode == '0') {
  353. let indexSpecs;
  354. // 显示最低价格的规格信息,不考虑库存问题
  355. if (res.data.specs && res.data.specs.length > 0) {
  356. // 规格排序
  357. indexSpecs = res.data.specs.sort(function(a, b) {
  358. let i, j;
  359. if (a.price) i = 'price'
  360. else i = 'sell_money'
  361. if (b.price) j = 'price'
  362. else j = 'sell_money'
  363. return a[i] - b[j];
  364. })
  365. }
  366. let act = res.data.act.map(i => {
  367. return i.tag
  368. })
  369. let goodsInfo = {
  370. "file": res.data && res.data.goods && res.data.goods.file && res.data.goods.file[0]
  371. .url,
  372. "name": res.data && res.data.goods && res.data.goods.name,
  373. "spec": indexSpecs[0],
  374. "act": act
  375. }
  376. let data = {
  377. "_id": 'goods' + moment(new Date()).valueOf(),
  378. "speaker": that.user._id,
  379. "content": that.goods.goods,
  380. "goodsInfo": goodsInfo,
  381. "time": moment().format('YYYY-MM-DD HH:mm:ss'),
  382. "msg_type": '2',
  383. "is_send": '0'
  384. }
  385. if (!that.id) data.shop = that.shop_id
  386. else data.room = that.id
  387. that.msgList.push(data);
  388. }
  389. } else if (that.goods && that.goods.order) {
  390. // 订单
  391. if (that.goods.status == '0') res = await that.$api(`/order/${that.goods.order}`)
  392. else res = await that.$api(`/orderDetail/${that.goods.order}`);
  393. if (res.errcode == '0') {
  394. let status = that.statusList.find(i => i.value == res.data.status)
  395. // 过滤店铺订单
  396. let shop_goods;
  397. if (that.goods.status != '0') {
  398. // 已支付订单
  399. shop_goods = res.data.goods
  400. } else {
  401. // 未支付订单
  402. if (!that.id) shop_goods = res.data.goods.filter(i => i.shop == that.shop_id)
  403. else shop_goods = res.data.goods.filter(i => i.shop == that.shop._id)
  404. if (shop_goods.length > 0) shop_goods = shop_goods[0].goods
  405. }
  406. let ordernfo = {
  407. "no": res.data && res.data.no,
  408. "goods": shop_goods,
  409. "status": status.label || '暂无',
  410. "is_status": res.data.status
  411. }
  412. let data = {
  413. "_id": 'order' + moment(new Date()).valueOf(),
  414. "speaker": that.user._id,
  415. "content": that.goods.order,
  416. "ordernfo": ordernfo,
  417. "time": moment().format('YYYY-MM-DD HH:mm:ss'),
  418. "msg_type": '3',
  419. "is_send": '0'
  420. }
  421. if (!that.id) data.shop = that.shop_id
  422. else data.room = that.id
  423. that.msgList.push(data);
  424. }
  425. }
  426. // 跳转到最后一条数据 与前面的:id进行对照
  427. // 如果是下拉刷新聊天记录不跳到最后一条
  428. if (that.is_bottom == true) that.goBottom();
  429. },
  430. // 查询历史记录
  431. async search() {
  432. const that = this;
  433. // 查询房间信息
  434. // 如果是下拉刷新聊天记录不请求房间信息
  435. if (that.is_bottom == true) {
  436. res = await that.$api(`/room/${that.id}`, `GET`, {}, 'chat')
  437. if (res.errcode == '0') {
  438. that.$set(that, `shop`, res.data && res.data.shop);
  439. if (res.data && res.data.shop && res.data.shop.name) {
  440. uni.setNavigationBarTitle({
  441. title: res.data.shop.name
  442. });
  443. }
  444. } else {
  445. uni.showToast({
  446. title: res.errmsg,
  447. icon: 'none'
  448. })
  449. }
  450. }
  451. let info = {
  452. skip: that.skip,
  453. limit: that.limit,
  454. room: that.id
  455. }
  456. let res;
  457. res = await that.$api(`/chatRecord`, `GET`, {
  458. ...info,
  459. }, 'chat');
  460. if (res.errcode == '0') {
  461. let msgList = [...res.data, ...that.msgList];
  462. msgList.sort(function(a, b) {
  463. return a.time > b.time ? 1 : -1;
  464. });
  465. that.$set(that, `total`, res.total)
  466. for (let val of msgList) {
  467. if (val.msg_type == '2') {
  468. // 商品
  469. res = await that.$api(`/viewGoods/goodsDetail`, `POST`, {
  470. id: val.content
  471. });
  472. if (res.errcode == '0') {
  473. let indexSpecs;
  474. // 显示最低价格的规格信息,不考虑库存问题
  475. if (res.data.specs && res.data.specs.length > 0) {
  476. // 规格排序
  477. indexSpecs = res.data.specs.sort(function(a, b) {
  478. let i, j;
  479. if (a.price) i = 'price'
  480. else i = 'sell_money'
  481. if (b.price) j = 'price'
  482. else j = 'sell_money'
  483. return a[i] - b[j];
  484. })
  485. }
  486. let act = res.data.act.map(i => {
  487. return i.tag
  488. })
  489. let goodsInfo = {
  490. "file": res.data && res.data.goods && res.data.goods.file && res.data.goods
  491. .file[0]
  492. .url,
  493. "name": res.data && res.data.goods && res.data.goods.name,
  494. "spec": indexSpecs[0],
  495. "act": act,
  496. }
  497. val.goodsInfo = goodsInfo
  498. val.is_send = '1'
  499. }
  500. } else if (val.msg_type == '3') {
  501. // 订单
  502. res = await that.$api(`/viewOrder/getOrder/${val.content}`)
  503. if (res.errcode == '0') {
  504. let status = that.statusList.find(i => i.value == res.data.status)
  505. // 过滤店铺订单
  506. let shop_goods;
  507. if (res.data.status != '0') {
  508. // 已支付订单
  509. shop_goods = res.data.goods
  510. } else {
  511. // 未支付订单
  512. if (!that.id) shop_goods = res.data.goods.filter(i => i.shop == that.shop_id)
  513. else shop_goods = res.data.goods.filter(i => i.shop == that.shop._id)
  514. if (shop_goods.length > 0) shop_goods = shop_goods[0].goods
  515. }
  516. let ordernfo = {
  517. "no": res.data && res.data.no,
  518. "goods": shop_goods,
  519. "status": status.label || '暂无',
  520. "is_status": res.data.status
  521. }
  522. val.ordernfo = ordernfo
  523. val.is_send = '1'
  524. }
  525. }
  526. }
  527. that.$set(that, `msgList`, msgList);
  528. } else {
  529. uni.showToast({
  530. title: res.errmsg,
  531. icon: 'none'
  532. })
  533. }
  534. let id = that.msgList.filter(i => {
  535. if (i.speaker != that.user._id) return i.is_read = '0';
  536. })
  537. let ids = id.map(i => {
  538. return i._id
  539. })
  540. if (ids.length > 0) {
  541. // 信息已读
  542. res = await that.$api(`/chatRecord/read`, `POST`, {
  543. ids
  544. }, 'chat')
  545. if (res.errcode == '0') {} else {
  546. uni.showToast({
  547. title: res.errmsg,
  548. icon: 'none'
  549. })
  550. }
  551. }
  552. },
  553. // 进行图片的预览
  554. previewImg(e) {
  555. const that = this;
  556. // 预览图片
  557. uni.previewImage({
  558. current: 0,
  559. urls: [e],
  560. longPressActions: {
  561. itemList: ['发送给朋友', '保存图片', '收藏'],
  562. success: function(data) {
  563. console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) +
  564. '张图片');
  565. },
  566. fail: function(err) {
  567. console.log(err.errMsg);
  568. }
  569. }
  570. });
  571. },
  572. // 判断是否是选择图片刷新
  573. choseImg(e) {
  574. const that = this;
  575. that.$set(that, `is_img`, e)
  576. },
  577. //接受输入内容
  578. async inputs(e) {
  579. const that = this;
  580. let user = that.user
  581. if (user._id) {
  582. //时间间隔处理
  583. let data = {
  584. "speaker": user._id,
  585. "content": e.message,
  586. "time": moment().format('YYYY-MM-DD HH:mm:ss'),
  587. "msg_type": e.type
  588. };
  589. // 发送给服务器消息
  590. if (!that.id) data.shop = that.shop_id
  591. else data.room = that.id
  592. let res = await that.$api(`/chatRecord`, `POST`, data, 'chat');
  593. if (res.errcode == '0') {
  594. that.msgList.push(res.data);
  595. } else {
  596. uni.showToast({
  597. title: res.errmsg,
  598. icon: 'none'
  599. })
  600. }
  601. // 跳转到最后一条数据 与前面的:id进行对照
  602. that.goBottom();
  603. } else {
  604. uni.showToast({
  605. title: '未登录账号无法发送消息 ,请及时登录!',
  606. icon: 'none'
  607. })
  608. }
  609. },
  610. // 发送连接
  611. async toSend(e) {
  612. const that = this;
  613. //时间间隔处理
  614. let data = {
  615. "speaker": e.speaker,
  616. "content": e.content,
  617. "time": moment().format('YYYY-MM-DD HH:mm:ss'),
  618. "msg_type": e.msg_type
  619. };
  620. if (!that.id) data.shop = that.shop_id
  621. else data.room = that.id
  622. let res = await that.$api(`/chatRecord`, `POST`, data, 'chat');
  623. if (res.errcode == '0') {
  624. e.is_send = '1'
  625. that.msgList = that.msgList.map(t => {
  626. return t.time === e.time ? e : t;
  627. });
  628. } else {
  629. uni.showToast({
  630. title: res.errmsg,
  631. icon: 'none'
  632. })
  633. }
  634. },
  635. // 发送商品
  636. async sendGoods() {
  637. const that = this;
  638. let res;
  639. let info = {
  640. skip: that.skip,
  641. limit: that.limit,
  642. shop: that.shop._id || that.shop_id
  643. };
  644. // 首页产品列表
  645. res = await that.$api(`/viewGoods/indexGoodsList`, `GET`, {
  646. ...info
  647. });
  648. if (res.errcode == '0') {
  649. let list = [...that.list, ...res.data];
  650. that.$set(that, `list`, list);
  651. that.$set(that, `total`, res.total)
  652. that.$set(that, `popupShow`, '1')
  653. that.$refs.specShow.open();
  654. }
  655. },
  656. // 发送商品
  657. async toGoods(e) {
  658. const that = this;
  659. let user = that.user
  660. if (user._id) {
  661. let res;
  662. // 商品
  663. res = await that.$api(`/viewGoods/goodsDetail`, `POST`, {
  664. id: e._id
  665. });
  666. if (res.errcode == '0') {
  667. let indexSpecs;
  668. // 显示最低价格的规格信息,不考虑库存问题
  669. if (res.data.specs && res.data.specs.length > 0) {
  670. // 规格排序
  671. indexSpecs = res.data.specs.sort(function(a, b) {
  672. let i, j;
  673. if (a.price) i = 'price'
  674. else i = 'sell_money'
  675. if (b.price) j = 'price'
  676. else j = 'sell_money'
  677. return a[i] - b[j];
  678. })
  679. }
  680. let act = res.data.act.map(i => {
  681. return i.tag
  682. })
  683. let goodsInfo = {
  684. "file": res.data && res.data.goods && res.data.goods.file && res.data.goods
  685. .file[0]
  686. .url,
  687. "name": res.data && res.data.goods && res.data.goods.name,
  688. "spec": indexSpecs[0],
  689. "act": act,
  690. }
  691. //时间间隔处理
  692. let data = {
  693. "speaker": user._id,
  694. "content": e._id,
  695. "time": moment().format('YYYY-MM-DD HH:mm:ss'),
  696. "msg_type": '2',
  697. };
  698. if (!that.id) data.shop = that.shop_id
  699. else data.room = that.id
  700. res = await that.$api(`/chatRecord`, `POST`, data, 'chat');
  701. if (res.errcode == '0') {
  702. res.data.goodsInfo = goodsInfo
  703. res.data.is_send = '1'
  704. that.msgList.push(res.data);
  705. } else {
  706. uni.showToast({
  707. title: res.errmsg,
  708. icon: 'none'
  709. })
  710. }
  711. }
  712. // 跳转到最后一条数据 与前面的:id进行对照
  713. that.goBottom();
  714. that.toClose();
  715. } else {
  716. uni.showToast({
  717. title: '未登录账号无法发送消息 ,请及时登录!',
  718. icon: 'none'
  719. })
  720. }
  721. },
  722. // 分页
  723. toPage(e) {
  724. const that = this;
  725. let list = that.list;
  726. let limit = that.limit;
  727. if (that.total > list.length) {
  728. uni.showLoading({
  729. title: '加载中',
  730. mask: true
  731. })
  732. let page = that.page + 1;
  733. that.$set(that, `page`, page)
  734. let skip = page * limit;
  735. that.$set(that, `skip`, skip)
  736. if (that.popupShow == '1') that.sendGoods();
  737. else that.sendOrder();
  738. uni.hideLoading();
  739. }
  740. },
  741. // 发送订单
  742. async sendOrder() {
  743. const that = this;
  744. let user = that.user;
  745. let status = that.status;
  746. let info = {
  747. skip: that.skip,
  748. limit: that.limit,
  749. customer: user._id,
  750. shop: that.shop._id || that.shop_id,
  751. status: status
  752. }
  753. let res;
  754. if (status == '0') {
  755. res = await that.$api(`/order`, 'GET', {
  756. ...info,
  757. });
  758. } else {
  759. res = await that.$api(`/orderDetail`, 'GET', {
  760. ...info,
  761. });
  762. }
  763. if (res.errcode == '0') {
  764. let list = [...that.list, ...res.data];
  765. for (let val of list) {
  766. val.zhStatus = that.searchStatus(val.status)
  767. }
  768. that.$set(that, `list`, list);
  769. that.$set(that, `total`, res.total)
  770. that.$set(that, `popupShow`, '2')
  771. that.$refs.specShow.open();
  772. } else {
  773. uni.showToast({
  774. title: res.errmsg,
  775. icon: 'none'
  776. })
  777. }
  778. },
  779. // 发送订单
  780. async toOrder(e) {
  781. const that = this;
  782. let user = that.user
  783. if (user._id) {
  784. let res;
  785. // 订单
  786. if (e.status == '0') res = await that.$api(`/order/${e._id}`)
  787. else res = await that.$api(`/orderDetail/${e._id}`);
  788. if (res.errcode == '0') {
  789. let status = that.statusList.find(i => i.value == res.data.status)
  790. // 过滤店铺订单
  791. let shop_goods;
  792. if (e.status != '0') {
  793. // 已支付订单
  794. shop_goods = res.data.goods
  795. } else {
  796. // 未支付订单
  797. if (!that.id) shop_goods = res.data.goods.filter(i => i.shop == that.shop_id)
  798. else shop_goods = res.data.goods.filter(i => i.shop == that.shop._id)
  799. if (shop_goods.length > 0) shop_goods = shop_goods[0].goods
  800. }
  801. let ordernfo = {
  802. "no": res.data && res.data.no,
  803. "goods": shop_goods,
  804. "status": status.label || '暂无',
  805. "is_status": res.data.status
  806. }
  807. //时间间隔处理
  808. let data = {
  809. "speaker": user._id,
  810. "content": e._id,
  811. "time": moment().format('YYYY-MM-DD HH:mm:ss'),
  812. "msg_type": '3',
  813. };
  814. if (!that.id) data.shop = that.shop_id
  815. else data.room = that.id
  816. res = await that.$api(`/chatRecord`, `POST`, data, 'chat');
  817. if (res.errcode == '0') {
  818. res.data.ordernfo = ordernfo
  819. res.data.is_send = '1'
  820. that.msgList.push(res.data);
  821. } else {
  822. uni.showToast({
  823. title: res.errmsg,
  824. icon: 'none'
  825. })
  826. }
  827. }
  828. // 跳转到最后一条数据 与前面的:id进行对照
  829. that.goBottom();
  830. that.toClose();
  831. } else {
  832. uni.showToast({
  833. title: '未登录账号无法发送消息 ,请及时登录!',
  834. icon: 'none'
  835. })
  836. }
  837. },
  838. // 查询状态
  839. searchStatus(e) {
  840. const that = this;
  841. let data = that.statusList.find((i) => i.value == e);
  842. if (data) return data.label
  843. else return '暂无'
  844. },
  845. // 选择选项卡
  846. tabsChange(e) {
  847. const that = this;
  848. that.$set(that.tabs, `active`, e.active)
  849. that.$set(that, `status`, e.active);
  850. that.$set(that, `list`, [])
  851. that.$set(that, `skip`, 0)
  852. that.$set(that, `limit`, 6)
  853. that.$set(that, `page`, 0)
  854. that.sendOrder()
  855. },
  856. // 关闭弹框
  857. toClose() {
  858. const that = this;
  859. that.$refs.specShow.close();
  860. that.$set(that, `list`, [])
  861. that.$set(that, `skip`, 0)
  862. that.$set(that, `limit`, 6)
  863. that.$set(that, `page`, 0)
  864. },
  865. // 店铺
  866. toShop() {
  867. const that = this;
  868. let id = that.shop._id
  869. uni.navigateTo({
  870. url: `/pagesHome/shop/index?id=${id}`
  871. })
  872. },
  873. // 查看详情
  874. toView(e) {
  875. const that = this;
  876. if (e.msg_type == '2') {
  877. let id = e.content;
  878. uni.navigateTo({
  879. url: `/pagesHome/order/detail?id=${id}`
  880. })
  881. } else {
  882. let status = e.ordernfo.is_status;
  883. uni.navigateTo({
  884. url: `/pagesMy/order/index?status=${status}`
  885. })
  886. }
  887. },
  888. //输入框高度
  889. heights(e) {
  890. const that = this;
  891. that.goBottom();
  892. },
  893. // 滚动到底部
  894. async goBottom() {
  895. const that = this;
  896. that.scrollToView = '';
  897. let lastItem = that.msgList.at(-1);
  898. that.$nextTick(function() {
  899. that.scrollToView = 'msg' + (lastItem._id)
  900. })
  901. },
  902. // 下拉刷新分页
  903. getFresh(e) {
  904. const that = this;
  905. that.$set(that, `triggered`, true)
  906. that.$set(that, `is_img`, false)
  907. let msgList = that.msgList;
  908. let limit = that.limit;
  909. setTimeout(() => {
  910. if (that.total > msgList.length) {
  911. uni.showLoading({
  912. title: '加载中',
  913. mask: true
  914. })
  915. let page = that.page + 1;
  916. that.$set(that, `page`, page)
  917. let skip = page * limit;
  918. that.$set(that, `skip`, skip)
  919. that.$set(that, `is_bottom`, false)
  920. that.search();
  921. uni.hideLoading();
  922. } else {
  923. uni.showToast({
  924. title: `没有更多聊天记录了`,
  925. icon: 'none'
  926. })
  927. }
  928. that.triggered = false;
  929. }, 1000)
  930. },
  931. clearPage() {
  932. const that = this;
  933. that.$set(that, `msgList`, [])
  934. that.$set(that, `skip`, 0)
  935. that.$set(that, `limit`, 6)
  936. that.$set(that, `page`, 0)
  937. },
  938. }
  939. }
  940. </script>
  941. <style lang="scss">
  942. .main {
  943. display: flex;
  944. flex-direction: column;
  945. width: 100vw;
  946. height: 100vh;
  947. overflow: hidden;
  948. .one {
  949. position: relative;
  950. flex-grow: 1;
  951. .scroll-view {
  952. .chat-ls {
  953. padding: 2vw 2vw 0 2vw;
  954. .chat-time {
  955. font-size: 24rpx;
  956. color: rgba(39, 40, 50, 0.3);
  957. line-height: 34rpx;
  958. padding: 10rpx 0rpx;
  959. text-align: center;
  960. }
  961. .msg-m {
  962. display: flex;
  963. padding: 20rpx 0;
  964. .user-img {
  965. flex: none;
  966. width: 80rpx;
  967. height: 80rpx;
  968. border-radius: 40rpx;
  969. border: 1px solid #c0c0c0;
  970. }
  971. .message {
  972. flex: none;
  973. max-width: 480rpx;
  974. }
  975. .img {
  976. margin: 0 20rpx;
  977. }
  978. .msg-text {
  979. font-size: 32rpx;
  980. color: rgba(39, 40, 50, 1);
  981. line-height: 44rpx;
  982. padding: 18rpx 24rpx;
  983. word-break: break-all;
  984. }
  985. .msg-img {
  986. max-width: 400rpx;
  987. border-radius: 20rpx;
  988. }
  989. .msg-goods {
  990. display: flex;
  991. padding: 10rpx;
  992. background-color: #f0f0f0;
  993. border-radius: 20rpx 0rpx 20rpx 20rpx;
  994. .image {
  995. width: 100rpx;
  996. height: 100rpx;
  997. border-radius: 10rpx;
  998. }
  999. .goods_1 {
  1000. width: 350rpx;
  1001. margin: 0 0 0 10rpx;
  1002. .name {
  1003. font-size: 14px;
  1004. }
  1005. .money {
  1006. .money_1 {
  1007. color: #23B67A;
  1008. font-size: 16px;
  1009. padding: 0 1vw 0 0;
  1010. font-weight: bold;
  1011. text {
  1012. font-size: 12px;
  1013. }
  1014. }
  1015. .money_2 {
  1016. font-size: 16px;
  1017. padding: 0 1vw 0 0;
  1018. color: #ff0000;
  1019. font-weight: bold;
  1020. text {
  1021. font-size: 12px;
  1022. }
  1023. }
  1024. .money_2:last-child {
  1025. font-size: 14px;
  1026. color: #858585;
  1027. text-decoration: line-through;
  1028. }
  1029. }
  1030. .act {
  1031. .label {
  1032. font-size: 12px;
  1033. color: #FFA500;
  1034. border: 1px solid #FFA500;
  1035. border-radius: 5px;
  1036. padding: 0 1vw;
  1037. margin: 0 1vw 0 0;
  1038. }
  1039. }
  1040. .button {
  1041. text-align: right;
  1042. margin: 5rpx 0 10rpx 0;
  1043. text {
  1044. font-size: 12px;
  1045. padding: 10rpx;
  1046. border-radius: 10rpx;
  1047. color: #FF4500;
  1048. background-color: #FFF8DC;
  1049. }
  1050. }
  1051. }
  1052. }
  1053. .msg-order {
  1054. width: 460rpx;
  1055. padding: 10rpx;
  1056. background-color: #f0f0f0;
  1057. border-radius: 20rpx 0rpx 20rpx 20rpx;
  1058. .order_1 {
  1059. display: flex;
  1060. flex-wrap: wrap;
  1061. .image {
  1062. width: 100rpx;
  1063. height: 100rpx;
  1064. border-radius: 10rpx;
  1065. margin: 0 5rpx 0 0;
  1066. border: 1rpx solid #858585;
  1067. }
  1068. }
  1069. .order_2 {
  1070. .no {
  1071. font-size: 12px;
  1072. }
  1073. .status {
  1074. display: flex;
  1075. justify-content: space-between;
  1076. margin: 5rpx 0;
  1077. text {
  1078. padding: 1rpx 2rpx;
  1079. border-radius: 5px;
  1080. font-size: 12px;
  1081. color: #ff0000;
  1082. }
  1083. .button {
  1084. text-align: right;
  1085. text {
  1086. font-size: 12px;
  1087. padding: 10rpx;
  1088. border-radius: 10rpx;
  1089. color: #FF4500;
  1090. background-color: #FFF8DC;
  1091. }
  1092. }
  1093. }
  1094. }
  1095. }
  1096. }
  1097. .msg-left {
  1098. flex-direction: row;
  1099. .msg-text {
  1100. word-break: break-all;
  1101. margin-left: 16rpx;
  1102. background-color: #f1f1f1;
  1103. border-radius: 0rpx 20rpx 20rpx 20rpx;
  1104. }
  1105. .ms-img {
  1106. margin-left: 16rpx;
  1107. }
  1108. }
  1109. .msg-right {
  1110. flex-direction: row-reverse;
  1111. .msg-text {
  1112. margin-right: 16rpx;
  1113. background-color: rgba(255, 228, 49, 0.8);
  1114. border-radius: 20rpx 0rpx 20rpx 20rpx;
  1115. }
  1116. .ms-img {
  1117. margin-right: 16rpx;
  1118. }
  1119. }
  1120. }
  1121. }
  1122. }
  1123. .two {
  1124. background-color: #f0f0f0;
  1125. border-top: 1px solid rgba(39, 40, 50, 0.1);
  1126. }
  1127. }
  1128. .uni-popup {
  1129. z-index: 9999 !important;
  1130. }
  1131. .popup {
  1132. display: flex;
  1133. flex-direction: column;
  1134. width: 100vw;
  1135. height: 80vh;
  1136. .close {
  1137. text-align: right;
  1138. padding: 2vw;
  1139. }
  1140. .info_1 {
  1141. position: relative;
  1142. display: flex;
  1143. flex-direction: column;
  1144. height: 74vh;
  1145. }
  1146. }
  1147. .scroll-view {
  1148. position: absolute;
  1149. top: 0;
  1150. left: 0;
  1151. right: 0;
  1152. bottom: 0;
  1153. .list-scroll-view {
  1154. display: flex;
  1155. flex-direction: column;
  1156. }
  1157. }
  1158. </style>