Selaa lähdekoodia

详情页评论

zhangdehua 1 vuosi sitten
vanhempi
commit
fd8aa2356b

+ 52 - 0
app/index/controller/Comment.php

@@ -85,4 +85,56 @@ class Comment extends Controller
         return $this->renderError($model->getError() ?: '评价发表失败');
     }
 
+    /**
+     * 商品评价列表
+     * @param int $goodsId 商品ID
+     * @param int|null $scoreType 评价评分
+     * @return \think\response\Json
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function listPage(int $goodsId, int $scoreType = null)
+    {
+        // 评价列表
+        $model = new CommentModel;
+        $list = $model->getCommentList($goodsId, $scoreType);
+        return $this->renderSuccess(compact('list'));
+    }
+
+    /**
+     * 商品评分总数
+     * @param int $goodsId
+     * @return array|\think\response\Json
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function total(int $goodsId)
+    {
+        // 指定评分总数
+        $model = new CommentModel;
+        $total = $model->getTotal($goodsId);
+        return $this->renderSuccess(compact('total'));
+    }
+
+    /**
+     * 商品评价列表 (限制数量, 用于商品详情页展示)
+     * @param int $goodsId
+     * @param int $limit
+     * @return array|\think\response\Json
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function listRows(int $goodsId, int $limit = 5)
+    {
+        // 评价列表
+        $model = new CommentModel;
+        $list = $model->listRows($goodsId, $limit);
+        // 评价总数量
+        $total = $model->rowsTotal($goodsId);
+        return $this->renderSuccess(compact('list', 'total'));
+    }
+
 }

+ 20 - 2
app/index/controller/Index.php

@@ -3,6 +3,7 @@
 namespace app\index\controller;
 
 use app\index\model\Article as ArticleModel;
+use app\index\model\Comment as CommentModel;
 use app\index\model\Goods as GoodsModel;
 
 /**
@@ -31,21 +32,34 @@ class Index extends Controller
 
         //获取评价数量
         $goodsIds = array_unique(array_merge($newGoodsId, $bestGoodsId, $superDealsGoodsId));
-        $commentModel = new \app\api\model\Comment();
+        $commentModel = new CommentModel();
         $rows = $commentModel->rowsTotalBatch($goodsIds)->toArray();
         $rowsByGoodsId = array_column($rows, 'cnt', 'goods_id');
+
+        //获取评论分数
+        $commentScores = $commentModel->getTotalAll($goodsIds)->toArray();
+        $scoresByGoodsId = array_column($commentScores, 'score_total', 'goods_id');
+
+        //dd($rowsByGoodsId);
+
         //可考虑缓存
 
         foreach ($newArrival as &$item) {
             $item['comment_cnt'] = $rowsByGoodsId[$item['goods_id']] ?? 0;
+            $temp = bcmul($item['comment_cnt'], 10, 0);
+            $item['avg_score'] = bcdiv($scoresByGoodsId[$item['goods_id']] ?? '0', $temp, 0);
         }
 
         foreach ($bestseller as &$item) {
             $item['comment_cnt'] = $rowsByGoodsId[$item['goods_id']] ?? 0;
+            $temp = bcmul($item['comment_cnt'], 10, 0);
+            $item['avg_score'] = bcdiv($scoresByGoodsId[$item['goods_id']], $temp, 0);
         }
 
         foreach ($superDeals as &$item) {
             $item['comment_cnt'] = $rowsByGoodsId[$item['goods_id']] ?? 0;
+            $temp = bcmul($item['comment_cnt'], 10, 0);
+            $item['avg_score'] = bcdiv($scoresByGoodsId[$item['goods_id']], $temp, 0);
         }
 
         $model = new ArticleModel;
@@ -78,7 +92,11 @@ class Index extends Controller
         $goodsModel = new GoodsModel();
         $goods = $goodsModel->getDetails($goodsId)->toArray();
         $goods['content'] = html_entity_decode($goods['content']);
-        return view('productDetails', ['goods' => $goods]);
+
+        $model = new CommentModel;
+        $total = $model->rowsTotal($goodsId);
+
+        return view('productDetails', ['goods' => $goods, 'comment_total' => $total]);
     }
 
 }

+ 11 - 3
app/index/model/Comment.php

@@ -8,7 +8,7 @@
 // +----------------------------------------------------------------------
 // | Author: 萤火科技 <admin@yiovo.com>
 // +----------------------------------------------------------------------
-declare (strict_types = 1);
+declare (strict_types=1);
 
 namespace app\index\model;
 
@@ -52,7 +52,8 @@ class Comment extends CommentModel
         $filter = $this->getFilter($goodsId, $scoreType);
         return $this->with(['user.avatar', 'orderGoods'])
             ->where($filter)
-            ->order(['sort' => 'asc', 'create_time' => 'desc'])
+            //->order(['sort' => 'asc', 'create_time' => 'desc'])
+            ->order(['comment_id' => 'desc'])
             ->paginate(15);
     }
 
@@ -88,7 +89,7 @@ class Comment extends CommentModel
 
     public function rowsTotalBatch(array $goodsIds)
     {
-        $filter =[
+        $filter = [
             ['status', '=', 1],
             ['is_delete', '=', 0],];
         return $this->field('goods_id, count(comment_id) as cnt')->where($filter)->whereIn('goods_id', $goodsIds)->group('goods_id')->select();
@@ -135,6 +136,13 @@ class Comment extends CommentModel
         ])->find();
     }
 
+    public function getTotalAll(array $goodsIds)
+    {
+        return $this->field('goods_id,sum(score) as score_total')->where([
+            'is_delete' => 0,
+            'status' => 1])->whereIn('goods_id', $goodsIds)->group('goods_id')->select();
+    }
+
     /**
      * 验证订单是否允许评价
      * @param OrderModel $order

+ 2 - 2
app/index/view/index/index.html

@@ -182,7 +182,7 @@
                                 <div class="goodsReviews">
                                     <div class="goodsStarContainer">
                                         <div class="goodsStarContainer">
-                                            {for start="1" end="6" step=1 name="i"}
+                                            {for start="1" end="$goods['avg_score']" step=1 name="i"}
                                             <p class="goodsStarItem">
                                                 {lt name="i" value="$goods['goods_id']")}
                                                 <img src="/assets/index/asstes/icon/selStar.png" alt="">
@@ -343,7 +343,7 @@
                             </div>
                             <div class="goodsReviews">
                                 <div class="goodsStarContainer">
-                                    {for start="1" end="6" step=1 name="i"}
+                                    {for start="1" end="$deal['avg_score']" step=1 name="i"}
                                     <p class="goodsStarItem">
                                         {lt name="i" value="$deal['goods_id']")}
                                         <img src="/assets/index/asstes/icon/selStar.png" alt="">

+ 150 - 4
app/index/view/index/productDetails.html

@@ -183,19 +183,32 @@
             <!-- 文案模块 -->
             <article class="articleContainer">
                 <div class="articleTabBox">
-                    <div class="articleTabItem active">
+                    <div class="articleTabItem active" data-type="description">
                         <p class="tabTag"></p>
                         <h2 class="articleTabTitle">Description</h2>
                     </div>
-                    <div class="articleTabItem">
+                    <div class="articleTabItem" data-type="reviews">
                         <p class="tabTag"></p>
-                        <h2 class="articleTabTitle">Reviews (0)</h2>
+                        <h2 class="articleTabTitle">Reviews ({$comment_total})</h2>
                     </div>
                 </div>
-                <div class="articleInfo">
+                <!-- 商品详情容器 -->
+                <div class="articleInfo" id="articleInfo">
                     <h2 class="articleTitle">Product description</h2>
                     <div id="richTextContainer"></div>
                 </div>
+                <!-- 评价内容容器 -->
+                <div id="reviewsInfo">
+                    <div id="reviews">
+                    </div>
+                    <div id="loadingIndicator">loading...</div>
+                    <div id="reviewsButtonContainer">
+                        <div id="reviewsButtonBox">
+                            <div id="prevPage">Prev page</div>
+                            <div id="nextPage">Next page</div>
+                        </div>
+                    </div>
+                </div>
             </article>
 
             <!-- 悬浮底部模块 -->
@@ -412,6 +425,139 @@
             addCart(number)
         });
         initRichText()
+
+        //页码
+        let page = 1;
+        //总页数
+        let totalPage = {$comment_total}
+        //页数
+        let itemsPerPage = 10;
+        //加载中
+        let isLoading = false;
+
+        //详情 & 评论切换
+        $(".articleTabItem").on(tap, function () {
+            const type = $(this).attr("data-type")
+            $(this).addClass("active").siblings().removeClass("active")
+            // 评论
+            if (type === "reviews") {
+                $("#reviewsInfo").show(0)
+                $("#articleInfo").hide(0)
+                getReviews()
+                page = 1
+            } else {
+                // 详情
+                $("#articleInfo").show(0)
+                $("#reviewsInfo").hide(0)
+            }
+        });
+
+
+        //上一页
+        $("#prevPage").on(tap, function () {
+            if (page > 1) {
+                page--
+            } else {
+                page = 1
+            }
+            getReviews()
+        });
+
+        //下一页
+        $("#nextPage").on(tap, function () {
+            if (page >= totalPage) {
+                page = totalPage
+            } else {
+                page++
+            }
+            getReviews()
+        });
+
+        // 获取评价列表
+        function getReviews() {
+            if (isLoading) {
+                return;
+            }
+            isLoading = true;
+            // 显示加载指示器
+            $('#loadingIndicator').show();
+            //调试后记得去除这段代码
+            $.ajax({
+                url: '/index/comment/listPage?goodsId=' + goodsId,
+                type: 'GET',
+                data: {
+                    page: page,
+                    per_page: itemsPerPage
+                },
+                success: function (response) {
+                    console.log(response.data)
+                    const data = response.data.list.data
+                    // 在页面中添加数据
+                    const container = $('#reviews');
+
+                    //var html = container.html();
+                    var html = '';
+                    //container.html("")
+                    $.each(data, function (index, item) {
+                        const rating = item.score / 10;
+                        let starHtml = "";
+                        for (let i = 0; i < 5; i++) {
+                            if (i < rating) {
+                                starHtml += '<img src="/assets/index/asstes/icon/selStar.png" alt="">';
+                            } else {
+                                starHtml += '<img src="/assets/index/asstes/icon/star.png" alt="">';
+                            }
+                        }
+
+                        html += `
+                        <div class="reviewItem">
+                        <div class="userInfo">
+                            <div class="userImg">
+                            <img src="https://himg.bdimg.com/sys/portrait/item/tb.1.772a23f6.WIunUru1_286k2Q9BG9SJg" alt="">
+                            </div>
+                            <p class="userName">${item.user.nick_name}</p>
+                        </div>
+                        <div class="reInfo">
+                            <div class="starBox">${starHtml}
+                            </div>
+                            <h3 class="reviewValues">${item.content}</h3>
+                        </div>
+                        </div>`;
+                    });
+
+                    container.html(html);
+
+
+
+
+                    //数据长度大于0显示上下页按钮
+                    //$('#reviewsButtonContainer').show();
+                    console.log(response.data.list.last_page , page,response.data.list.last_page > page)
+                    if (response.data.list.last_page > page){
+                        $("#nextPage").show()
+                    }else {
+                        $("#nextPage").hide()
+                    }
+
+                    if (page > 1){
+                        $("#prevPage").show()
+                    }else {
+                        $("#prevPage").hide()
+                    }
+
+                    // 隐藏加载指示器
+                    $('#loadingIndicator').hide();
+                    isLoading = false;
+                },
+                error: function () {
+                    // 处理错误情况
+                    console.log('请求数据失败');
+                    // 隐藏加载指示器
+                    $('#loadingIndicator').hide();
+                    isLoading = false;
+                }
+            });
+        }
     });
 </script>
 

+ 1 - 1
app/index/view/user/orderDetails.html

@@ -680,7 +680,7 @@
                 form: [{
                     order_goods_id: orderGoodsId,
                     goods_id: goodsId,
-                    score: score,
+                    score: score * 10,
                     content: textareaValue,
                 }]
             }

BIN
public/assets/index/asstes/icon/selStar.png


BIN
public/assets/index/asstes/icon/star.png


+ 108 - 0
public/assets/index/css/productDetails.css

@@ -372,6 +372,87 @@ body{
     margin-right: .08rem;
   }
 
+  #reviewsInfo{
+    padding: .36rem 0;
+    display: none;
+  }
+  .reviewItem{
+    display: flex;
+    align-items: flex-start;
+    margin-bottom: .24rem;
+    border-bottom: .02rem solid rgba(0, 0, 0, .02);
+    padding-bottom: .12rem;
+  }
+  .userInfo{
+    display: flex;
+    align-items: center;
+    padding-right: .24rem;
+  }
+  .userImg{
+    background-color: #F8F8F8;
+    width: .4rem;
+    height: .4rem;
+    border-radius: 50%;
+    overflow: hidden;
+    font-size: 0;
+  }
+  .userImg img{
+    width: 100%;
+    height: 100%;
+  }
+  .userName{
+    font-size: .17rem;
+    color: #434343;
+    padding-left: .12rem;
+    max-width: 1rem;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  .reInfo{
+    flex: 1;
+  }
+  .starBox{
+    display: flex;
+    align-items: center;
+    gap: .08rem;
+    margin-bottom: .12rem;
+    font-size: 0;
+  }
+  .starBox img{
+    width: .2rem;
+  }
+  .reviewValues{
+    font-size: .16rem;
+    line-height: 1.5;
+    word-break: break-all;
+    font-weight: 400;
+  }
+  #loadingIndicator{
+    text-align: center;
+    font-size: .16rem;
+    color: #999999;
+    padding-bottom: .24rem;
+}
+#reviewsButtonContainer{
+  display: block;
+}
+#reviewsButtonBox{
+  display: flex;
+  align-items: center;
+  gap: .24rem;
+  justify-content: flex-end;
+}
+#prevPage,#nextPage{
+  color: #fff;
+  height: .4rem;
+  padding: 0 .16rem;
+  border-radius: .04rem;
+  background-color: rgba(79, 73, 222, 1);
+  display: flex;
+  align-items: center;
+  cursor: pointer;
+}
   @media (max-width: 1320px) {
     .sectionContainer{
         padding: 0 .12rem;
@@ -523,4 +604,31 @@ body{
     .prViewImgBox{
         width: 100%;
     }
+    .reviewItem{
+      display: block;
+    }
+    .userInfo{
+      margin-bottom: .16rem;
+    }
+    .userImg{
+      width: .6rem;
+      height: .6rem;
+    }
+    .userName{
+      font-size: .22rem;
+    }
+    .starBox img{
+      width: .28rem;
+    }
+    .reviewValues{
+      font-size: .2rem;
+    }
+    .reviewItem{
+      padding-bottom: .24rem;
+      margin-bottom: .24rem;
+    }
+    #prevPage,#nextPage{
+      font-size: .22rem;
+      height: .52rem;
+    }
   }