소스 검색

商品评价

lifanagju_citu 5 달 전
부모
커밋
f432598feb

+ 13 - 0
src/api/mall/product.js

@@ -6,4 +6,17 @@ export const getProductDetail = async (params) => {
     url: '/app-api/product/spu/get-detail',
     params
   })
+}
+
+// 获得商品评价分页
+export const getCommentPage = async (spuId, pageNo, pageSize, type) => {
+  return request.get({
+    url: '/app-api//product/comment/page',
+    params: {
+      spuId,
+      pageNo,
+      pageSize,
+      type,
+    },
+  })
 }

+ 4 - 4
src/views/mall/components/details.vue

@@ -60,7 +60,7 @@
           </v-tabs>
         </div>
         <describe v-if="describeTab === 0 && state.goodsInfo?.description" :content="state.goodsInfo.description"></describe>
-        <!-- <comment v-if="describeTab === 1 && state.goodsId" class="detail-comment-selector" :goodsId="state.goodsId" /> -->
+        <comment v-if="describeTab === 1 && state.goodsId" class="detail-comment-selector" :goodsId="state.goodsId" />
       </div>
     </v-card>
   </div>
@@ -71,7 +71,7 @@ defineOptions({name: 'goods-details'})
 import { getProductDetail } from '@/api/mall/product'
 import selectSku from './details/s-select-sku.vue'
 import describe from './details/describe.vue'
-// import comment from './details/detail-comment-card.vue'
+import comment from './details/detail-comment-card.vue'
 import { ref, reactive } from 'vue'
 import { useRouter } from 'vue-router'
 import Snackbar from '@/plugins/snackbar'
@@ -79,7 +79,7 @@ import Snackbar from '@/plugins/snackbar'
 const router = useRouter()
 const { id } = router.currentRoute.value.params
 
-const describeTab = ref(0)
+const describeTab = ref(1)
 const selectedSkuPicUrl = ref('')
 const selectedSkuPrice = ref('')
 const selectedSkuMarketPrice = ref('')
