Showing 45 changed files with 985 additions and 278 deletions
... ... @@ -21,12 +21,18 @@ module.exports = {
uid: {type: Number}
}
},
'/resource/get': {
'/api/resource/get': {
api: 'operations/api/v5/resource/get',
cache: true,
service: true,
params: {
content_code: {type: String},
}
},
'/api/search/fuzzy': {
api: 'app.search.fuzzy',
params: {
keyword: {type: String, require: true},
}
}
};
... ...
... ... @@ -18,9 +18,9 @@ module.exports = {
app_type: 1
},
domains: {
// api: 'http://api-test2.yohops.com:9999/',
// service: 'http://service-test2.yohops.com:9999/',
// singleApi: 'http://api-test2.yohops.com:9999/'
api: 'http://api-test3.yohops.com:9999/',
service: 'http://service-test3.yohops.com:9999/',
singleApi: 'http://api-test3.yohops.com:9999/'
// api: 'http://api-test2.yohops.com:9999/',
// service: 'http://service-test2.yohops.com:9999/',
... ... @@ -29,9 +29,9 @@ module.exports = {
// service: 'http://dev-service.yohops.com:9999/',
// singleApi: 'http://192.168.102.27:8092/'
// //
api: 'http://api.yoho.cn/',
service: 'http://service.yoho.cn/',
singleApi: 'http://single.yoho.cn/'
// api: 'http://api.yoho.cn/',
// service: 'http://service.yoho.cn/',
// singleApi: 'http://single.yoho.cn/'
},
subDomains: {
host: '.m.yohoblk.com',
... ...
const api = global.yoho.API;
const service = global.yoho.ServiceAPI;
const logger = global.yoho.logger;
const checkParams = require('../../utils/check-params');
const apiMaps = require('../../config/api-map');
module.exports = () => {
return (req, res, next) => {
return async (req, res, next) => {
const apiInfo = apiMaps[req.path];
if (!apiInfo) {
... ... @@ -24,18 +25,27 @@ module.exports = () => {
const params = checkParams.getParams(reqParams, apiInfo);
const cache = req.method.toLowerCase() !== 'get' ? false : apiInfo.cache;
let result;
if (apiInfo.service) {
return service.get(apiInfo.api, params, {
result = await service.get(apiInfo.api, params, {
cache: cache,
code: 200
});
} else {
return api[req.method]('', params, {
result = await api[req.method.toLowerCase()]('', params, {
code: 200,
cache: cache
});
}
if (result) {
return res.json(result);
}
return res.json({
code: 400
});
} catch (e) {
logger.error(e);
return res.json({
code: 400,
message: e
... ...
const fs = require('fs');
const path = require('path');
const LRU = require('lru-cache');
const _ = require('lodash');
const pkg = require('../../package.json');
const {createBundleRenderer} = require('vue-server-renderer');
... ... @@ -46,6 +47,7 @@ const render = (req, res, next) => {
renderer.renderToString(context, (err, html) => {
if (err) {
// TODO 处理错误类型
return next(err);
}
if (cacheable) {
... ... @@ -85,7 +87,12 @@ const ssrRender = isDev ? (req, res, next) => {
process.removeListener('message', event);
if (msg.action === 'ssr_request') {
if (msg.err) {
return next(JSON.parse(msg.err));
const err = JSON.parse(msg.err);
if (err.code === 404) {
return next();
}
return next(err);
}
return res.end(msg.html);
}
... ... @@ -94,9 +101,12 @@ const ssrRender = isDev ? (req, res, next) => {
process.on('message', event);
} : render;
const routes = [
/product\/\d+/,
'/channel',
'/channel/search'
];
module.exports = app => {
app.get(/product\/\d+/, ssrRender);
app.get('/channel', ssrRender);
_.each(routes, r => app.get(r, ssrRender));
};
... ...
... ... @@ -3,6 +3,7 @@ import App from './app.vue';
import {createRouter} from './router';
import {createStore} from './store';
import 'filters';
import 'directives';
import titleMixin from './mixins/title';
import pluginCore from './plugins/core';
import lazyload from 'vue-lazyload';
... ...
... ... @@ -11,7 +11,7 @@ const NOT_FOUND_API_MAP = {
const checkApiMap = url => {
return apiMaps[url] ? apiMaps[url] : void 0;
};
const request = ({url, method, reqParams, context}) => {
const request = async ({url, method, reqParams, context}) => {
const apiInfo = checkApiMap(url);
if (!apiInfo) {
... ... @@ -33,12 +33,12 @@ const request = ({url, method, reqParams, context}) => {
const cache = method.toLowerCase() !== 'get' ? false : apiInfo.cache;
if (apiInfo.service) {
return service.get(apiInfo.api, params, {
return await service.get(apiInfo.api, params, {
cache: cache,
code: 200
});
} else {
return api[method]('', params, {
return await api[method]('', params, {
code: 200,
cache: cache
});
... ...
... ... @@ -14,3 +14,34 @@ export const getImgUrl = function(src, width = 300, height = 300, mode = 2) {
export const replaceHttp = function(src) {
return src.replace(/https?:/, '');
};
export const debounce = (idle, action) => { // 函数去抖动,超过一定时间才会执行,如果周期内触发,充值计时器
let last;
return function() {
let args = arguments;
if (last) {
clearTimeout(last);
}
last = setTimeout(() => {
action.apply(this, args);
}, idle);
};
};
export const throttle = (delay, action) => { // 函数节流器,定义函数执行间隔,按频率触发函数
let last = 0;
return function() {
let args = arguments;
let curr = +new Date();
if (curr - last > delay) {
action.apply(this, args);
last = curr;
}
};
};
... ...
... ... @@ -10,10 +10,10 @@ export default {
name: 'ImgFormat',
props: {
src: String,
w: Number,
h: Number,
width: Number,
height: Number,
w: [Number, String],
h: [Number, String],
width: [Number, String],
height: [Number, String],
lazy: Boolean,
mode: {
type: Number,
... ...
... ... @@ -2,6 +2,7 @@ import Layout from './layout';
import Img from './img';
import Links from './links';
// 在这里export的组件会加载到公用js中,所以非必须组件,不要在这里export
export default {
Layout,
Img,
... ...
<template>
<div class="input-search">
<i class="icon icon-search-new"></i>
<input ref="inpSearch" class="inp-search" type="text" dir="auto" placeholder="Search BLK" autocomplete="off" autocorrect="off" spellcheck="false" :value="value" @input="valueInput" @keyup.enter="enter">
<button class="clear-input" type="button" @click="clear" v-show="value">
<i class="icon icon-error-tip" v-show="!loading"></i>
<i class="icon icon-loading" v-show="loading"></i>
</button>
</div>
</template>
<script>
export default {
name: 'InputSearch',
props: {
value: String,
loading: Boolean
},
data() {
return {
showClear: false
};
},
methods: {
clear() {
this.$emit('input', '');
this.$refs.inpSearch && this.$refs.inpSearch.focus();
},
enter() {
this.$emit('enter', '');
},
focus() {
setTimeout(() => {
this.$refs.inpSearch && this.$refs.inpSearch.focus(); // 延迟focus 防止影响进入动画流畅
}, 200);
},
valueInput(event) {
this.$emit('input', event.target.value);
}
}
};
</script>
<style lang="scss">
.input-search {
position: relative;
display: flex;
.icon-search-new {
vertical-align: middle;
display: inline-block;
width: 60px;
height: 100%;
position: absolute;
font-size: 28px;
color: #b0b0b0;
left: 0;
top: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
}
.inp-search {
padding: 0 60px;
height: 100%;
width: 100%;
background-color: #eeeeee;
border-radius: 8px;
color: #000000;
font-size: 28px;
}
.clear-input {
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 60px;
display: flex;
align-items: center;
justify-content: center;
border: none;
background: none;
.icon {
color: #b0b0b0;
font-size: 34px;
}
}
.icon-loading {
animation: loading 2s linear infinite;
}
}
</style>
... ...
<template>
<div class="blk-header-wrap" ref="header" v-if="showHeader" :class="[className, classList]">
<div class="blk-header">
<div class="blk-header-left">
<slot name="left">
<i class="icon icon-back go-back-btn" @click="goBack"></i>
<div class="layout-header-box">
<div class="header-left">
<slot name="left">
<i class="icon icon-back go-back-btn" @click="goBack"></i>
</slot>
</div>
<transition name="header-title">
<div class="header-title brown-light" v-show="showTitle">
<slot name="title">
{{yoho.title}}
</slot>
</div>
<div class="blk-header-main">
<span class="blk-header-title">
<slot name="title">{{yoho.title}}</slot>
</span>
</div>
<div class="blk-header-right">
<slot name="right"></slot>
</div>
</transition>
<div class="header-right">
<slot name="right"></slot>
</div>
<div class="blk-header-gap" v-if="placeholder"></div>
</div>
</template>
<script>
... ... @@ -23,175 +22,89 @@ import {mapState} from 'vuex';
export default {
name: 'HeaderBox',
props: {
className: [String, Object, Array],
placeholder: {
type: Boolean,
default: true
},
autoHide: [Boolean]
autoHide: Boolean,
className: [String, Object, Array]
},
computed: {
...mapState(['yoho'])
},
data() {
return {
showHeader: true,
classList: {ghost: this.autoHide}
showTitle: !this.autoHide
};
},
methods: {
goBack() {
this.$yoho.goBack({}, function() {}, function() {});
},
toggle() {
if (window.scrollY > 100) {
this.classList = {};
} else if (window.scrollY > 70) {
this.classList = {ghost: true, ghost3: true};
} else if (window.scrollY > 30) {
this.classList = {ghost: true, ghost2: true};
}
}
},
mounted() {
if (this.autoHide) {
window.addEventListener('touchmove', () => {
this.toggle();
});
window.addEventListener('scroll', () => {
this.toggle();
});
switchBase() {
this.showTitle = false;
},
switchNormal() {
this.showTitle = true;
}
}
};
</script>
<style lang="scss">
@import "~scss/variable.scss";
.blk-header-wrap.hide {
.blk-header {
display: none;
}
}
.blk-header-wrap.ghost {
.blk-header {
background-color: rgba(255, 255, 255, 0);
transition: 0.3s all;
border-bottom: 0;
}
@import "~scss/variable.scss";
.layout-header-box {
position: relative;
height: $header-height;
font-size: $header-font-size;
padding: 0px 20px;
width: 100%;
.icon {
vertical-align: middle;
display: inline-block;
width: 80px;
height: 100%;
line-height: $header-height;
font-size: $header-font-size;
.blk-header-title {
opacity: 0;
&.icon-back {
font-size: 64px;
}
}
.blk-header-wrap.ghost-2 {
.blk-header {
background-color: rgba(255, 255, 255, 0.4);
transition: 0.3s all;
border-bottom: 0;
}
.blk-header-title {
opacity: 0.4;
}
.header-left, .header-right {
z-index: 2;
position: absolute;
min-width: 80px;
}
.blk-header-wrap.ghost-3 {
.blk-header {
background-color: rgba(255, 255, 255, 0.7);
transition: 0.3s all;
border-bottom: 0;
}
.blk-header-title {
opacity: 0.7;
}
.header-left {
left: 20px;
top: 0;
}
.blk-header {
box-sizing: content-box;
position: fixed;
display: flex;
.header-right {
text-align: right;
right: 20px;
top: 0;
right: 0;
}
.header-title {
position: absolute;
z-index: 1;
background-color: #fff;
left: 0;
z-index: 210;
height: $header-height;
max-width: 750px;
margin-left: auto;
margin-right: auto;
top: 0;
right: 0;
bottom: 0;
text-align: center;
line-height: $header-height;
font-size: $header-font-size;
font-weight: bold;
background-color: #fff;
border-bottom: 1px solid #eee;
color: #000;
.icon,
.blk-header-title {
vertical-align: middle;
}
.blk-header-left {
width: 100px;
text-align: center;
font-size: 40px;
.icon {
font-size: 40px;
}
}
.blk-header-right {
width: 100px;
text-align: center;
font-size: 40px;
.icon {
font-size: 40px;
}
.right-btn {
font-size: 17PX;
margin-right: 30px;
}
}
.blk-header-main {
flex: 1;
text-align: center;
font-size: $header-font-size;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.icon {
display: inline-block;
&.icon-search {
margin-top: -10px;
}
}
.go-back-btn {
&:active {
background: #ccc;
opacity: 0.5;
}
}
}
.blk-header-gap {
height: $header-height + 2;
background-color: transparent;
}
.blk-header-wrap {
&.ghost {
.blk-header-title {
visibility: hidden;
}
}
font-size: 17PX;
color: #000000;
letter-spacing: -0.41px;
border-bottom: solid 1px #eee;
}
}
.header-title-enter-active, .header-title-leave-active {
transition: opacity 0.2s ease-in-out;
}
.header-title-enter, .header-title-leave-to {
opacity: 0;
}
.header-title-enter-to, .header-title-leave {
opacity: 1;
}
</style>
... ...
<template>
<div class="page">
<slot name="header"></slot>
<div class="page-content">
<div class="layout">
<div class="layout-header" v-if="!hideHeader">
<slot name="header" ref="header"></slot>
</div>
<div class="layout-content" ref="content" :class="{'top-header': !autoHideHeader && !hideHeader}">
<slot></slot>
</div>
</div>
... ... @@ -9,18 +11,70 @@
<script>
import {mapState} from 'vuex';
export default {
name: 'LayoutBody',
props: {
hideHeader: Boolean,
autoHideHeader: Boolean
data() {
return {
autoHideHeader: false,
hideHeader: false,
};
},
computed: {
...mapState(['yoho'])
},
mounted() {
if (this.autoHideHeader) {
window.addEventListener('touchmove', this.toggle);
this.$refs.content.addEventListener('scroll', this.toggle);
}
},
methods: {
toggle() {
if (this.$refs.content.scrollTop < 70) {
this.$slots.header[0].componentInstance.switchBase();
} else {
this.$slots.header[0].componentInstance.switchNormal();
}
}
},
created() {
if (this.$slots.header && this.$slots.header.length) {
this.autoHideHeader = this.$slots.header[0].componentOptions.propsData.autoHide;
} else {
this.hideHeader = true;
}
}
};
</script>
<style>
<style lang="scss">
@import "~scss/variable.scss";
.layout {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
.layout-header {
position: relative;
z-index: 2;
}
.layout-content {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
overflow-y: auto;
z-index: 1;
-webkit-overflow-scrolling: touch;
&.top-header {
top: $header-height;
}
}
}
</style>
... ...
... ... @@ -10,7 +10,8 @@
export default {
name: 'ALink',
props: {
href: [String]
href: [String],
to: String
},
methods: {
click() {
... ... @@ -31,6 +32,9 @@
this.dispatch(url);
return false;
}
if (this.to) {
this.$router.push(this.to);
}
},
dispatch(url) {
const origin = location.origin;
... ...
import ResourceTwoImage from './resource-two-image';
import ResourceSingleImage from './resource-single-image';
import ResourceProductList from './resource-product-list';
import ResourceShopFloor from './resource-shop-floor';
export default {
export {
ResourceTwoImage,
ResourceSingleImage,
ResourceProductList,
ResourceShopFloor,
};
... ...
<template>
<resource>
<!-- <resource-single-image></resource-single-image>
<resource-product-list></resource-product-list> -->
</resource>
</template>
<script>
import Resource from './resource';
import ResourceSingleImage from './resource-single-image';
import ResourcePoductList from './resource-product-list';
export default {
name: 'ResourceShopFloor',
props: {
value: Object
},
components: {Resource, ResourceSingleImage, ResourcePoductList}
};
</script>
<style lang="scss">
.resource-products {
width: 100%;
overflow-x: scroll;
-webkit-overflow-scrolling: touch;
white-space: nowrap;
li.product-item {
display: inline-block;
padding-right: 20px;
text-align: center;
line-height: 40px;
img {
width: 188px;
height: 250px;
}
}
}
</style>
... ...
<template>
<resource class="resource-single-image">
<img-format :src="value.src" :w="250" :h="250"></img-format>
<a-link
:title="value.title"
:href="img.url"
v-for="(img, index) in value.list"
:key="index">
<img-format
:src="img.src"
:w="value.imageWidth"
:h="value.imageHeight"
:alt="img.alt">
</img-format>
</a-link>
</resource>
</template>
... ...
<template>
<resource class="resource-ti-image">
<div class="resource-ti-image-item">
<img-format :src="value[0].src" :w="250" :h="250"></img-format>
<a-link :href="value.list[0].url">
<img-format :src="value.list[0].src" :w="value.imageWidth" :h="value.imageHeight"></img-format>
</a-link>
</div>
<div class="split"></div>
<div class="resource-ti-image-item">
<img-format :src="value[1].src" :w="250" :h="250"></img-format>
<a-link :href="value.list[1].url">
<img-format :src="value.list[1].src" :w="value.imageWidth" :h="value.imageHeight"></img-format>
</a-link>
</div>
</resource>
</template>
... ... @@ -16,7 +20,7 @@ import Resource from './resource';
export default {
name: 'ResourceTwoImage',
props: {
value: Array
value: Object
},
components: {Resource}
};
... ...
import SearchSlider from './search-slider';
import SearchBar from './search-bar';
export {
SearchSlider,
SearchBar
};
... ...
<template>
<div class="search-slider">
<div class="search-block">
<input-search ref="search" class="search" v-model="searchValue" :loading="product.isSearching" @enter="enter"></input-search>
<button class="btn btn-trans btn-cancel" @click="cancel">取消</button>
</div>
<div class="search-content" v-show="extend">
<div class="search-list" v-if="!searchEmpty">
<ul>
<a-link
v-for="item in searchList"
:key="item.keyword"
:to="`/channel/search?query=${item.keyword}`">
<li>
{{item.keyword}}
<i class="icon icon-right"></i>
</li>
</a-link>
</ul>
</div>
<div class="search-tip" v-else>
<p class="chg">
未找到相关商品
</p>
<p class="eng">
Unfortunately there are no results
matching your request.
</p>
</div>
</div>
</div>
</template>
<script>
import InputSearch from '../input/input-search';
import {
FETCH_SEARCH_REQUEST
} from 'store/product/types';
import {mapState} from 'vuex';
import {debounce} from 'common/utils';
export default {
name: 'SearchBar',
props: {
full: Boolean,
keyword: String
},
data() {
return {
searchValue: this.keyword,
searchList: [],
searchEmpty: false
};
},
computed: {
...mapState(['product']),
extend() {
if (this.full) {
return true;
}
return this.searchEmpty || this.searchList.length;
}
},
created() {
this.searchDebounce = debounce(300, this.search);
},
methods: {
cancel() {
this.$emit('cancel');
},
enter() {
this.$router.push(`/channel/search?query=${this.searchValue}`);
},
focus() {
this.$refs.search.focus();
},
async search(val) {
const result = await this.$store.dispatch(FETCH_SEARCH_REQUEST, {keyword: val});
if (result && this.searchValue) {
if (result.data.length) {
this.searchEmpty = false;
this.searchList = result.data;
} else {
this.searchEmpty = true;
}
}
}
},
watch: {
searchValue(val) {
if (val) {
this.searchDebounce(val);
} else {
this.searchEmpty = false;
this.searchList = [];
}
}
},
components: {InputSearch}
};
</script>
<style lang="scss">
.search-slider {
.search-block {
position: relative;
width: 100%;
height: 90px;
padding: 14px 20px;
background-color: #fff;
display: flex;
border-bottom: solid 1px #eee;
z-index: 999;
.search {
flex: 1;
}
.btn-cancel {
width: 125px;
padding-right: 0px;
}
}
.search-content {
position: absolute;
top: 90px;
left: 0;
right: 0;
bottom: 0;
z-index: 998;
background: rgba(255, 255, 255, 0.9);
.search-tip {
width: 358px;
height: 380px;
margin: 380px auto;
padding-top: 225px;
background: url('~statics/img/search-tip.png') no-repeat;
background-repeat: no-repeat;
background-position: top center;
background-size: 205px 201px;
color: #b0b0b0;
text-align: center;
.chg {
font-size: 34px;
}
.eng {
font-size: 12PX;
}
}
.search-list {
li {
width: 100%;
line-height: 80px;
padding: 0 30px;
font-size: 30px;
border-bottom: solid 1px #eee;
background-color: #fff;
i {
float: right;
display: flex;
align-items: center;
justify-content: center;
height: 80px;
}
}
}
}
}
</style>
... ...
<template>
<transition name="search-slider" @after-enter="afterEnter">
<search-bar ref="searchBar" v-if="value" :full="true" @cancel="cancel"></search-bar>
</transition>
</template>
<script>
import SearchBar from './search-bar';
export default {
name: 'SearchSlider',
props: {
value: Boolean
},
methods: {
cancel() {
this.$emit('input', false);
},
afterEnter() {
this.$refs.searchBar.focus();
}
},
components: {SearchBar}
};
</script>
<style>
.search-slider-enter-active, .search-slider-leave-active {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
z-index: 999;
will-change: transform;
transition-duration: 280ms;
}
.search-slider-enter-active {
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.search-slider-leave-active {
transition-timing-function: cubic-bezier(0.4, 0, 0.6, 1);
}
.search-slider-enter, .search-slider-leave-to {
transform: translateX(750px);
}
.search-slider-enter-to, .search-slider-leave {
transform: translateX(0px);
}
</style>
... ...
export default {
inserted(el) {
el.focus();
}
};
... ...
import Vue from 'vue';
import focus from './focus';
Vue.directive('focus', focus);
... ...
... ... @@ -4,6 +4,7 @@ import {createApp} from './app';
import yoho from '../public/js/yoho';
import message from '../src/components/message';
import 'statics/scss/common.scss';
import 'statics/scss/animation.scss';
import 'statics/font/iconfont.css';
import 'statics/scss/font.scss';
... ...
<template>
<div class="home-slider-content">
<transition name="home-slider">
<div class="home-slider" v-if="value">
<div class="block" v-for="slider in sliders" :key="slider.title">
<div class="item title" @click="selectSlider(slider)">
<span>{{slider.title}}</span>
<i class="icon" :class="{'icon-up': slider.actived, 'icon-down': !slider.actived}"></i>
</div>
<div class="childs" v-show="slider.actived">
<div class="item" v-for="item in slider.childs" :key="item.title">{{item.title}}</div>
</div>
</div>
</div>
</transition>
<div class="mask" @click="close" v-show="value"></div>
</div>
</template>
<script>
import _ from 'lodash/core';
export default {
name: 'HomeSlider',
props: {
value: Boolean
},
data() {
return {
sliders: [{
title: 'MEN',
actived: false,
childs: [{
title: 'Brands'
}, {
title: 'Dresss'
}, {
title: 'Bottoms'
}, {
title: 'Shoes'
}]
}, {
title: 'WOMEN',
actived: false,
childs: [{
title: 'Brands'
}, {
title: 'Dresss'
}, {
title: 'Bottoms'
}, {
title: 'Shoes'
}]
}, {
title: 'SALE',
actived: false,
childs: [{
title: 'Brands'
}, {
title: 'Dresss'
}, {
title: 'Bottoms'
}, {
title: 'Shoes'
}]
}]
};
},
methods: {
close() {
this.$emit('input', false);
},
selectSlider(slider) {
if (slider.childs && slider.childs.length) {
slider.actived = !slider.actived;
_.each(this.sliders, s => {
if (slider !== s) {
s.actived = false;
}
});
}
}
}
};
</script>
<style lang="scss">
.home-slider {
position: absolute;
left: 0;
top: 0;
bottom: 0;
z-index: 999;
width: 500px;
background-color: #fff;
overflow-y: auto;
letter-spacing: -0.76px;
color: #000000;
.block {
.title {
font-size: 32px !important;
font-weight: bold;
height: 100px;
line-height: 100px !important;
.icon {
float: right;
height: 100%;
line-height: 100px;
font-weight: bold;
font-size: 26px;
}
}
.item {
font-size: 28px;
padding-left: 20px;
padding-right: 20px;
border-bottom: solid 1px #EEEEEE;
line-height: 86px;
}
}
}
.home-slider-enter-active, .home-slider-leave-active {
will-change: transform;
transition-duration: 280ms;
}
.home-slider-enter-active {
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.home-slider-leave-active {
transition-timing-function: cubic-bezier(0.4, 0, 0.6, 1);
}
.home-slider-enter, .home-slider-leave-to {
transform: translateX(-500px);
}
.home-slider-enter-to, .home-slider-leave {
transform: translateX(0px);
}
.home-slider-content {
.mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 998;
background: rgba(0, 0, 0, 0.4);
}
}
</style>
... ...
import HomeSlider from './home-slider';
export {
HomeSlider
};
... ...
<template>
<layout-body class="page-detail">
<header-box slot="header">
<span slot="left">
<i class="icon icon-nav"></i>
</span>
<span slot="title">
<div>
<home-slider v-model="homeSlider"></home-slider>
<search-slider v-model="searchSlider"></search-slider>
<layout-body>
<header-box slot="header" class="home-header">
<span slot="left">
<i class="icon icon-nav-new" @click="homeSliderSwitch"></i>
</span>
<span slot="title" class="logo">
</span>
<span slot="right">
<i class="icon icon-search"></i>
</span>
</header-box>
<div class="resources">
<resource-two-image v-if="twoImages" :value="twoImages"></resource-two-image>
<resource-single-image v-if="singleImages" :value="singleImages"></resource-single-image>
<resource-product-list v-if="products" :value="products"></resource-product-list>
<resource-single-image v-if="singleImages" :value="singleImages"></resource-single-image>
</div>
</layout-body>
</span>
<span slot="right">
<i class="icon icon-search-new" @click="searchSliderSwitch"></i>
</span>
</header-box>
<div class="resources">
<component
:is="component.template_name"
v-for="(component, index) in channel.home.filter(c => ['twoPicture', 'newSingleImage', 'shopFloor'].some(k => k === c.template_name) )"
:value="component.data"
:key="index"></component>
</div>
</layout-body>
</div>
</template>
<script>
import {
FETCH_HOME_REQUEST
} from 'store/channel/types';
import components from 'components/resources';
import {
ResourceTwoImage,
ResourceSingleImage,
ResourceShopFloor
} from 'components/resources';
import {SearchSlider} from 'components/search';
import {mapState} from 'vuex';
import {HomeSlider} from './components';
export default {
name: 'Channel',
data() {
return {
twoImages: [{
src: '//img10.static.yhbimg.com/yhb-img01/2017/07/05/09/01dfd379daa71513f228fe7586aca829e4.jpg?imageView2/2/w/375/h/375/interlace/1'
}, {
src: '//img10.static.yhbimg.com/yhb-img01/2017/07/05/09/01dfd379daa71513f228fe7586aca829e4.jpg?imageView2/2/w/375/h/375/interlace/1'
}],
singleImages: {
src: '//img11.static.yhbimg.com/yhb-img01/2017/07/26/09/01496efd7e853c2aaa1e38035d788eaa8e.jpg?imageView2/2/w/750/h/364/interlace/1'
},
products: [{
src: '//img11.static.yhbimg.com/goodsimg/2017/05/04/12/019698fcd41f21403a12e603ae64dc23f0.jpg?imageMogr2/thumbnail/330x440/background/d2hpdGU=/position/center/quality/80/interlace/1',
title: 'HBA',
price: '¥1399'
}, {
src: '//img12.static.yhbimg.com/goodsimg/2017/05/21/13/0221fbe4559a7033058b84c898fa59d18a.jpg?imageMogr2/thumbnail/330x440/background/d2hpdGU=/position/center/quality/80/interlace/1',
title: 'HBA',
price: '¥1399'
}, {
src: '//img12.static.yhbimg.com/goodsimg/2017/05/21/13/0221fbe4559a7033058b84c898fa59d18a.jpg?imageMogr2/thumbnail/330x440/background/d2hpdGU=/position/center/quality/80/interlace/1',
title: 'HBA',
price: '¥1399'
}, {
src: '//img12.static.yhbimg.com/goodsimg/2017/05/21/13/0221fbe4559a7033058b84c898fa59d18a.jpg?imageMogr2/thumbnail/330x440/background/d2hpdGU=/position/center/quality/80/interlace/1',
title: 'HBA',
price: '¥1399'
}, {
src: '//img12.static.yhbimg.com/goodsimg/2017/05/21/13/0221fbe4559a7033058b84c898fa59d18a.jpg?imageMogr2/thumbnail/330x440/background/d2hpdGU=/position/center/quality/80/interlace/1',
title: 'HBA',
price: '¥1399'
}, {
src: '//img12.static.yhbimg.com/goodsimg/2017/05/21/13/0221fbe4559a7033058b84c898fa59d18a.jpg?imageMogr2/thumbnail/330x440/background/d2hpdGU=/position/center/quality/80/interlace/1',
title: 'HBA',
price: '¥1399'
}, {
src: '//img12.static.yhbimg.com/goodsimg/2017/05/21/13/0221fbe4559a7033058b84c898fa59d18a.jpg?imageMogr2/thumbnail/330x440/background/d2hpdGU=/position/center/quality/80/interlace/1',
title: 'HBA',
price: '¥1399'
}, {
src: '//img12.static.yhbimg.com/goodsimg/2017/05/21/13/0221fbe4559a7033058b84c898fa59d18a.jpg?imageMogr2/thumbnail/330x440/background/d2hpdGU=/position/center/quality/80/interlace/1',
title: 'HBA',
price: '¥1399'
}, {
src: '//img12.static.yhbimg.com/goodsimg/2017/05/21/13/0221fbe4559a7033058b84c898fa59d18a.jpg?imageMogr2/thumbnail/330x440/background/d2hpdGU=/position/center/quality/80/interlace/1',
title: 'HBA',
price: '¥1399'
}, {
src: '//img12.static.yhbimg.com/goodsimg/2017/05/21/13/0221fbe4559a7033058b84c898fa59d18a.jpg?imageMogr2/thumbnail/330x440/background/d2hpdGU=/position/center/quality/80/interlace/1',
title: 'HBA',
price: '¥1399'
}]
homeSlider: false,
searchSlider: false
};
},
asyncData({store}) {
return store.dispatch(FETCH_HOME_REQUEST);
},
components: {...components}
computed: {
...mapState(['channel'])
},
methods: {
homeSliderSwitch() {
this.homeSlider = !this.homeSlider;
},
searchSliderSwitch() {
this.searchSlider = !this.searchSlider;
},
},
components: {
twoPicture: ResourceTwoImage,
newSingleImage: ResourceSingleImage,
shopFloor: ResourceShopFloor,
SearchSlider,
HomeSlider
}
};
</script>
<style lang="scss">
.resources {
padding-bottom: 20px;
}
.home-header {
.icon-nav-new {
font-size: 34px !important;
}
.icon-search-new {
font-size: 42px !important;
}
.logo {
background-image: url('~statics/img/logo.png');
display: block;
width: 100%;
height: 100%;
background-position: center center;
background-repeat: no-repeat;
background-size: 152px 27px;
}
}
</style>
... ...
<template>
<layout-body :auto-hide-header="true" class="page-detail">
<header-box slot="header" :auto-hide="true" :placeholder="false"></header-box>
<header-box slot="header" :auto-hide="true"></header-box>
<product-swipe :goods="detail.goods_list" ref="imageSwiper"></product-swipe>
<div class="detail-box border-bottom">
<shop-fav :entity="detail" class="border-bottom"></shop-fav>
... ...
export default {
path: '/:pid',
path: '/:pid(\\d+)',
name: 'detail',
component: () => import(/* webpackChunkName: "detail" */ './detail')
};
... ...
import detail from './detail';
import search from './search';
export default {
detail
detail,
search
};
... ...
export default {
path: '/search',
name: 'search',
alias: '/channel/search',
component: () => import(/* webpackChunkName: "search" */ './search')
};
... ...
<template>
<layout-body class="product-search">
<search-bar class="product-search-bar" @cancel="cancel" :keyword="keyword"></search-bar>
<iframe class="ifr-product" src="" frameborder="0"></iframe>
</layout-body>
</template>
<script>
import SearchBar from 'components/search/search-bar';
export default {
name: 'Search',
data() {
return {
keyword: ''
};
},
created() {
this.keyword = this.$route.query.query;
},
methods: {
cancel() {
this.$router.go(-1);
}
},
components: {SearchBar}
};
</script>
<style lang="scss">
.product-search {
display: flex;
flex-direction: column;
}
.product-search-bar {
height: 90px;
}
.ifr-product {
position: absolute;
top: 90px;
left: 0;
right: 0;
bottom: 0;
}
</style>
... ...
@font-face {font-family: "icon";
src: url('iconfont.eot?t=1513926885177'); /* IE9*/
src: url('iconfont.eot?t=1513926885177#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),
url('iconfont.ttf?t=1513926885177') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('iconfont.svg?t=1513926885177#icon') format('svg'); /* iOS 4.1- */
src: url('iconfont.eot?t=1514271932966'); /* IE9*/
src: url('iconfont.eot?t=1514271932966#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),
url('iconfont.ttf?t=1514271932966') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('iconfont.svg?t=1514271932966#icon') format('svg'); /* iOS 4.1- */
}
.icon {
... ... @@ -15,6 +15,8 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-loading:before { content: "\e62d"; }
.icon-add:before { content: "\e762"; }
.icon-back:before { content: "\e763"; }
... ... @@ -199,3 +201,7 @@
.icon-zazhi:before { content: "\e7bd"; }
.icon-search-new:before { content: "\e7be"; }
.icon-nav-new:before { content: "\e7bf"; }
... ...
... ... @@ -27,6 +27,9 @@ t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-
<glyph glyph-name="loading" unicode="&#58925;" d="M709.13627 561.68138 815.140124 707.458617C828.730652 726.15552 824.598044 752.333284 805.901938 765.924352 787.205831 779.515449 761.039644 775.372203 747.449145 756.685767L641.445262 610.90853C627.854763 592.211627 631.987371 566.044331 650.683477 552.453234 658.111687 547.044011 666.722162 544.438784 675.259392 544.438784 688.190777 544.438784 700.944299 550.423467 709.13627 561.68138M780.56229 419.482396 952.060075 475.165042C974.041316 482.311083 986.072946 505.915022 978.937685 527.897202 971.791929 549.889877 948.209948 561.880178 926.207744 554.775979L754.720427 499.093305C732.739186 491.947264 720.697088 468.343353 727.842816 446.361145 733.586631 428.668672 749.991481 417.421227 767.630905 417.421227 771.920441 417.421227 776.272754 418.090837 780.56229 419.482396M978.937685 233.706126C986.072946 255.688334 974.041316 279.292245 952.060075 286.438286L780.56229 342.12096C758.591488 349.267001 734.978105 337.224391 727.842816 315.242183 720.697088 293.260004 732.739186 269.645596 754.720427 262.510023L926.207744 206.81691C930.507748 205.425351 934.86006 204.766208 939.149596 204.766208 956.78902 204.766208 973.19387 216.013653 978.937685 233.706126M805.901938-4.321024C824.598044 9.280512 828.730652 35.447808 815.140124 54.144711L709.13627 199.911509C695.55621 218.597945 669.390023 222.741191 650.683477 209.150094 631.987371 195.54853 627.854763 169.381234 641.445262 150.684331L747.449145 4.917561C755.641116-6.350791 768.394638-12.325006 781.326023-12.325006 789.863253-12.325006 798.4737-9.719808 805.901938-4.321024M567.738482-53.401714 567.738482 126.78747C567.738482 149.899634 549.000505 168.638379 525.889337 168.638379 502.77814 168.638379 484.040192 149.899634 484.040192 126.78747L484.040192-53.401714C484.040192-76.513877 502.77814-95.252622 525.889337-95.252622 549.000505-95.252622 567.738482-76.513877 567.738482-53.401714M304.3295 4.917561 410.322916 150.684331C423.923883 169.381234 419.791303 195.54853 401.095196 209.150094 382.39909 222.741191 356.232903 218.597945 342.642404 199.911509L236.638521 54.144711C223.048021 35.447808 227.180629 9.280512 245.866268-4.321024 253.304946-9.719808 261.915392-12.325006 270.452622-12.325006 283.384007-12.325006 296.137529-6.350791 304.3295 4.917561M125.560434 206.81691 297.058219 262.510023C319.039488 269.645596 331.071118 293.260004 323.935829 315.242183 316.80054 337.224391 293.208092 349.214692 271.205916 342.12096L99.718599 286.438286C77.73733 279.292245 65.695232 255.688334 72.830521 233.706126 78.584775 216.013653 94.989653 204.766208 112.629049 204.766208 116.918585 204.766208 121.270898 205.435819 125.560434 206.81691M323.935829 446.361145C331.071118 468.343353 319.039488 491.947264 297.058219 499.093305L125.560434 554.775979C103.579164 561.92202 79.976249 549.889877 72.830521 527.897202 65.695232 505.915022 77.73733 482.311083 99.718599 475.165042L271.205916 419.482396C275.50592 418.08037 279.858233 417.421227 284.147769 417.421227 301.787164 417.421227 318.192043 428.67914 323.935829 446.361145M401.095196 552.453234C419.791303 566.044331 423.923883 592.211627 410.322916 610.90853L304.3295 756.685767C290.739001 775.38267 264.562375 779.525916 245.866268 765.924352 227.180629 752.333284 223.048021 726.15552 236.638521 707.458617L342.642404 561.68138C350.823908 550.412999 363.577429 544.438784 376.519282 544.438784 385.046044 544.438784 393.666958 547.044011 401.095196 552.453234M525.889337 592.954482C502.77814 592.954482 484.040192 611.693227 484.040192 634.805419L484.040192 815.005042C484.040192 838.117205 502.77814 856.85595 525.889337 856.85595 549.000505 856.85595 567.738482 838.117205 567.738482 815.005042L567.738482 634.805419C567.738482 611.693227 549.000505 592.954482 525.889337 592.954482" horiz-adv-x="1024" />
<glyph glyph-name="add" unicode="&#59234;" d="M1024 486.4H614.4V896h-204.8v-409.6H0v-204.8h409.6V-128h204.8V281.6H1024z" horiz-adv-x="1024" />
... ... @@ -303,6 +306,12 @@ t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-
<glyph glyph-name="zazhi" unicode="&#59325;" d="M511.838771-96.807586a25.01612 25.01612 0 0 0-24.376322 24.376322V678.276263c0 12.987909 11.388413 24.376321 24.376322 24.376321s24.376321-11.388413 24.376321-24.376321v-752.307023c0-12.987909-11.388413-22.744835-24.376321-22.744836z m0.06398-30.998235a61.388663 61.388663 0 0 0-61.900502 61.900501 88.452138 88.452138 0 0 1-88.228208 88.228208H136.756922a136.820901 136.820901 0 0 0-136.788912 136.788912V758.922859A136.884881 136.884881 0 0 0 136.756922 896.03167h225.017119c57.134003 0 110.429215-22.840805 150.09672-63.468008a208.542309 208.542309 0 0 0 150.096719 63.468008h225.01712a136.820901 136.820901 0 0 0 136.788911-136.788911v-599.81106a136.820901 136.820901 0 0 0-136.788911-136.788911h-225.01712a88.452138 88.452138 0 0 1-88.228208-88.228209A61.420652 61.420652 0 0 0 511.838771-127.773831zM136.788911 847.119077a88.452138 88.452138 0 0 1-88.228208-88.228208v-599.811059a88.452138 88.452138 0 0 1 88.228208-88.228208h225.01712a136.820901 136.820901 0 0 0 136.788912-136.788912c0-7.613602 5.726196-13.019899 13.019898-13.019898a12.7 12.7 0 0 1 13.019899 13.019898 136.820901 136.820901 0 0 0 136.788912 136.788912h225.017119a88.452138 88.452138 0 0 1 88.228208 88.228208V758.890869a88.452138 88.452138 0 0 1-88.228208 88.228208h-225.017119c-51.407807 0-99.008812-24.440301-130.422917-66.635009-9.213098-12.3801-29.846598-12.3801-39.027707 0-31.414105 42.194709-79.01511 66.63501-130.422916 66.635009H136.852891z" horiz-adv-x="1024" />
<glyph glyph-name="search-new" unicode="&#59326;" d="M121.904762 457.142857c0 187.733333 153.6 341.333333 341.333333 341.333333s341.333333-153.6 341.333334-341.333333-153.6-341.333333-341.333334-341.333333-341.333333 153.6-341.333333 341.333333z m877.714286-536.380952l-221.866667 229.180952C855.771429 227.961905 902.095238 337.67619 902.095238 457.142857c0 241.371429-197.485714 438.857143-438.857143 438.857143S24.380952 698.514286 24.380952 457.142857s197.485714-438.857143 438.857143-438.857143c87.771429 0 170.666667 26.819048 238.933334 70.704762L950.857143-128l48.761905 48.761905z" horiz-adv-x="1024" />
<glyph glyph-name="nav-new" unicode="&#59327;" d="M301.176471 775.529412h963.764705V896H301.176471v-120.470588zM180.705882 896L0 832.752941V745.4117650000001L180.705882 775.529412V896z m120.470589-572.235294h963.764705v120.470588H301.176471v-120.470588zM3.011765 380.98823500000003L0 293.647059l180.705882 30.117647v120.470588L3.011765 380.98823500000003zM301.176471-97.88235299999997h963.764705v120.470588H301.176471v-120.470588z m-298.164706 57.223529L0-128l180.705882 30.117647v120.470588L3.011765-40.65882399999998z" horiz-adv-x="1264" />
</font>
... ...
@keyframes loading {
from {
transform: rotateX(0deg);
}
to {
transform: rotate(360deg);
}
}
... ...
... ... @@ -522,6 +522,12 @@ body {
font-size: 0.6rem;
font-family: "PingFang SC", Helvetica, Roboto, "Heiti SC", "黑体", Arial;
line-height: 1.4;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
body {
... ... @@ -658,3 +664,15 @@ img[lazy=loaded] {
text-transform: none;
line-height: 1;
}
.btn {
padding-left: 20px;
padding-right: 20px;
border: none;
&.btn-trans {
background-color: transparent;
color: #4a90e2;
font-size: 30px;
}
}
... ...
$header-height: 88px;
$header-font-size: 17PX;
$header-height: 90px;
$header-font-size: 32px;
... ...
... ... @@ -6,7 +6,6 @@ import {
import {
HOME_CONTENT_CODE
} from '../content-code';
import _ from 'lodash';
export default {
state: {
... ... @@ -32,7 +31,7 @@ export default {
// }
commit(FETCH_HOME_REQUEST);
try {
const result = await this.$api.get('/resource/get', {content_code: HOME_CONTENT_CODE});
const result = await this.$api.get('/api/resource/get', {content_code: HOME_CONTENT_CODE});
commit(FETCH_HOME_SUCCESS, result);
return result;
... ...
import Vue from 'vue';
import _ from 'lodash';
import _ from 'lodash/core';
import {
FETCH_PRODUCT_DETAIL,
PRODUCT_FAVORITE,
FETCH_CART_COUNT,
PRODUCT_ADD_CART,
FETCH_PRODUCT_INTRO
FETCH_PRODUCT_INTRO,
FETCH_SEARCH_REQUEST,
FETCH_SEARCH_SUCCESS,
FETCH_SEARCH_FAILURE
} from './types';
import api from 'common/api';
... ... @@ -14,7 +17,9 @@ export default {
list: [],
items: {},
isFetching: false,
cartCount: 0
cartCount: 0,
isSearching: false,
searchError: false
},
mutations: {
[FETCH_PRODUCT_DETAIL](state, {product, product: { product_id }}) {
... ... @@ -28,6 +33,18 @@ export default {
},
[FETCH_CART_COUNT](state, {cart_goods_count}) {
state.cartCount = cart_goods_count;
},
[FETCH_SEARCH_REQUEST](state) {
state.searchError = false;
state.isSearching = true;
},
[FETCH_SEARCH_SUCCESS](state) {
state.searchError = false;
state.isSearching = false;
},
[FETCH_SEARCH_FAILURE](state) {
state.searchError = true;
state.isSearching = false;
}
},
actions: {
... ... @@ -38,7 +55,7 @@ export default {
// return Promise.resolve();
// }
return this.$api.get('/api/product/data', {
product_id: _.parseInt(product_id)
product_id: parseInt(product_id, 10)
}).then(res => {
if (res.code === 200) {
return Promise.all([
... ... @@ -101,6 +118,20 @@ export default {
res.__lasttime = Date.now();
commit(FETCH_PRODUCT_INTRO, {intro: res, product_id: pid});
});
},
async [FETCH_SEARCH_REQUEST]({commit}, {keyword}) {
commit(FETCH_SEARCH_REQUEST);
try {
const result = await this.$api.get('/api/search/fuzzy', {keyword});
if (result.code === 200) {
commit(FETCH_SEARCH_SUCCESS);
return result;
}
commit(FETCH_SEARCH_FAILURE);
} catch (e) {
commit(FETCH_SEARCH_FAILURE);
}
}
}
};
... ...
... ... @@ -9,3 +9,7 @@ export const FETCH_CART_COUNT = 'FETCH_CART_COUNT';
export const PRODUCT_FAVORITE = 'PRODUCT_FAVORITE';
export const PRODUCT_ADD_CART = 'PRODUCT_ADD_CART';
export const FETCH_SEARCH_REQUEST = 'FETCH_SEARCH_REQUEST';
export const FETCH_SEARCH_SUCCESS = 'FETCH_SEARCH_SUCCESS';
export const FETCH_SEARCH_FAILURE = 'FETCH_SEARCH_FAILURE';
... ...