Authored by 沈志敏

活动模版

'use strict';
const model = require('../models/feature');
exports.index = function(req, res, next) {
let code = req.params.code;
model.index(code).then((result) => {
res.render('feature', {
module: 'activity',
page: 'feature',
title: result.name || 'Yoho!Buy有货',
content: result,
isFeature: true
});
}).catch(next);
};
... ...
'use strict';
const activeapi = global.yoho.ActiveAPI;
const api = global.yoho.API;
const helpers = global.yoho.helpers;
const _getProductBySkns = function(productObj) {
return api.get('', {
productSkn: productObj.defaultSkns,
method: 'h5.product.batch'
}).then((result) => {
let nskns = [];
if (result && result.data && result.data.product_list && result.code === 200) {
result.data.product_list.forEach(function(val) {
var goods_id = Array.isArray(val.goods_list) && val.goods_list.length ? val.goods_list[0].goods_id : null;
var obj = {
producturl: `//m.yohobuy.com/product/pro_${val.product_id}_${goods_id}/${val.cn_alphabet}.html?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":${val.product_skn}}}`,
productimg: helpers.image(val.default_images, 213, 284, 2, 60).replace('quality/80', 'quality/60'),
productname: val.product_name,
saleprice: val.sales_price,
marketprice: val.sales_price === val.market_price ? '' : val.market_price,
brandname: val.brand_name
};
if (val.shop_id) {
obj.brandurl = `//m.yohobuy.com/product/index/brand?domain=${val.brand_domain}&openby:yohobuy={"action":"go.shop","params":{"shop_id":${val.shop_id},"shop_template_type":${val.shop_template_type}}}`;
} else {
obj.brandurl = `//m.yohobuy.com/product/index/brand?domain=${val.brand_domain}&openby:yohobuy={"action":"go.brand","params":{"brand_id":${val.brand_id}}}`;
}
nskns.push(obj);
});
productObj.defaultSkns = nskns;
} else {
delete productObj.defaultSkns;
}
});
};
module.exports = {
index: function(code) {
return Promise.coroutine(function*() {
if (!code) {
return Promise.resolve({});
}
let data = yield activeapi.get('', {
method: 'app.activity.template',
activity_id: code
});
if (data.code === 200) {
data = data.data;
}
let sknsArr = [];
if (data.floors) {
data.floors.forEach(function(f) {
if (f.component && f.component[0] && f.component[0].type === 'productGroup' && f.component[0].defaultSkns) {
sknsArr.push(_getProductBySkns(f.component[0]));
}
});
}
if (sknsArr.length) {
yield Promise.all(sknsArr);
}
return data;
})();
}
};
... ...
... ... @@ -34,6 +34,8 @@ const promotion = require(`${cRoot}/promotion`);
const individuation = require(`${cRoot}/individuation`);
const feature = require(`${cRoot}/feature`);
const appDownloads = require(`${cRoot}/app-downloads`);
const redbag = require(`${cRoot}/redbag`);
... ... @@ -162,6 +164,9 @@ router.get('/redbag/2017', redbag.index);
// 获取活动页面个性化推荐商品数据
router.get('/individuation', individuation.productLst);
// 活动页模版
router.get('/feature/:code', feature.index);
// 2016 年度账单
router.get('/annual-account', annualAccount.index);
router.get('/annual-account/share', annualAccount.share);
... ...
<div class="feature-page yoho-page">
{{#content.floors}}
{{#isEqualOr type 'sidebar'}}
{{! 侧悬浮}}
<div class="cexuanfu" id="load_cxf"></div>
{{/isEqualOr}}
{{#isEqualOr type '' 'common_floor' 'fix'}}
{{! 普通楼层 顶悬浮}}
<div {{#if param.anchorname}}id="{{param.anchorname}}"{{/if}} {{#if id}}data-id="{{id}}"{{/if}} class="floor {{type}}"
style="{{#if param.bgcolor}}background-color:{{param.bgcolor}}{{/if}}">
{{#if param.bgimg}}
<img src="{{image2 param.bgimg q=60}}">
{{/if}}
{{#component}}
{{#isEqualOr type 'link'}}
{{! 普通组件}}
<a class="anchor" style="{{styleFormat this percent=1}}" href="{{#if url}}{{url}}{{else}}javascript:void(0);{{/if}}" fp="{{getAnalysis ../this @index}}"></a>
{{/isEqualOr}}
{{#isEqualOr type 'coupon'}}
{{! 优惠券}}
<a class="anchor yoho-conpon" style="{{styleFormat this percent=1}}" data-token="{{token}}" href="{{#if url}}{{url}}{{else}}javascript:void(0);{{/if}}" fp="{{getAnalysis ../this @index}}"></a>
{{/isEqualOr}}
{{#isEqualOr type 'yohoCoin'}}
{{! 有货币}}
<a class="anchor yoho-coin" style="{{styleFormat this percent=1}}" data-token="{{token}}" href="{{#if url}}{{url}}{{else}}javascript:void(0);{{/if}}" fp="{{getAnalysis ../this @index}}"></a>
{{/isEqualOr}}
{{#isEqualOr type 'video'}}
{{! 视频}}
<a class="anchor video-bg" style="{{styleFormat this percent=1}}" href="{{#if url}}{{url}}{{else}}javascript:void(0);{{/if}}" fp="{{getAnalysis ../this @index}}"></a>
<div class="video-android-close hide"></div>
<div class="video-android-bg hide"></div>
<video class="video" controls loop preload="meta" name="media">
<source src="{{videoSrc}}">
</video>
{{/isEqualOr}}
{{#isEqualOr type 'marquee' 'swiper'}}
{{! 轮播/滑动}}
<div class="swiper-container {{type}}" data-loop="{{loop}}" {{#if autoplay}}data-autoplay="{{autoplay}}"{{/if}}>
<div class="swiper-wrapper">
{{#list}}
<div class="swiper-slide" style="{{styleFormat this percent=1}}">
<img src="{{image2 src q=60}}">
<a class="anchor" href="{{#if link}}{{link}}{{else}}javascript:void(0);{{/if}}" fp="{{getAnalysis ../../this @index}}"></a>
</div>
{{/list}}
</div>
{{#isEqualOr type 'marquee'}}
<div class="swiper-pagination"></div>
{{/isEqualOr}}
</div>
{{/isEqualOr}}
{{#isEqualOr type 'tab'}}
{{! tab}}
<div class="tab-container">
{{#repeat count}}
<a class="anchor {{#if @first}}active{{/if}}" style="{{tabStyle @index ../count}}"></a>
{{/repeat}}
</div>
{{/isEqualOr}}
{{#isEqualOr type 'productGroup'}}
{{! 商品池}}
<div class="product-container item{{numOfOneRow}}">
<div class="product-source" {{#if searchCondition}}cloneitem="{{searchCondition.limit}}" condition='{{stringify searchCondition}}'{{/if}} fp="{{getAnalysis ../this @index}}">
<input class="imgwh" type="hidden" value="193x257">
{{#ifand defaultSkns defaultSkns.length}}
{{#defaultSkns}}
<div class="feature-product-info {{#if ../condition}}novisible{{/if}}">
<a class="first-part product-detail" href='{{producturl}}'>
<div class="product-detail-imgbox">
{{#if ../lefTopImg}}<img class="leftopimg" src="{{image2 ../lefTopImg q=60}}">{{/if}}
{{#if ../rigTopImg}}<img class="rigtopimg" src="{{image2 ../rigTopImg q=60}}">{{/if}}
<img class="product-detail-img" src="{{image2 productimg q=60}}">
</div>
{{#isEqualOr ../showPrdName '1'}}<p class="product-name">{{productname}}</p>{{/isEqualOr}}
<div class="product-detail-text">
<div class="price">
<span class="sale-price">¥{{saleprice}}</span>
{{#if marketprice}}<span class="market-price">¥{{marketprice}}</span>{{/if}}
</div>
</div>
</a>
{{#if ../brandImg}}
<a class="second-part {{#isEqualOr ../showBrandUrl '1'}}product-brand{{else}}product-detail{{/isEqualOr}}" href='{{brandurl}}'>
<div class="brand-div">
<span class="brand-name">{{brandname}}</span>
</div>
<img class="brand-img" src="{{image2 ../brandImg q=60}}">
</a>
{{/if}}
</div>
{{/defaultSkns}}
{{else}}
<div class="feature-product-info novisible">
<a class="first-part product-detail" href=''>
<div class="product-detail-imgbox">
{{#if lefTopImg}}<img class="leftopimg" src="{{image2 lefTopImg q=60}}">{{/if}}
{{#if rigTopImg}}<img class="rigtopimg" src="{{image2 rigTopImg q=60}}">{{/if}}
<img class="product-detail-img" src="">
</div>
{{#isEqualOr showpname '1'}}<p class="product-name"></p>{{/isEqualOr}}
<div class="product-detail-text">
<div class="price">
<span class="sale-price"></span>
<span class="market-price"></span>
</div>
</div>
</a>
{{#if brandImg}}
<a class="second-part {{#isEqualOr showBrandUrl '1'}}product-brand{{else}}product-detail{{/isEqualOr}}" href=''>
<div class="brand-div">
<span class="brand-name"></span>
</div>
<img class="brand-img" src="{{image2 brandImg q=60}}">
</a>
{{/if}}
</div>
{{/ifand}}
</div>
</div>
{{/isEqualOr}}
{{/component}}
</div>
{{/isEqualOr}}
{{/content.floors}}
</div>
\ No newline at end of file
... ...
... ... @@ -44,22 +44,30 @@
{{#if localCss}}
<link rel="stylesheet" media="all" href="//{{devHost}}:5001/bundle/common.css">
{{/if}}
{{#ifor localCss vue}}
<link rel="stylesheet" media="all" href="//{{devHost}}:5001/bundle/{{module}}.{{page}}.css">
{{^}}
<link rel="stylesheet" media="all" href="//{{devHost}}:5001/bundle/index.css">
{{/ifor}}
{{#if isFeature}}
<link rel="stylesheet" media="all" href="//{{devHost}}:5001/bundle/feature.css">
{{else}}
{{#ifor localCss vue}}
<link rel="stylesheet" media="all" href="//{{devHost}}:5001/bundle/{{module}}.{{page}}.css">
{{^}}
<link rel="stylesheet" media="all" href="//{{devHost}}:5001/bundle/index.css">
{{/ifor}}
{{/if}}
{{^}}
{{#if localCss }}
<link rel="stylesheet" media="all" href="//cdn.yoho.cn/m-yohobuy-node/{{version}}/common.css">
{{/if}}
{{#ifor localCss vue}}
<link rel="stylesheet" media="all" href="//cdn.yoho.cn/m-yohobuy-node/{{version}}/{{module}}.{{page}}.css">
{{^}}
<link rel="stylesheet" media="all" href="//cdn.yoho.cn/m-yohobuy-node/{{version}}/index.css">
{{/ifor}}
{{#if isFeature}}
<link rel="stylesheet" media="all" href="//cdn.yoho.cn/m-yohobuy-node/{{version}}/feature.css">
{{else}}
{{#ifor localCss vue}}
<link rel="stylesheet" media="all" href="//cdn.yoho.cn/m-yohobuy-node/{{version}}/{{module}}.{{page}}.css">
{{^}}
<link rel="stylesheet" media="all" href="//cdn.yoho.cn/m-yohobuy-node/{{version}}/index.css">
{{/ifor}}
{{/if}}
{{/if}}
<link rel="apple-touch-icon-precomposed" href="http://static.yohobuy.com/m/v1/img/touch/apple-touch-icon-144x144-precomposed-new.png">
<link rel="apple-touch-startup-image" sizes="640x920" href="http://static.yohobuy.com/m/v1/img/startup/startup-retina.png" media="screen and (max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2)">
... ... @@ -97,7 +105,9 @@
<script src="//cdn.yoho.cn/m-yohobuy-node/{{version}}/libs.js"></script>
<script src="//cdn.yoho.cn/m-yohobuy-node/{{version}}/{{module}}.{{page}}.js"></script>
{{/if}}
{{#unless devEnv}}
{{#isFeature}}
<script type="text/javascript" src="//cdn.yoho.cn/js-sdk/99.99.99/jssdk.js"></script>
{{/isFeature}}
{{> analysis}}
{{/unless}}
</body>
... ...
... ... @@ -160,7 +160,7 @@ gulp.task('dist', ['ge'], () => {
// postcss compile in dev
gulp.task('postcss-dev', () => {
return gulp.src(['scss/index.css', 'scss/common.css'])
return gulp.src(['scss/index.css', 'scss/common.css', 'scss/feature.css'])
.pipe(sourcemaps.init())
.pipe(postcss(postcssPlugin(env.dev), {
parser: require('postcss-scss')
... ... @@ -191,7 +191,7 @@ gulp.task('font', () => {
// postcss compile in pro
gulp.task('postcss', ['assets'], () => {
return gulp.src(['scss/index.css', 'scss/common.css'])
return gulp.src(['scss/index.css', 'scss/common.css', 'scss/feature.css'])
.pipe(postcss(postcssPlugin(env.pro), {
parser: require('postcss-scss')
}))
... ...
var $ = require('yoho-jquery');
var Swiper = require('yoho-swiper');
global.jQuery = $;
var isAndroid = /(Android)/i.test(navigator.userAgent);
var isWechat = /micromessenger/i.test(navigator.userAgent);
function swiperInit() {
$('.swiper-container').each(function() {
var opt = {
loop: $(this).data('loop') === '1' ? true : false,
spaceBetween: 15,
slidesPerView: 'auto'
};
var autoplay = $(this).data('autoplay');
var pagination = $(this).find('.swiper-pagination');
if (autoplay) {
opt.autoplay = Number(autoplay);
}
if (pagination) {
opt.pagination = pagination;
opt.paginationClickable = true;
}
new Swiper(this, opt);
});
}
function topNavInit() {
var topnav = $('.floor.fix');
if (topnav.length) {
var doc = $(document);
var cloneNav = topnav.clone().addClass('fixnav').prependTo($('.feature-page'));
$(window).scroll(function() {
var top = doc.scrollTop();
var top1 = topnav.offset().top;
if (top > top1) {
cloneNav.fadeIn('slow');
} else {
cloneNav.fadeOut('slow');
}
});
}
}
function ceXuanFuInit() {
$('#load_cxf').load('http://feature.yoho.cn/public/cexuanfu/cexuanfu.html', function() {
$('#cxf').click(function() {
if ($(this).hasClass('isclick')) {
$('.cxfall').hide();
$(this).removeClass('iscxf');
} else {
$('.cxfall').show();
$(this).addClass('iscxf');
}
});
$('.cxfallbg').click(function() {
$(this).parent().hide();
$('#cxf').removeClass('iscxf');
});
});
}
function videoInit() {
function cancelMove(e) {
e.preventDefault && e.preventDefault();
e.returnValue = false;
e.stopPropagation && e.stopPropagation();
return false;
}
$('.video-bg').on('click', function() {
var v = $(this).nextAll('video')[0];
v.play();
if (isAndroid && !isWechat) {
$('.video').addClass('android');
$('.video-android-bg').removeClass('hide');
$('.video-android-close').removeClass('hide');
$('body').css('overflow', 'hidden').on('touchmove', cancelMove);
}
});
$('.video-android-close').on('click', function() {
$('.video').removeClass('android');
$('.video-android-bg').addClass('hide');
$('.video-android-close').addClass('hide');
$('body').css('overflow', '').off('touchmove', cancelMove);
$(this).nextAll('video')[0].pause();
});
}
function tabInit() {
var tabContainer = $('.tab-container');
var nextDom = tabContainer.parent().nextAll();
var tab = tabContainer.find('a.anchor');
tab.on('click', function() {
tab.removeClass('active');
$(this).addClass('active');
var index = $(this).index();
for (var i = 0; i < tab.length; i++) {
if (index === i) {
$(nextDom[i]).show();
} else {
$(nextDom[i]).hide();
}
}
});
for (var i = 1; i < tab.length; i++) {
$(nextDom[i]).hide();
}
}
$(function() {
// 微信中点击之后,返回跳到指定位置
var totalH, scH;
var top = localStorage.changtu1;
window.scrollTo(0, top);
localStorage.removeItem('changtu1');
$('a').click(function() {
totalH = event.pageY;
scH = event.clientY;
localStorage.changtu1 = totalH - scH; // 每次点击缓存高度
});
// 轮播
swiperInit();
// 顶悬浮
topNavInit();
// 侧悬浮
ceXuanFuInit();
// 视频相关
videoInit();
// tab
tabInit();
});
... ...
@charset "utf-8";
@import "feature/anchor";
@import "feature/product";
@import "feature/swiper.min";
\ No newline at end of file
... ...
body,
ul,
dl,
dd,
dt,
ol,
li,
p,
h1,
h2,
h3,
h4,
h5,
h6,
textarea,
form,
select,
fieldset,
table,
td,
div,
input {
margin: 0;
padding: 0;
-webkit-text-size-adjust: none;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-size: 12px;
font-weight: normal;
}
body > div {
margin: 0 auto;
}
div {
text-align: left;
}
a img {
border: 0;
}
body {
color: #333;
text-align: center;
font-size: 12px;
font-family: helvetica,Arial,黑体;
}
ul,
ol,
li {
list-style-type: none;
vertical-align: 0;
}
body {
background-color: #fff;
color: #666;
}
* {
-webkit-user-select: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-ms-touch-action: none;
-webkit-touch-callout: none;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.feature-page {
max-width: 640px;
margin: 0 auto;
}
.feature-page .cexuanfu {
img {
width: 100%;
}
.anchor {
position: absolute;
top: 0;
left: 0;
background: transparent;
cursor: pointer;
z-index: 100;
}
}
.feature-page .floor {
width: 100%;
position: relative;
img {
display: block;
width: 100%;
height: 100%;
}
.anchor {
position: absolute;
top: 0;
left: 0;
background: transparent;
cursor: pointer;
z-index: 100;
}
.hide {
display: none;
}
/*顶悬浮*/
&.fixnav {
position: fixed;
top: 0;
left: 0;
width: 100%;
display: none;
z-index: 1000;
}
.tab-container {
a.active {
background: rgba(0, 0, 0, 0.2);
}
}
}
.swiper-container {
height: 100%;
&.swiper {
padding: 5px 10px;
height: 100%;
}
}
.swiper-slide {
.anchor {
width: 100%;
height: 100%;
}
}
/*弹窗*/
.tc_box {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
margin: 0 auto;
display: none;
z-index: 1000;
}
.tc_bg {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
margin: 0 auto;
z-index: 1001;
}
.tc_con {
position: fixed;
top: 50%;
left: 3.9%;
width: 92.2%;
margin-top: -200px;
z-index: 1000000;
display: block;
}
\ No newline at end of file
... ...
.video {
position: fixed;
top: -100%;
width: 100%;
height: 360px;
z-index: 3;
&.android {
top: 30%;
z-index: 1002;
}
}
.video-android-bg {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 1001;
background: #000;
opacity: 0.7;
}
.video-android-close {
position: fixed;
top: 26.2%;
right: 10px;
width: 35px;
height: 35px;
z-index: 1003;
background-image: resolve("activity/close.png");
background-size: cover;
}
.product-container {
overflow: hidden;
padding: 0 20px 10px;
font-size: 22px;
&.item3 {
padding: 0 20px 10px;
font-size: 20px;
.feature-product-info {
width: 193px;
margin-right: 10px;
&:nth-of-type(3n) {
margin-right: 0;
}
.product-detail-img {
height: 257px;
}
.price {
line-height: 34px;
height: 34px;
}
}
.brand-name {
line-height: 23px;
font-size: 12px;
}
}
.product-source {
display: block;
overflow: hidden;
position: relative;
}
.feature-product-info {
float: left;
width: 288px;
margin-right: 20px;
border: 1px solid #eee;
margin-top: 25px;
overflow: hidden;
&.novisible {
visibility: hidden;
}
&:nth-of-type(2n) {
margin-right: 0;
}
a {
display: block;
text-decoration: none;
}
img {
display: block;
width: 100%;
}
.first-part {
background: #fff;
}
.product-detail-imgbox {
position: relative;
.product-detail-img {
width: 100%;
height: 380px;
}
}
.product-name {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
color: #444;
height: 60px;
line-height: 35px;
padding: 0 5px;
}
.leftopimg {
position: absolute;
left: 0;
top: 0;
width: 40%;
height: auto;
z-index: 1;
}
.rigtopimg {
position: absolute;
right: 0;
top: 0;
width: 40%;
height: auto;
z-index: 1;
}
.price {
font-size: 18px;
line-height: 40px;
height: 40px;
white-space: nowrap;
text-align: center;
}
.sale-price {
color: #f73207;
font-size: 30px;
}
.market-price {
margin: 0 0 0 3px;
color: #bebebe;
text-decoration: line-through;
}
}
.second-part {
display: block;
color: #fff;
font-size: 32px;
position: relative;
.brand-div {
position: absolute;
top: 8px;
left: 50%;
width: 100%;
transform: translateX(-50%);
}
.brand-name {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
text-align: center;
line-height: 30px;
overflow: hidden;
font-size: 26px;
}
.brand-img {
display: block;
margin: 0 auto;
}
}
}
\ No newline at end of file
... ...
@charset "utf-8";
/* CSS Document */
/**
* Swiper 3.1.7
* Most modern mobile touch slider and framework with hardware accelerated transitions
*
* http://www.idangero.us/swiper/
*
* Copyright 2015, Vladimir Kharlampidi
* The iDangero.us
* http://www.idangero.us/
*
* Licensed under MIT
*
* Released on: October 10, 2015
*/
.swiper-container {
margin: 0 auto;
position: relative;
overflow: hidden;
/*z-index: 1*/
}
.swiper-container-no-flexbox .swiper-slide {
float: left;
}
.swiper-container-vertical > .swiper-wrapper {
-webkit-box-orient: vertical;
-moz-box-orient: vertical;
-ms-flex-direction: column;
-webkit-flex-direction: column;
flex-direction: column;
}
.swiper-wrapper {
position: relative;
width: 100%;
height: 100%;
z-index: 1;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-transition-property: -webkit-transform;
-moz-transition-property: -moz-transform;
-o-transition-property: -o-transform;
-ms-transition-property: -ms-transform;
transition-property: transform;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.swiper-container-android .swiper-slide,
.swiper-wrapper {
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-o-transform: translate(0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.swiper-container-multirow > .swiper-wrapper {
-webkit-box-lines: multiple;
-moz-box-lines: multiple;
-ms-flex-wrap: wrap;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
}
.swiper-container-free-mode > .swiper-wrapper {
-webkit-transition-timing-function: ease-out;
-moz-transition-timing-function: ease-out;
-ms-transition-timing-function: ease-out;
-o-transition-timing-function: ease-out;
transition-timing-function: ease-out;
margin: 0 auto;
}
.swiper-slide {
-webkit-flex-shrink: 0;
-ms-flex: 0 0 auto;
flex-shrink: 0;
width: 100%;
height: 100%;
position: relative;
}
.swiper-container .swiper-notification {
position: absolute;
left: 0;
top: 0;
pointer-events: none;
opacity: 0;
z-index: -1000;
}
.swiper-wp8-horizontal {
-ms-touch-action: pan-y;
touch-action: pan-y;
}
.swiper-wp8-vertical {
-ms-touch-action: pan-x;
touch-action: pan-x;
}
.swiper-button-next,
.swiper-button-prev {
position: absolute;
top: 50%;
width: 27px;
height: 44px;
margin-top: -22px;
z-index: 10;
cursor: pointer;
-moz-background-size: 27px 44px;
-webkit-background-size: 27px 44px;
background-size: 27px 44px;
background-position: center;
background-repeat: no-repeat;
}
.swiper-button-next.swiper-button-disabled,
.swiper-button-prev.swiper-button-disabled {
opacity: 0.35;
cursor: auto;
pointer-events: none;
}
.swiper-pagination {
position: absolute;
text-align: center;
-webkit-transition: 0.3s;
-moz-transition: 0.3s;
-o-transition: 0.3s;
transition: 0.3s;
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
z-index: 10;
}
.swiper-pagination.swiper-pagination-hidden {
opacity: 0;
}
.swiper-pagination-bullet {
width: 8px;
height: 8px;
border-radius: 50%;
display: inline-block;
background: #9b9b9a;
opacity: 1;
}
button.swiper-pagination-bullet {
border: none;
margin: 0;
padding: 0;
box-shadow: none;
-moz-appearance: none;
-ms-appearance: none;
-webkit-appearance: none;
appearance: none;
}
.swiper-pagination-clickable .swiper-pagination-bullet {
cursor: pointer;
}
.swiper-pagination-white .swiper-pagination-bullet {
background: #fff;
}
.swiper-pagination-bullet-active {
opacity: 1;
background: #383838;
}
.swiper-pagination-white .swiper-pagination-bullet-active {
background: #fff;
}
.swiper-pagination-black .swiper-pagination-bullet-active {
background: #000;
}
.swiper-container-vertical > .swiper-pagination {
right: 10px;
top: 50%;
-webkit-transform: translate3d(0, -50%, 0);
-moz-transform: translate3d(0, -50%, 0);
-o-transform: translate(0, -50%);
-ms-transform: translate3d(0, -50%, 0);
transform: translate3d(0, -50%, 0);
}
.swiper-container-vertical > .swiper-pagination .swiper-pagination-bullet {
margin: 5px 0;
display: block;
}
.swiper-container-horizontal > .swiper-pagination {
bottom: 0;
right: 0;
width: 100%;
}
.swiper-container-horizontal > .swiper-pagination .swiper-pagination-bullet {
margin: 0 3px;
}
.swiper-container-3d {
-webkit-perspective: 1200px;
-moz-perspective: 1200px;
-o-perspective: 1200px;
perspective: 1200px;
}
.swiper-container-3d .swiper-cube-shadow,
.swiper-container-3d .swiper-slide,
.swiper-container-3d .swiper-slide-shadow-bottom,
.swiper-container-3d .swiper-slide-shadow-left,
.swiper-container-3d .swiper-slide-shadow-right,
.swiper-container-3d .swiper-slide-shadow-top,
.swiper-container-3d .swiper-wrapper {
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.swiper-container-3d .swiper-slide-shadow-bottom,
.swiper-container-3d .swiper-slide-shadow-left,
.swiper-container-3d .swiper-slide-shadow-right,
.swiper-container-3d .swiper-slide-shadow-top {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 10;
}
.swiper-container-3d .swiper-slide-shadow-left {
background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));
background-image: -webkit-linear-gradient(right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
background-image: -moz-linear-gradient(right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
background-image: -o-linear-gradient(right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
background-image: linear-gradient(to left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
}
.swiper-container-3d .swiper-slide-shadow-right {
background-image: -webkit-gradient(linear, right top, left top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));
background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
}
.swiper-container-3d .swiper-slide-shadow-top {
background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));
background-image: -webkit-linear-gradient(bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
background-image: -moz-linear-gradient(bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
background-image: -o-linear-gradient(bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
background-image: linear-gradient(to top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
}
.swiper-container-3d .swiper-slide-shadow-bottom {
background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));
background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
}
.swiper-container-coverflow .swiper-wrapper {
-ms-perspective: 1200px;
}
.swiper-container-fade.swiper-container-free-mode .swiper-slide {
-webkit-transition-timing-function: ease-out;
-moz-transition-timing-function: ease-out;
-ms-transition-timing-function: ease-out;
-o-transition-timing-function: ease-out;
transition-timing-function: ease-out;
}
.swiper-container-fade .swiper-slide {
pointer-events: none;
}
.swiper-container-fade .swiper-slide .swiper-slide {
pointer-events: none;
}
.swiper-container-fade .swiper-slide-active,
.swiper-container-fade .swiper-slide-active .swiper-slide-active {
pointer-events: auto;
}
.swiper-container-cube {
overflow: visible;
}
.swiper-container-cube .swiper-slide {
pointer-events: none;
visibility: hidden;
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
-ms-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;
width: 100%;
height: 100%;
z-index: 1;
}
.swiper-container-cube.swiper-container-rtl .swiper-slide {
-webkit-transform-origin: 100% 0;
-moz-transform-origin: 100% 0;
-ms-transform-origin: 100% 0;
transform-origin: 100% 0;
}
.swiper-container-cube .swiper-slide-active,
.swiper-container-cube .swiper-slide-next,
.swiper-container-cube .swiper-slide-next + .swiper-slide,
.swiper-container-cube .swiper-slide-prev {
pointer-events: auto;
visibility: visible;
}
.swiper-container-cube .swiper-slide-shadow-bottom,
.swiper-container-cube .swiper-slide-shadow-left,
.swiper-container-cube .swiper-slide-shadow-right,
.swiper-container-cube .swiper-slide-shadow-top {
z-index: 0;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;
}
.swiper-container-cube .swiper-cube-shadow {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 100%;
background: #000;
opacity: 0.6;
-webkit-filter: blur(50px);
filter: blur(50px);
z-index: 0;
}
.swiper-scrollbar {
border-radius: 10px;
position: relative;
-ms-touch-action: none;
background: rgba(0, 0, 0, 0.1);
}
.swiper-container-horizontal > .swiper-scrollbar {
position: absolute;
left: 1%;
bottom: 3px;
z-index: 50;
height: 5px;
width: 98%;
}
.swiper-container-vertical > .swiper-scrollbar {
position: absolute;
right: 3px;
top: 1%;
z-index: 50;
width: 5px;
height: 98%;
}
.swiper-scrollbar-drag {
height: 100%;
width: 100%;
position: relative;
background: rgba(0, 0, 0, 0.5);
border-radius: 10px;
left: 0;
top: 0;
}
.swiper-scrollbar-cursor-drag {
cursor: move;
}
... ...
... ... @@ -5,7 +5,79 @@ const _ = require('lodash');
const config = require('../config/common');
const assetUrl = config.assetUrl;
const unitfromat = function(value, params) {
if (params.rem) {
value = Number(value) / (params.width || 40) + 'rem';
} else if (params.percent) {
value = value + '%';
} else {
value = value + 'px';
}
return value;
};
module.exports = {
getAnalysis: function(data, index) {
if (!data) {
return '';
}
let fp = {
F_ID: data.id,
F_INDEX: data.order,
F_NM: data.param.name,
I_INDEX: index
};
if (data.component[index] && data.component[index].name) {
fp.I_NM = data.component[index].name;
}
return JSON.stringify(fp);
},
styleFormat: function(styleObj, opts) {
let style = '';
if (styleObj && _.isObject(styleObj)) {
let params = opts.hash;
let keys = ['width', 'height', 'top', 'left', 'right', 'bottom'];
keys.forEach(function(k) {
if (styleObj[k]) {
style += k + ':' + unitfromat(styleObj[k], params) + ';';
}
});
}
return style;
},
tabStyle: function(index, count) {
let width = (100 / Number(count)).toFixed(2);
let style = 'height:100%;width:' + width + '%;';
style += 'left:' + (Number(index) * Number(width)) + '%;';
return style;
},
stringify: function(obj) {
return JSON.stringify(obj);
},
repeat: function(n, options) {
if (n) {
var str = '';
for (var i = 0; i < n; i++) {
var opt = {
index: i,
first: i === 0
};
str += options.fn(options, {
data: _.merge(opt, options)
});
}
return str;
}
return options.inverse(this);
},
imgSrc: function(imgSrc) {
return url.resolve(assetUrl, imgSrc);
},
... ... @@ -35,7 +107,7 @@ module.exports = {
} else if (params.q) {
query += '/quality/' + params.q;
}
} else if (query.indexOf('imageView/') === 0){
} else if (query.indexOf('imageView/') === 0) {
if (params.q && query.indexOf('/q/') > 0) {
query = query.replace(/\/q\/\d+/g, '/q/' + params.q);
} else if (params.q) {
... ... @@ -54,6 +126,43 @@ module.exports = {
return '';
}
},
isEqualOr: function() {
var args = Array.prototype.slice.call(arguments);
var v1 = args[0];
var opt = args[args.length - 1];
var isTrue = false;
for (var i = 1; i < args.length - 1; i++) {
if (v1 === args[i]) {
isTrue = true;
break;
}
}
if (isTrue) {
return opt.fn(this); // eslint-disable-line
} else {
return opt.inverse(this); // eslint-disable-line
}
},
ifand: function() {
var args = Array.prototype.slice.call(arguments);
var opt = args[args.length - 1];
var isTrue = true;
for (var i = 0; i < args.length - 1; i++) {
if (!args[i]) {
isTrue = false;
break;
}
}
if (isTrue) {
return opt.fn(this);
} else {
return opt.inverse(this);
}
},
ifor: function() {
var args = Array.prototype.slice.call(arguments);
var opt = args[args.length - 1];
... ...