diff --git a/app/appfront/modules/Catalog/block/product/Index.php b/app/appfront/modules/Catalog/block/product/Index.php index 7b1cb8a48115258466d422207108098efcf9c72b..10b1721c181ebb3b853464a6859fa75c062ef5c7 100644 --- a/app/appfront/modules/Catalog/block/product/Index.php +++ b/app/appfront/modules/Catalog/block/product/Index.php @@ -31,6 +31,7 @@ class Index { 'name' => Yii::$service->store->getStoreAttrVal($this->_product['name'],'name'), 'image' => $this->_product['image'], 'sku' => $this->_product['sku'], + 'spu' => $this->_product['spu'], 'price_info' => $this->getProductPriceInfo(), 'tier_price' => $this->_product['tier_price'], 'media_size' => [ @@ -42,7 +43,8 @@ class Index { 'options' => $this->getSameSpuInfo(), 'custom_option' => $this->_product['custom_option'], 'description' => Yii::$service->store->getStoreAttrVal($this->_product['description'],'description'), - + '_id' => $this->_product['_id'], + 'review_count' => Yii::$service->product->review->getCountBySpu($this->_product['spu']), ]; } diff --git a/app/appfront/modules/Catalog/block/reviewproduct/Add.php b/app/appfront/modules/Catalog/block/reviewproduct/Add.php new file mode 100644 index 0000000000000000000000000000000000000000..0b0e906133b2946c740805bd125693df8eb70695 --- /dev/null +++ b/app/appfront/modules/Catalog/block/reviewproduct/Add.php @@ -0,0 +1,84 @@ + + * @since 1.0 + */ +class Add { + + + public function getLastData(){ + $_id = Yii::$app->request->get('_id'); + if(!$_id){ + Yii::$service->page->message->addError('product _id is empty'); + return []; + } + $product = Yii::$service->product->getByPrimaryKey($_id); + if(!$product['spu']){ + Yii::$service->page->message->addError('product _id:'.$_id.' is not exist in product collection'); + return []; + } + + $price_info = $this->getProductPriceInfo($product); + $spu = $product['spu']; + $image = $product['image']; + $main_img = isset($image['main']['image']) ? $image['main']['image'] : ''; + $url_key = $product['url_key']; + $name = Yii::$service->store->getStoreAttrVal($product['name'],'name'); + return [ + 'name' => $name, + 'spu' => $spu, + 'price_info' => $price_info, + 'main_img' => $main_img, + 'url' => Yii::$service->url->getUrl($url_key), + ]; + } + + protected function getProductPriceInfo($product){ + $price = $product['price']; + $special_price = $product['special_price']; + $special_from = $product['special_from']; + $special_to = $product['special_to']; + return Yii::$service->product->price->getCurrentCurrencyProductPriceInfo($price,$special_price,$special_from,$special_to); + + } + + + protected function getSpuData(){ + $spu = $this->_product['spu']; + $filter = [ + 'select' => ['size',], + 'where' => [ + ['spu' => $spu], + ], + 'asArray' => true, + ]; + $coll = Yii::$service->product->coll($filter); + if(is_array($coll['coll']) && !empty($coll['coll'])){ + foreach($coll['coll'] as $one){ + $spu = $one['spu']; + + } + } + + } + + + + + + + + +} diff --git a/app/appfront/modules/Catalog/controllers/ReviewproductController.php b/app/appfront/modules/Catalog/controllers/ReviewproductController.php new file mode 100644 index 0000000000000000000000000000000000000000..2e1886a4868dae9923a73025dc23c99e3d36fcb5 --- /dev/null +++ b/app/appfront/modules/Catalog/controllers/ReviewproductController.php @@ -0,0 +1,49 @@ + + * @since 1.0 + */ +class ReviewproductController extends AppfrontController +{ + public function init(){ + parent::init(); + Yii::$service->page->theme->layoutFile = 'product_view.php'; + } + # + public function actionAdd() + { + //echo 1;exit; + $data = $this->getBlock()->getLastData(); + return $this->render($this->action->id,$data); + } + + +} + + + + + + + + + + + + + + + + diff --git a/app/appfront/theme/base/front/assets/css/ie.css b/app/appfront/theme/base/front/assets/css/ie.css index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bbb4a9e69b0e875ad346099fc2c481372a76b248 100644 --- a/app/appfront/theme/base/front/assets/css/ie.css +++ b/app/appfront/theme/base/front/assets/css/ie.css @@ -0,0 +1 @@ +img{border:none;} \ No newline at end of file diff --git a/app/appfront/theme/base/front/assets/css/style.css b/app/appfront/theme/base/front/assets/css/style.css index 03a374b192ebc2a6e3330042c1320a8df153deee..c36aefe4d937e45acf802410071f6774b5465c9b 100644 --- a/app/appfront/theme/base/front/assets/css/style.css +++ b/app/appfront/theme/base/front/assets/css/style.css @@ -3,7 +3,7 @@ body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, body {color: #333;font: 1em/1.55 Verdana,Arial,Helvetica,sans-serif;} a{color: #666;text-decoration: none;} ol, ul {list-style: outside none none;} - +img{border:none;} h1, h2, h3, h4, h5, h6 { color: #444; font-family: Bitter,Myriad Pro,Verdana,serif; @@ -844,6 +844,7 @@ button{ margin-left: -3px; padding: 0; background:none; + height:auto; } button.redBtn:hover{ background:none; @@ -1512,11 +1513,6 @@ td:nth-child(2n) { -#review_description li{ - width:940px; - border-bottom:1px solid #ccc; - padding:15px 0 ; -} .review_description_left a span{ display: block; height: 32px; @@ -1682,10 +1678,6 @@ border: solid 1px #adadad; width:44px;float:right;height:28px;margin-right:5px; } -#review_description { - border-top: 1px solid #ccc; -} - .fieldset { background: #fefefe none repeat scroll 0 0; @@ -1929,8 +1921,6 @@ border-bottom:1px solid #bbb; - - a.pre_images { background: rgba(0, 0, 0, 0) url("../images/tag.png") no-repeat scroll -104px -80px; border-radius: 0; @@ -1974,12 +1964,9 @@ a.next_images { - - - -.product_info{ +.product_description_info{ list-style:none; - margin:0; + margin:25px 0 ; padding:0; text-decoration:none; font-family:'Microsoft YaHei'; @@ -1987,7 +1974,7 @@ a.next_images { } -.product_info li { +.product_description_info #nav-container li { border-right: 2px solid #eee; cursor: pointer; float: left; @@ -2000,28 +1987,218 @@ a.next_images { } -.product_info ul{ +.product_description_info #nav-container ul{ width:1200px; margin:0 auto; } -.product_info .nav{ +.product_description_info .nav{ height:52px; width:100%; background:#f5f5f5; } -.product_info .nav .cur{ +.product_description_info .nav .cur{ background:#fff; border-top:2px solid #1a92cf; color:#1a92cf; } -.product_info .fixed{ +.product_description_info .fixed{ position:fixed; - top:0; + top:0; left:0; + z-index:999999999; } -.product_info a{ +.product_description_info #nav-container a{ color:#505050; } +.product_page{font-size:12px;} +.product_description_info #text{padding:20px 10px;} + + +.scroll_left a { + color: #4c6b99; + font-family: Georgia; + font-size: 19px; + line-height: 40px; + text-decoration: none; +} + + +.scroll_horizontal { + padding: 30px 0 10px; + position: relative; + width: 100%; +} + + + +.product-Reviews .scroll_horizontal .box { + padding: 15px 0 0; +} +.scroll_horizontal .box { + border-top: 1px solid #ccc; + margin: 0 auto; + overflow: hidden; + padding: 10px 0 0; + position: relative; + width: 1170px; +} + +.product-Reviews_top { + padding: 20px 0 20px 10px; + width: 100%; +} + + +.view_all_review { + background: #eee none repeat scroll 0 0; + border-bottom: 1px solid #ccc; + border-top: 1px solid #ccc; + color: #fff; + height: 22px; + margin: 15px 0; + text-align: center; +} + + +#review_description li{ + border-bottom: 1px solid #ddd; + margin-bottom:15px; +} +.view_all_review a { + color: #333; + line-height: 20px; +} + + + + +.review_description_left a { + color: #000; + text-decoration: none; +} +.product-Reviews_top a { + font-family: Georgia; + text-transform: uppercase; +} +.review_star_5 { + background: rgba(0, 0, 0, 0) url("../images/Star_5.png") no-repeat scroll 0 0; +} +.review_star { + display: block; + height: 15px; + width: 69px; +} + +.currentprice { + color: #4c6b99; + font-size: 16px; +} +.product-description_em { + color: #cc0000; + font: 17px/12px Segoeui,Arial,Verdana,serif; + margin: 0 3px; +} + + + +.star_1, .star_2, .star_3, .star_4, .star_5 { + background: rgba(0, 0, 0, 0) url("../images/product_rating_big_blank_star.png") repeat scroll 0 0; + display: block; + height: 30px; + width: 30px; +} +.full_star { + background: rgba(0, 0, 0, 0) url("../images/product_rating_big_full_star.png") repeat scroll 0 0; +} + + + +#reviews_form_list li { + float: left; + margin-top: 10px; + width: 360px; +} + + +#reviews_form_list label { + color: #707070; + font: bold 11px/13px Segoeui-Bold,Myriad Pro,Verdana,serif; +} + + +.review_span_error { + color: #f00; + display: block; + height: 20px; +} + + + +#reviews_form_list select { + width: 336px; + background: #fff none repeat scroll 0 0; + border: 1px solid #ccc; + border-radius: 2px; + color: #444; + display: inline-block; + font: 12px/33px Segoeui,Arial,Verdana,serif; + height: 33px; + overflow: hidden; + padding-left: 10px; + position: relative; + text-decoration: none !important; + text-overflow: ellipsis; + white-space: nowrap; +} + + +#review_review_field { + border: 1px solid #ccc; + border-radius: 2px; + color: #777; + height: 100px; + padding: 0 10px; + resize: none; + width: 676px; +} + +.verification_code_input { + height: 30px; + padding: 0 10px; + width: 86px; +} + + +.product-Reviews_bottom button { + margin: 8px 0 0; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/appfront/theme/base/front/assets/images/product_rating_big_blank_star.png b/app/appfront/theme/base/front/assets/images/product_rating_big_blank_star.png new file mode 100644 index 0000000000000000000000000000000000000000..34db2af6c3c7f16f7815ffa28a112e0cfb4ddf84 Binary files /dev/null and b/app/appfront/theme/base/front/assets/images/product_rating_big_blank_star.png differ diff --git a/app/appfront/theme/base/front/assets/images/product_rating_big_full_star.png b/app/appfront/theme/base/front/assets/images/product_rating_big_full_star.png new file mode 100644 index 0000000000000000000000000000000000000000..84d71adb8667a13a01d5468a57fb17a9c225b2ad Binary files /dev/null and b/app/appfront/theme/base/front/assets/images/product_rating_big_full_star.png differ diff --git a/app/appfront/theme/base/front/catalog/product/index.php b/app/appfront/theme/base/front/catalog/product/index.php index ae446bd2597872b5d1929314de462a7d0a185a88..7c1c76da4d2ba613759b9f2c82ad0428a4f8fda1 100644 --- a/app/appfront/theme/base/front/catalog/product/index.php +++ b/app/appfront/theme/base/front/catalog/product/index.php @@ -1,148 +1,162 @@
-
- -
-

-
-
- - Average rating : - 0 - - - (0 reviews) - - -
-
-
Item Code:
-
- 'catalog/product/index/price.php' - ]; - $priceParam = [ - 'price_info' => $price_info, - ]; - ?> - page->widget->render($priceView,$priceParam); ?> +
+
-
-
-
- 'catalog/product/index/options.php' - ]; - $optionsParam = [ - 'options' => $options, - ]; - ?> - page->widget->render($optionsView,$optionsParam); ?> - +
+

