ShowGoodsDetail.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. <template>
  2. <div>
  3. <div class="item-intro-show">
  4. <!-- <div class="item-intro-recommend">
  5. <div class="item-recommend-title">
  6. <p>店铺热销</p>
  7. </div>
  8. <div class="item-intro-recommend-column">
  9. <div class="item-recommend-column" v-for="(item, index) in hotList" :key="index">
  10. <div class="item-recommend-img">
  11. <img :src="item.img" alt="">
  12. </div>
  13. <div class="item-recommend-intro">
  14. <span>
  15. <span class="item-recommend-top-num">{{index + 1}}</span> 热销{{item.sale}}件</span>
  16. <span class="item-recommend-price">¥{{item.price | unitPrice}}</span>
  17. </div>
  18. </div>
  19. </div>
  20. </div> -->
  21. <div class="item-intro-detail" ref="itemIntroDetail">
  22. <div class="item-intro-nav item-tabs">
  23. <Tabs :animated="false" @on-click="tabClick">
  24. <TabPane label="商品介绍">
  25. <div class="item-intro-img" ref="itemIntroGoods">
  26. <div v-html="skuDetail.intro" v-if="skuDetail.intro"></div>
  27. <div v-else style="margin:20px;">暂无商品介绍</div>
  28. </div>
  29. </TabPane>
  30. <TabPane label="商品评价">
  31. <div class="remarks-container" ref="itemGoodsComment">
  32. <div class="remarks-analyse-box">
  33. <div class="remarks-analyse-goods">
  34. <i-circle :percent="skuDetail.grade || 100" stroke-color="#5cb85c">
  35. <span class="remarks-analyse-num">{{skuDetail.grade || 100}}%</span>
  36. <p class="remarks-analyse-title">好评率</p>
  37. </i-circle>
  38. </div>
  39. </div>
  40. <div class="remarks-bar">
  41. <span @click="searchByGrade('')" :class="{selectedBar: commentParams.grade === ''}">全部({{commentTypeNum.all}})</span>
  42. <span @click="searchByGrade('GOOD')" :class="{selectedBar: commentParams.grade === 'GOOD'}">好评({{commentTypeNum.good}})</span>
  43. <span @click="searchByGrade('MODERATE')" :class="{selectedBar: commentParams.grade === 'MODERATE'}">中评({{commentTypeNum.moderate}})</span>
  44. <span @click="searchByGrade('WORSE')" :class="{selectedBar: commentParams.grade === 'WORSE'}">差评({{commentTypeNum.worse}})</span>
  45. </div>
  46. <div style="text-align: center;margin-top: 20px;" v-if="commentList.length === 0">
  47. 暂无评价数据
  48. </div>
  49. <div class="remarks-box" v-for="(item,index) in commentList" :key="index" v-else>
  50. <div class="remarks-user">
  51. <Avatar :src="item.memberProfile" />
  52. <span class="remarks-user-name">{{item.memberName | secrecyMobile}}</span>
  53. </div>
  54. <div class="remarks-content-box">
  55. <p>
  56. <Rate disabled :value="Number(item.descriptionScore)" allow-half class="remarks-star"></Rate>
  57. </p>
  58. <p class="remarks-content">{{item.content}}</p>
  59. <div class="comment-img" v-if="item.images">
  60. <div v-for="(img, imgIndex) in item.images.split(',')"
  61. @click="previewImg(img, item)"
  62. :class="{borderColor:img === item.previewImg}"
  63. :key="imgIndex">
  64. <img :src="img" alt="">
  65. </div>
  66. </div>
  67. <div class="preview-img" v-if="item.previewImg" @click.prevent="hidePreviewImg(item)">
  68. <div>
  69. <span @click.stop="rotatePreviewImg(0, item)"><Icon type="md-refresh" />左转</span>
  70. <span @click.stop="rotatePreviewImg(1, item)"><Icon type="md-refresh" />右转</span>
  71. </div>
  72. <img :src="item.previewImg" :style="{transform:`rotate(${item.deg}deg)`}" width="198" alt="">
  73. </div>
  74. <p class="remarks-sub">
  75. <span class="remarks-item">{{item.goodsName}}</span>
  76. <span class="remarks-time">{{item.createTime}}</span>
  77. </p>
  78. </div>
  79. </div>
  80. <div class="remarks-page">
  81. <Page :total="commentTotal" size="small"
  82. @on-change="changePageNum"
  83. @on-page-size-change="changePageSize"
  84. :page-size="commentParams.pageSize"
  85. ></Page>
  86. </div>
  87. </div>
  88. </TabPane>
  89. <!-- <TabPane label="商品问答">
  90. <ShowGoodsQuestion/>
  91. </TabPane> -->
  92. </Tabs>
  93. </div>
  94. </div>
  95. </div>
  96. </div>
  97. </template>
  98. <script>
  99. import ShowGoodsQuestion from '@/components/goodsDetail/ShowGoodsQuestion';
  100. import { goodsComment, goodsCommentNum } from '@/api/member.js';
  101. export default {
  102. name: 'ShowGoodsDetail',
  103. props: {
  104. detail: { // 商品详情
  105. type: Object,
  106. default: null
  107. }
  108. },
  109. data () {
  110. return {
  111. commentList: [], // 评论列表
  112. commentParams: { // 评论传参
  113. pageNumber: 1,
  114. pageSize: 10,
  115. grade: '',
  116. goodsId: ''
  117. },
  118. commentTypeNum: {}, // 评论数量,包括好中差分别的数量
  119. commentTotal: 0, // 评论总数
  120. onceFlag: true // 只调用一次
  121. };
  122. },
  123. computed: {
  124. skuDetail () {
  125. return this.detail.data;
  126. }
  127. },
  128. methods: {
  129. changeHeight (name) {
  130. let heightCss = window.getComputedStyle(this.$refs[name]).height;
  131. heightCss = parseInt(heightCss.substr(0, heightCss.length - 2)) + 89;
  132. this.$refs.itemIntroDetail.style.height = heightCss + 'px';
  133. },
  134. changePageNum (val) {
  135. this.commentParams.pageNumber = val;
  136. this.getList();
  137. },
  138. changePageSize (val) {
  139. this.commentParams.pageNumber = 1;
  140. this.commentParams.pageSize = val;
  141. this.getList();
  142. },
  143. getList () { // 获取评论列表
  144. this.commentParams.goodsId = this.skuDetail.goodsId;
  145. goodsComment(this.commentParams).then(res => {
  146. if (res.success) {
  147. this.commentList = res.result.records;
  148. this.commentTotal = res.result.total;
  149. }
  150. });
  151. goodsCommentNum(this.skuDetail.goodsId).then(res => {
  152. if (res.success) {
  153. this.commentTypeNum = res.result;
  154. }
  155. });
  156. },
  157. searchByGrade (grade) {
  158. this.$set(this.commentParams, 'grade', grade);
  159. this.commentParams.pageNumber = 1;
  160. this.getList();
  161. },
  162. tabClick (name) {
  163. if (name === 0) {
  164. this.$nextTick(() => {
  165. this.changeHeight('itemIntroGoods')
  166. });
  167. } else {
  168. this.$nextTick(() => {
  169. this.changeHeight('itemGoodsComment')
  170. });
  171. }
  172. },
  173. previewImg (img, item) { // 预览图片
  174. this.$set(item, 'previewImg', img);
  175. this.$nextTick(() => {
  176. this.changeHeight('itemGoodsComment')
  177. });
  178. },
  179. hidePreviewImg (item) { // 隐藏预览图片
  180. this.$set(item, 'previewImg', '');
  181. this.$nextTick(() => {
  182. this.changeHeight('itemGoodsComment')
  183. });
  184. },
  185. rotatePreviewImg (type, item) { // 图片旋转
  186. if (type) {
  187. if (item.deg) {
  188. this.$set(item, 'deg', item.deg + 90);
  189. } else {
  190. this.$set(item, 'deg', 90);
  191. }
  192. } else {
  193. if (item.deg) {
  194. this.$set(item, 'deg', item.deg - 90);
  195. } else {
  196. this.$set(item, 'deg', -90);
  197. }
  198. }
  199. },
  200. handleScroll () {
  201. if (this.onceFlag) {
  202. this.$nextTick(() => {
  203. this.changeHeight('itemIntroGoods')
  204. });
  205. this.onceFlag = false
  206. }
  207. }
  208. },
  209. mounted () {
  210. this.$nextTick(() => {
  211. setTimeout(this.changeHeight('itemIntroGoods'), 2000);
  212. });
  213. window.addEventListener('scroll', this.handleScroll)
  214. this.getList();
  215. },
  216. components: {
  217. ShowGoodsQuestion
  218. }
  219. };
  220. </script>
  221. <style scoped lang="scss">
  222. /***************商品详情介绍和推荐侧边栏开始***************/
  223. .item-intro-show{
  224. width: 1200px;
  225. margin: 15px auto;
  226. display: flex;
  227. flex-direction: row;
  228. }
  229. .item-intro-recommend{
  230. width: 200px;
  231. display: flex;
  232. flex-direction: column;
  233. }
  234. .item-intro-recommend-column{
  235. display: flex;
  236. flex-direction: column;
  237. box-shadow: 0px 0px 5px #999;
  238. }
  239. .item-recommend-title{
  240. width: 100%;
  241. height: 38px;
  242. font-size: 16px;
  243. line-height: 38px;
  244. color: #fff;
  245. background-color: $theme_color;
  246. box-shadow: 0px 0px 5px $theme_color;
  247. text-align: center;
  248. }
  249. .item-recommend-column{
  250. margin-top: 15px;
  251. }
  252. .item-recommend-intro{
  253. padding: 5px 15px;
  254. display: flex;
  255. flex-direction: row;
  256. justify-content: space-between;
  257. font-size: 12px;
  258. color: #999;
  259. cursor: pointer;
  260. }
  261. .item-recommend-img{
  262. width: 80%;
  263. margin: 0px auto;
  264. cursor: pointer;
  265. }
  266. .item-recommend-img img{
  267. width: 100%;
  268. }
  269. .item-recommend-top-num{
  270. color: #fff;
  271. margin: 0px 2px;
  272. padding: 1px 5px;
  273. border-radius: 12px;
  274. background-color: $theme_color;
  275. }
  276. .item-recommend-price{
  277. color: $theme_color;
  278. font-weight: bolder;
  279. }
  280. .item-intro-detail{
  281. margin: 0 30px;
  282. // min-height: 1500px;
  283. width: 100%;
  284. }
  285. .item-intro-nav{
  286. width: 100%;
  287. height: 38px;
  288. background-color: #F7F7F7;
  289. // border-bottom: 1px solid $theme_color;
  290. }
  291. .item-intro-nav ul{
  292. margin: 0px;
  293. padding: 0px;
  294. list-style: none;
  295. }
  296. .item-intro-nav li{
  297. float: left;
  298. height: 100%;
  299. width: 120px;
  300. line-height: 38px;
  301. text-align: center;
  302. color: $theme_color;
  303. }
  304. .item-intro-nav li:first-child{
  305. background-color: $theme_color;
  306. color: #fff;
  307. }
  308. .item-intro-img {
  309. width: 100%;
  310. min-height: 300px;
  311. }
  312. .item-intro-img img{
  313. max-width: 1000px;
  314. }
  315. /************* 商品参数 *************/
  316. .item-param-container {
  317. display: flex;
  318. flex-wrap: wrap;
  319. flex-direction: row;
  320. justify-content: space-between;
  321. }
  322. .item-param-box {
  323. padding: 5px;
  324. padding-left: 30px;
  325. width: 240px;
  326. height: 36px;
  327. font-size: 14px;
  328. /* text-align: center; */
  329. /* background-color: #ccc; */
  330. }
  331. .item-param-title {
  332. color: #232323;
  333. }
  334. .item-param-content {
  335. color: #999;
  336. }
  337. .remarks-title {
  338. padding-left: 15px;
  339. height: 36px;
  340. font-size: 16px;
  341. font-weight: bolder;
  342. line-height: 36px;
  343. color: #666666;
  344. background-color: #F7F7F7;
  345. }
  346. .remarks-analyse-box {
  347. padding: 15px;
  348. display: flex;
  349. align-items: center;
  350. }
  351. .remarks-analyse-goods {
  352. margin-left: 15px;
  353. margin-right: 15px;
  354. }
  355. .remarks-analyse-num {
  356. font-size: 26px;
  357. }
  358. .remarks-analyse-title {
  359. font-size: 12px;
  360. line-height: 20px;
  361. }
  362. .remarks-bar {
  363. padding-left: 15px;
  364. height: 36px;
  365. line-height: 36px;
  366. color: #666666;
  367. background-color: #F7F7F7;
  368. .selectedBar{
  369. color: $theme_color;
  370. }
  371. }
  372. .remarks-bar span {
  373. margin-right: 15px;
  374. &:hover{
  375. color: $theme_color;
  376. cursor: pointer;
  377. }
  378. }
  379. .remarks-box {
  380. padding: 15px;
  381. display: flex;
  382. flex-direction: row;
  383. border-bottom: 1px #ccc dotted;
  384. }
  385. .remarks-user {
  386. width: 180px;
  387. }
  388. .remarks-user-name {
  389. padding-left: 15px;
  390. }
  391. .remarks-content-box {
  392. width: calc(100% - 180px);
  393. .comment-img{
  394. display: flex;
  395. .borderColor{
  396. border-color: $theme_color;
  397. }
  398. div{
  399. border: 1px solid #999;
  400. margin-right: 5px;
  401. width: 50px;
  402. height: 50px;
  403. img{width: 100%;}
  404. }
  405. }
  406. .preview-img{
  407. position: relative;
  408. border: 1px solid #eee;
  409. margin: 10px 0;
  410. width: 200px;
  411. div{
  412. position: absolute;
  413. top: 3px;
  414. left: 3px;
  415. z-index: 3;
  416. span{
  417. display: inline-block;
  418. background-color: rgba(0,0,0,.5);
  419. padding:3px 5px;
  420. color: #fff;
  421. border-radius: 4px;
  422. cursor: pointer;
  423. }
  424. span:nth-child(1) .ivu-icon {
  425. transform: rotateY(180deg);
  426. }
  427. }
  428. img:hover{
  429. cursor: url(require('../../../static/small.cur')),auto;
  430. }
  431. }
  432. }
  433. .remarks-content {
  434. font-size: 14px;
  435. color: #232323;
  436. line-height: 28px;
  437. }
  438. .remarks-sub {
  439. margin-top: 5px;
  440. color: #ccc;
  441. }
  442. .remarks-time {
  443. margin-left: 15px;
  444. }
  445. .remarks-page {
  446. margin: 15px;
  447. display: flex;
  448. justify-content:flex-end;
  449. }
  450. /***************商品详情介绍和推荐侧边栏结束***************/
  451. /* 改变便签页样式 */
  452. .ivu-tabs-ink-bar {
  453. background-color: $theme_color !important;
  454. }
  455. /deep/.ivu-tabs-bar{
  456. border: none;
  457. }
  458. .item-tabs > .ivu-tabs > .ivu-tabs-bar .ivu-tabs-tab{
  459. border-radius: 0px;
  460. color: #999;
  461. height: 38px;
  462. // background: #F7F7F7;
  463. }
  464. .item-tabs > .ivu-tabs > .ivu-tabs-bar .ivu-tabs-tab-active{
  465. color: #fff;
  466. background-color: $theme_color;
  467. }
  468. .item-tabs > .ivu-tabs > .ivu-tabs-bar .ivu-tabs-tab-active:before{
  469. content: '';
  470. display: block;
  471. width: 100%;
  472. height: 1px;
  473. color: #fff;
  474. background: #F7F7F7;
  475. position: absolute;
  476. top: 0;
  477. left: 0;
  478. }
  479. .ivu-rate-star-full:before, .ivu-rate-star-half .ivu-rate-star-content:before {
  480. color: $theme_color;
  481. }
  482. </style>