@@ -111,7 +111,7 @@ getData()
 const calcPrice = (price) => { return price && (price-0) ? (price-0)/100 : '--' }
 
 const state = reactive({
-  goodsId: 0,
+  goodsId: id || 0,
   skeletonLoading: true, // SPU 加载中
   goodsInfo: {}, // SPU 信息
   showSelectSku: false, // 是否展示 SKU 选择弹窗

+ 106 - 0
src/views/mall/components/details/comment-item.vue

@@ -0,0 +1,106 @@
+<!-- 商品评论项 -->
+<template>
+  <div>
+    <!-- 用户评论 -->
+    <div class="d-flex align-center mb-5">
+      <div class="d-flexx mr-3">
+        <!-- <image class="avatar" :src="item.userAvatar"></image> -->
+        <v-avatar class="avatar">
+          <v-img alt="" :src="getUserAvatar(item.userAvatar, '1')" ></v-img>
+        </v-avatar>
+      </div>
+      <div class="nickname mr-3 mb-1">{{ item.userNickname }}</div>
+      <div class="">
+        <!-- <uni-rate :readonly="true" v-model="item.scores" size="18" /> -->
+        <v-rating
+          readonly
+          :length="5"
+          :size="26"
+          v-model="item.scores"
+          active-color="#ffca3e"
+        />
+      </div>
+    </div>
+    <div class="content"> {{ item.content }} </div>
+    <div class="ss-m-t-24" v-if="item.picUrls?.length">
+      <div class="scroll-box">
+        <div class="ss-flex">
+          <div v-for="(picUrl, index) in item.picUrls" :key="picUrl" class="ss-m-r-10">
+            <v-img :src="picUrl" :aspect-ratio="1" :current="index" style="border-radius: 8px;"></v-img>
+            <!-- <su-image
+              class="content-img"
+              isPreview
+              :previewList="item.picUrls"
+              :current="index"
+              :src="picUrl"
+              :height="120"
+              :width="120"
+              mode="aspectFill"
+            /> -->
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 商家回复 -->
+    <div class="ss-m-t-20 reply-box" v-if="item.replyTime">
+      <div class="reply-title">商家回复:</div>
+      <div class="reply-content">{{ item.replyContent }}</div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { getUserAvatar } from '@/utils/avatar'
+  const props = defineProps({
+    item: {
+      type: Object,
+      default() {},
+    },
+  });
+</script>
+
+<style lang="scss" scoped>
+  .avatar {
+    width: 52rpx;
+    height: 52rpx;
+    border-radius: 50%;
+  }
+
+  .nickname {
+    font-size: 26rpx;
+    font-weight: 500;
+    color: #999999;
+  }
+
+  .content {
+    width: 636rpx;
+    font-size: 26rpx;
+    font-weight: 400;
+    color: #333333;
+  }
+
+  .reply-box {
+    position: relative;
+    background: #f8f8f8;
+    border-radius: 8rpx;
+    padding: 16rpx;
+  }
+
+  .reply-title {
+    position: absolute;
+    left: 16rpx;
+    top: 16rpx;
+    font-weight: 400;
+    font-size: 26rpx;
+    line-height: 40rpx;
+    color: #333333;
+  }
+
+  .reply-content {
+    text-indent: 128rpx;
+    font-weight: 400;
+    font-size: 26rpx;
+    line-height: 40rpx;
+    color: #333333;
+  }
+</style>

+ 101 - 0
src/views/mall/components/details/detail-comment-card.vue

@@ -0,0 +1,101 @@
+<!-- 商品评论的卡片 -->
+<template>
+  <div class="detail-comment-card ">
+    <div class="card-header d-flex align-center justify-space-between pb-6">
+      <div class="resume-header">
+        <div class="resume-title">
+          评价<span class="des ml-1">({{ state.total }})</span>
+        </div>
+      </div>
+      <!-- @tap="sheep.$router.go('/pages/goods/comment/list', { id: goodsId })" -->
+      <div
+        class="ss-flex ss-col-center"
+        @click="null"
+        v-if="state.commentList.length > 0"
+      >
+        <v-btn variant="text" class="ss-reset-button more-btn">查看全部</v-btn>
+        <span class="cicon-forward" />
+      </div>
+    </div>
+    <!-- 评论列表 -->
+    <div class="card-content">
+      <div class="comment-box ss-p-y-30" v-for="item in state.commentList" :key="item.id">
+        <comment-item :item="item" />
+      </div>
+      <div v-if="state.commentList.length === 0" style="margin: 30px auto; color: #777;">期待您的第一个评价</div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+  import { reactive, onBeforeMount } from 'vue';
+  import { getCommentPage } from '@/api/mall/product'
+  import commentItem from './comment-item.vue';
+
+  const props = defineProps({
+    goodsId: {
+      type: [Number, String],
+      default: 0,
+    },
+  });
+
+  const state = reactive({
+    commentList: [], // 评论列表,只展示最近的 3 条
+    total: 0, // 总评论数
+  });
+
+  async function getComment(id) {
+    const res = await getCommentPage(id, 1, 3, 0);
+    state.commentList = res.list;
+    state.total = res.total;
+  }
+
+  onBeforeMount(() => {
+    getComment(props.goodsId);
+  });
+</script>
+
+<style lang="scss" scoped>
+  .detail-comment-card {
+    margin: 0 20rpx 20rpx 20rpx;
+    padding: 20rpx 20rpx 0 20rpx;
+    .card-header {
+      .line {
+        width: 6rpx;
+        height: 30rpx;
+        background: linear-gradient(180deg, var(--v-primary-base) 0%, var(--v-primary-lighten1) 100%);
+        border-radius: 3rpx;
+      }
+
+      .title {
+        font-size: 30rpx;
+        font-weight: bold;
+        line-height: normal;
+      }
+
+      .des {
+        font-size: 24rpx;
+        color: #999999;
+      }
+
+      .more-btn {
+        font-size: 24rpx;
+        color: var(--v-primary-base);
+        line-height: normal;
+      }
+
+      .cicon-forward {
+        font-size: 24rpx;
+        line-height: normal;
+        color: var(--v-primary-base);
+        margin-top: 4rpx;
+      }
+    }
+  }
+  .comment-box {
+    border-bottom: 2rpx solid #eeeeee;
+    &:last-child {
+      border: none;
+    }
+  }
+</style>