+
+
+ + Average rating : + 0 + + + (0 reviews) + + +
-
- 'catalog/product/index/custom_option.php' +
Item Code:
+
+ 'catalog/product/index/price.php' ]; - $optionsParam = [ - 'custom_option' => $custom_option, + $priceParam = [ + 'price_info' => $price_info, ]; ?> - page->widget->render($optionsView,$optionsParam); ?> + page->widget->render($priceView,$priceParam); ?>
- -
-
Qty:
-
- +
+
+ 'catalog/product/index/options.php' + ]; + $optionsParam = [ + 'options' => $options, + ]; + ?> + page->widget->render($optionsView,$optionsParam); ?> + +
+
+ 'catalog/product/index/custom_option.php' + ]; + $optionsParam = [ + 'custom_option' => $custom_option, + ]; + ?> + page->widget->render($optionsView,$optionsParam); ?> +
-
-
- -
- -
- - Add to Favorites - +
+
Qty:
+
+ +
+
+
+ +
+ + + +
-
+
+
+ 'catalog/product/index/tier_price.php' + ]; + $priceParam = [ + 'tier_price' => $tier_price, + ]; + ?> + page->widget->render($priceView,$priceParam); ?> +
-
- 'catalog/product/index/tier_price.php' - ]; - $priceParam = [ - 'tier_price' => $tier_price, - ]; - ?> - page->widget->render($priceView,$priceParam); ?> - +
+
+ 'catalog/product/index/image.php' + ]; + $imageParam = [ + 'media_size' => $media_size, + 'image' => $image, + 'productImgMagnifier' => $productImgMagnifier, + ]; + ?> + page->widget->render($imageView,$imageParam); ?> +
+
-
-
- 'catalog/product/index/image.php' - ]; - $imageParam = [ - 'media_size' => $media_size, - 'image' => $image, - 'productImgMagnifier' => $productImgMagnifier, - ]; - ?> - page->widget->render($imageView,$imageParam); ?> -
+ +
+ +
+
+ +
+
+ 'catalog/product/index/review.php' + ]; + $reviewParam = [ + '_id' => $_id, + 'review_count' => $review_count, + 'spu' => $spu, + ]; + ?> + page->widget->render($reviewView,$reviewParam); ?> +
+
text3
+
text2
+ +
-
-
- -
- -
-
text1
-
text2
-
text3
-
text2
- -
-
\ No newline at end of file diff --git a/config/services/Product.php b/config/services/Product.php index 2cc09a08ca4cb0c5e7e4fa07c816086e9dd467da..af8a5c86dbeb08df7ffcc43211eb452c54b3da82 100644 --- a/config/services/Product.php +++ b/config/services/Product.php @@ -83,9 +83,12 @@ return [ ], 'review' => [ 'class' => 'fecshop\services\product\Review', + 'filterByStore' => false, # 是否通过store的值进行评论过滤? + 'filterByLang' => false, # 是否通过语言进行评论过滤? ], 'info' => [ 'class' => 'fecshop\services\product\Info', + ], 'coll' => [ 'class' => 'fecshop\services\product\Coll', diff --git a/models/mongodb/product/Review.php b/models/mongodb/product/Review.php new file mode 100644 index 0000000000000000000000000000000000000000..c44e39ae107fc49c7fcf00ef020b77cac566577d --- /dev/null +++ b/models/mongodb/product/Review.php @@ -0,0 +1,65 @@ + + * @since 1.0 + */ +class Review extends ActiveRecord +{ + public static $_customAttrs; + + + + public static function collectionName() + { + return 'review'; + } + # ֶ̬Ρ + public static function addCustomAttrs($attrs){ + self::$_customAttrs = $attrs; + } + + public function attributes($origin=false) + { + $origin = [ + '_id', + 'product_spu', + 'product_id', + 'rate_star', + 'name', + 'summary', + 'review_content', + 'review_date', # + 'store', # store + 'lang_code', # + 'status', # ״̬ + 'audit_user', # ˺ + 'audit_date', # ʱ + ]; + if($origin){ # ȡԭʼ + return $origin; + } + if(is_array(self::$_customAttrs) && !empty(self::$_customAttrs)){ + $origin = array_merge($origin,self::$_customAttrs); + } + return $origin; + } + + + + + + + + + +} \ No newline at end of file diff --git a/services/product/Review.php b/services/product/Review.php index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..39f0bbdd943c730bf23bf7b63b370848cc503557 100644 --- a/services/product/Review.php +++ b/services/product/Review.php @@ -0,0 +1,153 @@ + + * @since 1.0 + */ +class Review extends Service +{ + public $filterByStore; + public $filterByLang; + /** + * @property $arr | Array + * ʼreview modelԣΪÿһƷĿӵֶβͬ + */ + protected function actionInitReviewAttr($arr){ + if(!empty($arr) && is_array($arr)){ + $ReviewModel = new ReviewModel; + $attr_arr = $ReviewModel->attributes(true); + $arr_keys = array_keys($arr); + $attrs = array_diff($arr_keys,$attr_arr); + ReviewModel::addCustomAttrs($attrs); + } + } + /** + * @property $spu | String. + * ͨspuҵ + */ + protected function actionGetCountBySpu($spu){ + $where = [ + 'product_spu' => $spu + ]; + if($this->filterByStore && ($currentStore = Yii::$service->store->currentStore)){ + $where['store'] = $currentStore; + } + if($this->filterByLang && ($currentLangCode = Yii::$service->store->currentLangCode)){ + $where['lang_code'] = $currentLangCode; + } + $count = ReviewModel::find()->asArray()->where($where)->count(); + return $count ? $count : 0; + } + /** + * example filter: + * [ + * 'numPerPage' => 20, + * 'pageNum' => 1, + * 'orderBy' => ['review_date' => SORT_DESC], + * where' => [ + * ['spu' => 'uk10001'], + * ], + * 'asArray' => true, + * ] + * ͨspuҵlisting + */ + protected function actionGetListBySpu($filter){ + + if($this->filterByStore && ($currentStore = Yii::$service->store->currentStore)){ + $filter['where'][] = ['store' => $currentStore ]; + } + if($this->filterByLang && ($currentLangCode = Yii::$service->store->currentLangCode)){ + $filter['where'][] = ['lang_code' => $currentLangCode ]; + } + $query = ReviewModel::find(); + $query = Yii::$service->helper->ar->getCollByFilter($query,$filter); + return [ + 'coll' => $query->all(), + 'count'=> $query->count(), + ]; + + } + + /** + * @property $review_data | Array + * + * + */ + protected function actionAddReview($review_data){ + $this->initReviewAttr($review_data); + $model = new ReviewModel; + if(isset($review_data['_id'])){ + unset($review_data['_id']); + } + $saveStatus = Yii::$service->helper->ar->save($model,$review_data); + return true; + } + + /** + * @property $review_data | Array + * + */ + protected function actionUpdateReview($review_data){ + $this->initReviewAttr($review_data); + $model = ReviewModel::findOne(['_id'=> $review_data[$primaryKey]]); + unset($review_data[$primaryKey]); + $saveStatus = Yii::$service->helper->ar->save($model,$review_data); + return true; + } + + /* + * example filter: + * [ + * 'numPerPage' => 20, + * 'pageNum' => 1, + * 'orderBy' => ['_id' => SORT_DESC, 'sku' => SORT_ASC ], + * 'where' => [ + ['>','price',1], + ['<=','price',10] + * ['sku' => 'uk10001'], + * ], + * 'asArray' => true, + * ] + * 鿴review б + */ + protected function actionList($filter){ + $query = ReviewModel::find(); + $query = Yii::$service->helper->ar->getCollByFilter($query,$filter); + return [ + 'coll' => $query->all(), + 'count'=> $query->count(), + ]; + } + /** + * @property $_id | String + * ̨༭ ͨidҵ + * ע⣺ΪÿƷۿܼµֶΣ˲ʹActiveRecordķʽȡ + * ʹķʽ԰ֶζȡ + */ + protected function actionGetByReviewId($_id){ + + return ReviewModel::getCollection()->findOne(['_id' => $_id]); + + } + + + + + + + +} \ No newline at end of file