detail.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  1. <template>
  2. <!-- #ifdef H5 -->
  3. <view>
  4. <Loading
  5. :type="3"
  6. :loadStatus="loadStatus"
  7. :showText="errorText"
  8. />
  9. <zj-page-layout
  10. v-if="detail"
  11. :hasFooter="true"
  12. :isScroll="true"
  13. :refresherTriggered="refresherTriggered"
  14. @refresherrefresh="refresherrefresh">
  15. <view class="top-container">
  16. <view class="user">
  17. <image src="@/static/common/logo.png"></image>
  18. <view class="info">
  19. <view class="name">{{detail.userName}}</view>
  20. <view class="phone">联系电话:{{detail.phone}}</view>
  21. </view>
  22. </view>
  23. <view class="btns">
  24. <u-button type="warning" text="分享好友" class="share"></u-button>
  25. <u-button type="error" text="立即联系" class="contact" @click="toContact" v-if="!isMine"></u-button>
  26. <u-button type="primary" text="立即购买" class="buy" @click="toBuy" v-if="!isMine"></u-button>
  27. </view>
  28. </view>
  29. <view class="info-container">
  30. <view class="title">
  31. <view class="tit">{{detail.goodsTitle}}</view>
  32. <view class="price">{{detail.goodsAmount | priceFilter2}}</view>
  33. </view>
  34. <view class="des">{{detail.content}}</view>
  35. <view class="tags">
  36. <view class="it">{{detail.brand}}</view>
  37. <view class="it">{{detail.power}}</view>
  38. <view class="it">{{detail.energy}}</view>
  39. </view>
  40. <view class="info">
  41. <text>{{detail.goodsCreateTime}}</text>
  42. </view>
  43. <view class="bottom">
  44. <view class="left-location">{{detail.address}}</view>
  45. <view class="right-stats">
  46. <view class="it">
  47. <text class="iconfont icon-liulan"></text>
  48. <text class="text">{{detail.visit || 0}}浏览</text>
  49. </view>
  50. <view class="it" :class="detail.isLike ? 'active':''" @tap="handelLickCollect(1)">
  51. <text class="iconfont icon-dianzan"></text>
  52. <text class="text">点赞</text>
  53. </view>
  54. <view class="it" :class="detail.isCollect ? 'active':''" @tap="handelLickCollect(2)">
  55. <text class="iconfont icon-shoucang"></text>
  56. <text class="text">收藏</text>
  57. </view>
  58. </view>
  59. </view>
  60. </view>
  61. <view class="imgs-container">
  62. <image :src="imageUrl + item.imgUrl" v-for="(item, index) in detail.goodsFiles" :key="index"></image>
  63. </view>
  64. <view class="remark-container">
  65. <view class="title">
  66. <view class="tit">全部留言</view>
  67. <view class="right" v-if="!isMine">内容违规,我要举报</view>
  68. </view>
  69. <view class="item" v-for="(item, index) in remarkList" :key="index">
  70. <view class="top">
  71. <image src="@/static/common/logo.png"></image>
  72. <view class="user">
  73. <view class="name">{{item.userName}}</view>
  74. <view class="time">{{item.createTime}}</view>
  75. </view>
  76. </view>
  77. <view class="content">
  78. <view class="left">{{item.message}}</view>
  79. <view class="right" @tap="handelReply(item)"><text class="iconfont icon-bianji"></text><text>回复</text></view>
  80. </view>
  81. <view class="reply">
  82. <view class="it" v-for="(it, idx) in item.goodsMessageList" :key="idx" @tap="handelReply(it)">{{it.userName}}回复{{it.replyNickName}}:{{it.message}}</view>
  83. </view>
  84. </view>
  85. </view>
  86. <template slot="footer">
  87. <view class="bottom-container">
  88. <u-button text="留言" type="primary" shape="circle" @click="openRemark()"></u-button>
  89. <u-button text="操作" type="primary" shape="circle" @click="isShowActionDialog = true" v-if="isMine"></u-button>
  90. </view>
  91. </template>
  92. </zj-page-layout>
  93. <zj-dialog-remark
  94. ref="remarkDialog"
  95. :isShow="isShowRemarkDialog"
  96. @close="isShowRemarkDialog = false"
  97. @confirm="confirmRemark">
  98. </zj-dialog-remark>
  99. <u-action-sheet
  100. :actions="actionList"
  101. :title="'操作'"
  102. :show="isShowActionDialog"
  103. @close="isShowActionDialog = false"
  104. @select="selectAction">
  105. </u-action-sheet>
  106. </view>
  107. <!-- #endif -->
  108. <!-- #ifndef H5 -->
  109. <web-view :src="webViewHref('/pages/goods/detail', pam)"></web-view>
  110. <!-- #endif -->
  111. </template>
  112. <script>
  113. // #ifdef H5
  114. import zjDialogRemark from '@/components/zj-dialog/zj-dialog-remark.vue';
  115. export default {
  116. components: {
  117. zjDialogRemark
  118. },
  119. data() {
  120. return {
  121. id: null,
  122. detail: null,
  123. remarkList: [],
  124. imageUrl: this.$imageUrl,
  125. loadStatus: 0,
  126. errorText: '',
  127. refresherTriggered: false,
  128. isShowRemarkDialog: false,
  129. actionList: [
  130. {name: '已卖出'},
  131. {name: '下架'},
  132. {name: '重新上架'},
  133. {name: '编辑'},
  134. ],
  135. isShowActionDialog: false,
  136. replyId: '',
  137. }
  138. },
  139. computed: {
  140. isMine() {
  141. return this.$store.state.user.userId === this.detail.userId;
  142. }
  143. },
  144. onLoad({id}) {
  145. this.id = id;
  146. this.getDetail();
  147. this.getRemarkList();
  148. },
  149. methods: {
  150. getDetail() {
  151. this.$api.postJson('/goods/detail', {
  152. id: this.id
  153. }).then(res => {
  154. this.detail = res.data;
  155. this.loadStatus = 0;
  156. }).catch(res => {
  157. this.errorText = res.message;
  158. this.loadStatus = 2;
  159. }).finally(res => {
  160. this.refresherTriggered = false;
  161. })
  162. },
  163. refresherrefresh() {
  164. this.refresherTriggered = true;
  165. this.getDetail();
  166. this.getRemarkList();
  167. },
  168. // 处理点赞留言
  169. handelLickCollect(type) {
  170. let status = false;
  171. if(type === 1) {
  172. status = this.detail.isLike || false;
  173. }else {
  174. status = this.detail.isCollect || false;
  175. }
  176. this.$api.postJson('/likeOrCollect/likeOrCollect', {
  177. userId: this.$store.state.user.userId,
  178. goodsId: this.id,
  179. type,
  180. operate: !status
  181. }).then(res => {
  182. this.getDetail();
  183. })
  184. },
  185. // 去联系
  186. toContact() {
  187. this.$navToPage({
  188. url: `/pages/message/msgView?goodsId=${this.id}`
  189. })
  190. },
  191. // 去购买
  192. toBuy() {
  193. this.$navToPage({
  194. url: `/pages/goods/order?id=${this.id}`
  195. })
  196. },
  197. // 获取留言列表
  198. getRemarkList() {
  199. this.$api.postJson('/message/list2', {
  200. userId: this.$store.state.user.userId,
  201. goodsId: this.id,
  202. pageNum: 1,
  203. pageSize: -1,
  204. }).then(res => {
  205. this.remarkList = res.data.records;
  206. })
  207. },
  208. openRemark(replyItem) {
  209. this.$refs.remarkDialog.setValue(replyItem);
  210. this.isShowRemarkDialog = true;
  211. },
  212. // 提交留言
  213. confirmRemark(val) {
  214. this.$api.postJson('/message/add', {
  215. userId: this.$store.state.user.userId,
  216. goodsId: this.id,
  217. message: val,
  218. replyId: this.replyId,
  219. }).then(res => {
  220. this.replyId = '';
  221. this.isShowRemarkDialog = false;
  222. this.getRemarkList();
  223. })
  224. },
  225. // 回复留言
  226. handelReply(item) {
  227. this.replyId = item.id;
  228. this.openRemark(item);
  229. },
  230. selectAction() {
  231. }
  232. }
  233. }
  234. // #endif
  235. // #ifndef H5
  236. import zjDialogRemark from '@/components/zj-dialog/zj-dialog-remark.vue';
  237. export default {
  238. components: {
  239. zjDialogRemark
  240. },
  241. data() {
  242. return {
  243. pam: {},
  244. }
  245. },
  246. onLoad(pam) {
  247. this.pam = pam;
  248. },
  249. }
  250. // #endif
  251. </script>
  252. <style lang="scss" scoped>
  253. .top-container {
  254. background: #ffffff;
  255. margin-top: 30rpx;
  256. padding: 30rpx;
  257. .user {
  258. display: flex;
  259. align-items: center;
  260. image {
  261. width: 88rpx;
  262. height: 88rpx;
  263. border-radius: 50%;
  264. }
  265. .info {
  266. margin-left: 12rpx;
  267. .name {
  268. font-size: 28rpx;
  269. }
  270. .phone {
  271. font-size: 24rpx;
  272. margin-top: 12rpx;
  273. }
  274. }
  275. }
  276. .btns {
  277. display: flex;
  278. justify-content: space-between;
  279. margin-top: 30rpx;
  280. ::v-deep .u-button {
  281. width: 188rpx;
  282. height: 68rpx;
  283. line-height: 68rpx;
  284. font-size: 28rpx;
  285. color: #ffffff;
  286. margin: 0;
  287. }
  288. .share {
  289. }
  290. }
  291. }
  292. .info-container {
  293. background: #ffffff;
  294. padding: 30rpx;
  295. margin-top: 30rpx;
  296. .title {
  297. display: flex;
  298. justify-content: space-between;
  299. .tit {
  300. font-size: 32rpx;
  301. }
  302. .price {
  303. font-size: 28rpx;
  304. color: $assist-color;
  305. }
  306. }
  307. .des {
  308. margin-top: 12rpx;
  309. font-size: 28rpx;
  310. color: $reg-font;
  311. }
  312. .tags {
  313. margin-top: 12rpx;
  314. display: flex;
  315. .it {
  316. background: #f1f1f1;
  317. font-size: 20rpx;
  318. margin-right: 20rpx;
  319. padding: 8rpx 12rpx;
  320. border-radius: 8rpx;
  321. }
  322. }
  323. .info {
  324. display: flex;
  325. margin-top: 20rpx;
  326. text {
  327. font-size: 24rpx;
  328. color: $sec-font;
  329. }
  330. }
  331. .bottom {
  332. border-top: 1px solid #eaeaea;
  333. margin-top: 20rpx;
  334. padding-top: 20rpx;
  335. display: flex;
  336. align-items: center;
  337. justify-content: space-between;
  338. .left-location {
  339. font-size: 24rpx;
  340. color: $sec-font;
  341. }
  342. .right-stats {
  343. display: flex;
  344. align-items: center;
  345. .it {
  346. display: flex;
  347. align-items: center;
  348. margin-left: 16rpx;
  349. .iconfont {
  350. font-size: 28rpx;
  351. color: $sec-font;
  352. }
  353. .text {
  354. font-size: 24rpx;
  355. margin-left: 4rpx;
  356. color: $sec-font;
  357. }
  358. &.active {
  359. .iconfont {
  360. color: $theme-color;
  361. }
  362. .text {
  363. color: $theme-color;
  364. }
  365. }
  366. }
  367. }
  368. }
  369. }
  370. .imgs-container {
  371. margin-top: 30rpx;
  372. image {
  373. width: 100%;
  374. }
  375. }
  376. .remark-container {
  377. background: #ffffff;
  378. margin-top: 30rpx;
  379. padding: 30rpx;
  380. .title {
  381. display: flex;
  382. align-items: center;
  383. justify-content: space-between;
  384. .tit {
  385. font-weight: 500;
  386. }
  387. .right {
  388. font-size: 24rpx;
  389. color: $sec-font;
  390. }
  391. }
  392. .item {
  393. padding: 30rpx 0;
  394. border-bottom: 1px solid #eaeaea;
  395. &:last-child {
  396. border: none;
  397. }
  398. .top {
  399. display: flex;
  400. image {
  401. width: 88rpx;
  402. height: 88rpx;
  403. border-radius: 50%;
  404. flex-shrink: 0;
  405. }
  406. .user {
  407. margin-left: 20rpx;
  408. flex: 1;
  409. display: flex;
  410. flex-direction: column;
  411. justify-content: center;
  412. .name {
  413. }
  414. .time {
  415. color: $sec-font;
  416. font-size: 24rpx;
  417. margin-top: 8rpx;
  418. }
  419. }
  420. .status {
  421. color: $assist-color;
  422. }
  423. }
  424. .content {
  425. margin-top: 20rpx;
  426. display: flex;
  427. justify-content: space-between;
  428. align-items: center;
  429. .left {
  430. font-size: 28rpx;
  431. }
  432. .right {
  433. flex-shrink: 0;
  434. font-size: 24rpx;
  435. background: #eaeaea;
  436. display: flex;
  437. align-items: center;
  438. padding: 8rpx 12rpx;
  439. margin-left: 40rpx;
  440. border-radius: 8rpx;
  441. .iconfont {
  442. font-size: 24rpx;
  443. margin-right: 4rpx;
  444. }
  445. }
  446. }
  447. .reply {
  448. .it {
  449. margin-top: 20rpx;
  450. font-size: 24rpx;
  451. color: $sec-font;
  452. border-left: 4rpx solid $theme-color;
  453. padding-left: 8rpx;
  454. }
  455. }
  456. }
  457. }
  458. .bottom-container {
  459. padding: 20rpx 30rpx;
  460. display: flex;
  461. align-items: center;
  462. justify-content: flex-end;
  463. .u-button {
  464. width: auto;
  465. height: 60rpx;
  466. margin: 0;
  467. margin-left: 20rpx;
  468. }
  469. }
  470. </style>