Commit e8c5e3fd by halweg

feat : 相册动态数据

parent 49d6abd9
......@@ -111,4 +111,14 @@ class Images extends \Magento\Framework\View\Element\Template
return $this->imageHelper->resize($item->getPath(), self::REVIEW_COVER_WIDTH * 2);
}
/**
* @param $item
* @return string
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function getResizedImagePathByLimit($item, $width): string
{
return $this->imageHelper->resize($item->getPath(), $width);
}
}
<?php
namespace Joshine\Review\Controller\Ajax;
use Amasty\AdvancedReview\Model\ResourceModel\Images as ImagesModel;
use Joshine\Review\Helper\BlockHelper;
use Joshine\Review\Helper\ImageHelper;
use Magento\Catalog\Model\ProductFactory;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Review\Model\ResourceModel\Review\Collection;
use Magento\Review\Model\Review;
class ReviewInfo extends \Magento\Framework\App\Action\Action {
/**
* @var \Magento\Framework\Data\Form\FormKey\Validator
*/
private $formKeyValidator;
/**
* @var \Psr\Log\LoggerInterface
*/
private $logger;
/**
* @var \Magento\Framework\Json\EncoderInterface
*/
private $jsonEncoder;
/**
* @var JsonFactory
*/
private $resultJsonFactory;
private $reviewFactory;
/**
* @var ProductFactory
*/
private $productFactory;
/**
* @var \Magento\Review\Model\ResourceModel\Review\CollectionFactory
*/
private $reviewsColFactory;
/**
* @var \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress
*/
private $remoteAddress;
public function __construct(
Context $context,
\Psr\Log\LoggerInterface $logger,
\Magento\Framework\Json\EncoderInterface $jsonEncoder,
JsonFactory $resultJsonFactory,
\Magento\Review\Model\ReviewFactory $reviewFactory,
ProductFactory $productFactory,
\Magento\Review\Model\ResourceModel\Review\CollectionFactory $reviewsColFactory,
\Magento\Framework\Data\Form\FormKey\Validator $formKeyValidator,
\Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress
) {
parent::__construct($context);
$this->logger = $logger;
$this->jsonEncoder = $jsonEncoder;
$this->resultJsonFactory = $resultJsonFactory;
$this->reviewFactory = $reviewFactory;
$this->productFactory = $productFactory;
$this->reviewsColFactory = $reviewsColFactory;
$this->formKeyValidator = $formKeyValidator;
$this->remoteAddress = $remoteAddress;
}
/**
* @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\Result\Json|\Magento\Framework\Controller\ResultInterface
*/
public function execute()
{
$message = [
'error' => __('Sorry. There is a problem with your Request.')
];
if ($this->getRequest()->isAjax()) {
try {
if (!$this->formKeyValidator->validate($this->getRequest())) {
throw new LocalizedException(
__('Form key is not valid. Please try to reload the page.')
);
}
$reviewId = $this->getRequest()->getParam('review_id');
$productId = $this->getRequest()->getParam('product_id');
if (empty($reviewId) || empty($productId) ) {
throw new LocalizedException(
__('request is valid.')
);
}
$reviewInfo = $this->getReviewInfo($reviewId, $productId);
$reviews = $this->getAllReview($productId);
$message = [
'success' => __('Success.'),
'data' => $reviews,
'review' => $reviewInfo,
'total' => count($reviews),
'offset' => $this->getOffset($reviews, $reviewInfo)
];
} catch (LocalizedException $e) {
$message = ['error' => $e->getMessage()];
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
}
}
$resultPage = $this->resultJsonFactory->create();
$resultPage->setHttpResponseCode(200);
$resultPage->setData($message);
return $resultPage;
}
/**
* @param $productId
* @return \Magento\Review\Model\ResourceModel\Review\Collection
*/
public function getCollection($productId) : Collection
{
return $this->reviewsColFactory->create()->addStatusFilter(
\Magento\Review\Model\Review::STATUS_APPROVED
)->addEntityFilter(
'product',
$productId
);
}
private function getStoreId()
{
$storeManager = $this->_objectManager->get('\Magento\Store\Model\StoreManagerInterface');
return $storeManager->getStore()->getId();
}
public function getRatingPercent($reviewId)
{
$ratingCollection = $this->_objectManager->get('Magento\Review\Model\ResourceModel\Rating\Option\Vote\Collection')
->addFieldToFilter('review_id',$reviewId);
$data = $ratingCollection->getData();
return $data[0]['percent'] ?? 100;
}
public function getAllReview($productId)
{
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$db = $objectManager->get( 'Magento\Framework\App\ResourceConnection' )->getConnection();
$tblReview = $db->getTableName( 'review' );
$tblImages = $db->getTableName( 'joshine_review_images' );
$tblDetail = $db->getTableName( 'review_detail' );
$select = $db->select()
->distinct()
->from( [ 'review' => $tblReview ], ['*'] )
->join( [ 'images' => $tblImages ], 'review.review_id = images.review_id' )
->join( [ 'review_detail' => $tblDetail ], 'review.review_id = review_detail.review_id' )
->where( 'review.entity_pk_value = ?', $productId )
->where('review.status_id = ? ', Review::STATUS_APPROVED)
->group('review.review_id')->limit(50)->order('review.created_at DESC',);
$data = $db->fetchAll($select);
$res = [];
foreach ($data as $item) {
$_item['review_id'] = $item['review_id'];
$_item['size_fits'] = $item['size_fits'];
$_item['nickname'] = $item['nickname'];
$_item['title'] = $item['title'];
$_item['detail'] = $item['detail'];
$_item['created_at'] = $item['created_at'];
$_item['images'] = $this->getImages($item['review_id'], $productId);
$_item['rating'] = $this->getRatingPercent($item['review_id']);
$_item['helpful'] = $this->getVoteCount($item['review_id'])['plus'];
$_item['helpful_clicked'] = $this->getVoteCount($item['review_id'], $this->remoteAddress->getRemoteAddress())['plus'] > 0;
$res[] = $_item;
}
return $res;
}
public function getReviewInfo($reviewId, $productId)
{
$model = $this->reviewFactory->create()->load($reviewId);
$_item = [];
$_item['review_id'] = $reviewId;
$_item['size_fits'] = $model->getSize_fits();
$_item['nickname'] = $model->getNickname();
$_item['title'] = $model->getTitle();
$_item['detail'] = $model->getDetail();
$_item['created_at'] = $model->getCreatedAt();
$_item['images'] = $this->getImages($reviewId, $productId);
$_item['rating'] = $this->getRatingPercent($reviewId);
$_item['helpful'] = $this->getVoteCount($reviewId)['plus'];
$_item['helpful_clicked'] = $this->getVoteCount($reviewId, $this->remoteAddress->getRemoteAddress())['plus'] > 0;
return $_item;
}
public function getVoteCount($reviewId, $ip=null)
{
$repo = $this->_objectManager->get('Joshine\Review\Model\Repository\VoteRepository');
return $repo->getVotesCount($reviewId);
}
public function getImages($reviewId, $productId)
{
$collect = $this->_objectManager->create('Joshine\Review\Model\ResourceModel\Images\Collection')
->addFieldToSelect('*')
->addFieldToFilter('review_id', $reviewId);
/** @var $helper BlockHelper */
$helper = $this->_objectManager->get('Joshine\Review\Helper\BlockHelper');
$block = $helper->getReviewImagesBlock($reviewId, $productId);
$res = [];
foreach ($collect->getItems() as $item) {
$res['full'][] = ['url'=>$block->getFullImagePath($item), 'image_id'=>$item->getId()] ;
$res['thumb'][] = ['url'=>$block->getResizedImagePathByLimit($item, 100), 'image_id'=>$item->getId()] ; ;
}
return $res;
}
public function getOffset($allArr, $arr)
{
$offset = 0;
foreach ($allArr as $key => $value) {
$offset++;
if ($value['review_id'] == $arr['review_id']) {
break;
}
}
return $offset;
}
}
\ No newline at end of file
......@@ -101,7 +101,6 @@ class ImageHelper
$destination = $imageResized;
$imageResize->save($destination);
return $resizedURL;
}
}
......@@ -5,6 +5,7 @@ $collection = $block->getCollection();
<?php if ($collection->getSize()): ?>
<?php foreach ($collection as $item): ?>
<div class="joshine-review-pic-item joshine-col-xs-4" data-img-src="<?= $block->getFullImagePath($item) ?>"
data-image-id="<?= $item->getId(); ?>"
data-product-id="<?= $block->getProductId() ?>"
data-reviews-id="<?= $block->getReviewId() ?>">
<img class="review-image rounded" src="<?= $block->getResizedImagePath($item) ?>"/>
......
......@@ -366,11 +366,12 @@ $imagesBlock = $helper->getReviewImagesBlock(15, $block->getProductId());
transition-property: transform,-webkit-transform;
-webkit-box-sizing: content-box;
box-sizing: content-box;
overflow: hidden;
}
.swiper-item {
position: relative;
margin-right: 1px;
margin-right: 2px;
}
.swiper-item img {
......@@ -465,6 +466,13 @@ $imagesBlock = $helper->getReviewImagesBlock(15, $block->getProductId());
cursor: url(static/frontend/Joshine/breeze/en_US/Joshine_Review/img/favicon-next.ico), auto;
}
.modal-reviews-details__image-thumbs-image{
position: relative;
height: 100%;
overflow: hidden;
border: 1px solid #efefef;
}
</style>
<div class="joshine-model-warp joshine-hidden">
......@@ -481,58 +489,37 @@ $imagesBlock = $helper->getReviewImagesBlock(15, $block->getProductId());
<div class="modal-reviews-details__image-swiper joshine-bg-silver">
<div class="swiper-container">
<div class="swiper-button-prev"></div>
<div class="swiper-wrapper">
<?php if ($imagesBlock->getCollection()->getSize()): ?>
<?php foreach ($imagesBlock->getCollection() as $item): ?>
<div class="swiper-item">
<img src="<?= $imagesBlock->getFullImagePath($item) ?>" alt="">
</div>
<?php endforeach; ?>
<?php endif;?>
<div class="swiper-wrapper image-full-wrapper" data-review-js="image-full-wrapper">
</div>
<div class="swiper-button-next"></div>
</div>
</div>
<div class="modal-reviews-details__image-thumbs">
<div class="image-thumbs-list">
<?php if ($imagesBlock->getCollection()->getSize()): ?>
<?php foreach ($imagesBlock->getCollection() as $item): ?>
<div class="image-thumbs-list-item">
<div class="modal-reviews-details__image-thumbs-image active">
<img src="<?= $imagesBlock->getFullImagePath($item) ?>" alt="">
</div>
</div>
<?php endforeach; ?>
<?php endif;?>
<div class="image-thumbs-list" data-review-js="image-thumbs-wrapper">
</div>
</div>
</div>
<div class="modal-reviews-details__des-wrap joshine-col-xs-4">
<div class="joshine-review-des-head">
<span class="joshine-review-nickname" style="font-size: .9em;">
halweg
<span class="joshine-review-nickname" data-review-js="nickname" style="font-size: .9em;">
</span>
<div class="joshine-rating-container joshine-rating-small" style="margin-bottom: 3px;">
<div class="joshine-rating-starts" style="width: 60%;"></div>
<div class="joshine-rating-starts" style="width: 100%;" data-review-js="rating"></div>
</div>
<span class="joshine-review-date joshine-font-c-darkgray joshine-font-mini-plus joshine-pull-right">
2020/03/04 11:11
<span class="joshine-review-date joshine-font-c-darkgray joshine-font-mini-plus joshine-pull-right" data-review-js="date">
</span>
</div>
<div class="joshine-review-des-title joshine-font-w-bolder joshine-font-text joshine-font-c-deepin">
I love this product!!!
<div class="joshine-review-des-title joshine-font-w-bolder joshine-font-text joshine-font-c-deepin" data-review-js="title">
</div>
<div class="joshine-review-des-text joshine-font-c-darkgray joshine-font-mini-plus">
This Product is good,This Product is good,This Product is good,This Product is good,
This Product is good,This Product is good,This Product is good,This Product is good,
This Product is good,This Product is good,This Product is good,This Product is good,
<div class="joshine-review-des-text joshine-font-c-darkgray joshine-font-mini-plus" data-review-js="detail">
</div>
<div class="joshine-foot-mark rate-fit">
<div class="rate-fit-item">
<span><strong class="joshine-font-w-bolder">Size Fits:</strong> Small </span>
<span><strong class="joshine-font-w-bolder">Size Fits:</strong> <span data-review-js="fits"></span></span>
</div>
</div>
</div>
......@@ -547,6 +534,7 @@ $imagesBlock = $helper->getReviewImagesBlock(15, $block->getProductId());
require([
'jquery','ko'
], function ($) {
$(".joshine-review-add-btn").on('click',function () {
$(".block.review-add").removeClass('joshine-hidden');
});
......@@ -586,36 +574,172 @@ $imagesBlock = $helper->getReviewImagesBlock(15, $block->getProductId());
});
});
var img_idx = 0;
// 节流锁
var lock = true;
var swiper_wrapper = $('.swiper-wrapper');
var reviewList;
$(".joshine-review-pic-item").on('click', function () {
$(".joshine-model-warp").removeClass('joshine-hidden')
var reviewId = $(this).data('reviews-id');
var productId = $(this).data('product-id');
var image_id = $(this).data('image-id');
var formKey = $.mage.cookies.get('form_key');
var data = 'review_id='+ reviewId +'&form_key=' + formKey + '&product_id=' + productId;
$.ajax({
url: '/joshine_review/ajax/reviewinfo',
data: data,
type: 'GET',
dataType: 'json',
success: function (response) {
reviewList = response.data;
processModal(response);
pullIdx(image_id);
}
});
function processModal(response)
{
processReview(response.review);
processThumbs(response);
processFullImage(response);
$(".joshine-model-warp").removeClass('joshine-hidden')
}
function processThumbs(response) {
var html = '';
var image_index = 0;
var data = response.data;
for (let i = 0; i < data.length; i++) {
for (let j = 0; j < data[i].images.thumb.length; j++) {
html += `
<div class="image-thumbs-list-item" data-review-id="${data[i].review_id}" data-img-index="${image_index}" data-image-id="${data[i].images.thumb[j].image_id}">
<div class="modal-reviews-details__image-thumbs-image">
<img src="${data[i].images.thumb[j].url}" alt="">
</div>
</div>
`;
image_index++;
}
}
$('.image-thumbs-list').html(html);
}
function processFullImage(response)
{
var html = '';
var image_index = 0;
var data = response.data;
for (let i = 0; i < data.length; i++) {
for (let j = 0; j < data[i].images.full.length; j++) {
html += `
<div class="swiper-item" data-review-id="${data[i].review_id}" data-img-index="${image_index}" data-image-id="${data[i].images.full[j].image_id}">
<img src="${data[i].images.full[j].url}" alt="">
</div>
`;
image_index++;
}
}
$('.image-full-wrapper').html(html);
}
function processReview(review) {
$('[data-review-js="nickname"]').html(review.nickname);
$('[data-review-js="title"]').html(review.title);
$('[data-review-js="detail"]').html(review.detail);
$('[data-review-js="date"]').html(review.created_at);
let fits_text = fitsTranslate(review.size_fits);
$('[data-review-js="fits"]').html(fits_text);
$('[data-review-js="rating"]').width(review.rating + '%');
}
function fitsTranslate(fits) {
var fits_words = 'default';
if (fits === '1') {
fits_words = 'Small';
}
if (fits === '2') {
fits_words = 'Ture Size';
}
if (fits === '3') {
fits_words = 'Large';
}
return fits_words;
}
function pullIdx(id)
{
img_idx = findIdxByImgId(id);
swiper_wrapper.css({"transform" : 'translateX(' + -536 * img_idx + 'px)'});
dealIndex(img_idx);
}
function findIdxByImgId(imgId)
{
let res = 0;
$(".image-thumbs-list-item").each(function (index, ele) {
if ($(ele).data('image-id') == imgId) {
res = $(ele).data('img-index');
}
});
return res;
}
});
$(".joshine-close").on('click', function () {
$(".joshine-model-warp").addClass('joshine-hidden')
});
var img_idx = 0;
// 节流锁
var lock = true;
var swiper_wrapper = $('.swiper-wrapper');
function dealIndex(img_idx)
{
$('.image-thumbs-list-item').each(function (index, element) {
if ($(element).data('img-index') == img_idx && !$(this).hasClass('active')) {
$(element).addClass('active');
return;
}
$(element).removeClass('active');
});
}
$(".swiper-button-next").on('click', function () {
if (!lock) return;
lock = false;
swiper_wrapper.css({"transition" : 'transform .5s ease 0s'});
img_idx++;
swiper_wrapper.css({"transform" : 'translateX(' + -536 * img_idx + 'px)'});
// 开锁,动画结束之后开锁
dealIndex(img_idx);
setTimeout(function () {
lock = true;
}, 500);
});
$(".swiper-button-prev").on('click', function () {
if (!lock) return;
lock = false;
if (img_idx == 0) {
setTimeout(function () {
lock = true;
}, 500);
return;
}
swiper_wrapper.css({"transition" : 'transform .5s ease 0s'});
img_idx--;
swiper_wrapper.css({"transform" : 'translateX(' + -536 * img_idx + 'px)'});
dealIndex(img_idx);
setTimeout(function () {
lock = true;
}, 500);
});
function getReviewInfo(reviewId)
{
}
});
</script>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment