Authored by bevishuang

merge

<template>
<div class="layout">
<div ref="layout" class="layout">
<slot name="header">
<LayoutHeader v-if="!hideHeader"
class="layout-header"
:title="title"
:opacity="opacity"
:show-back="showBack"
:back-action="backAction"
<LayoutHeader
v-if="!hideHeader"
class="layout-header"
:title="title"
:opacity="opacity"
:show-back="showBack"
:back-action="backAction"
></LayoutHeader>
</slot>
... ... @@ -18,7 +19,7 @@
<script>
export default {
name: 'LayoutApp',
name: "LayoutApp",
props: {
title: String,
opacity: {
... ... @@ -41,6 +42,38 @@ export default {
type: Function,
default: null
}
},
data() {
return {
isTouchStart: false,
isStop: false,
touchStartY: 0,
touchMoveY: 0
};
},
methods: {
webviewScrollStart(e) {
this.isTouchStart = true;
this.touchStartY = e.changedTouches[0].pageY;
},
webviewScrollMove(e) {
if (this.isTouchStart && !this.isStop) {
let scrollTop = this.$refs.layout.scrollTop;
this.touchMoveY = e.changedTouches[0].pageY;
if (scrollTop <= 0 && this.touchMoveY > this.touchStartY) {
e.preventDefault();
}
}
},
webviewScrollEnd() {
this.isTouchStart = false;
},
stopPrevent() {
this.isStop = true;
},
startPrevent() {
this.isStop = false;
}
}
};
</script>
... ...
... ... @@ -42,7 +42,14 @@ export default {
setTimeout(() => {
if (this.title) {
setTitle(this.title);
this.$xianyu.setXianyuTitle({ title: this.title });
if (this.isAliApp && !window.WindVane) {
setTimeout(() => {
this.$xianyu.setXianyuTitle({ title: this.title });
}, 300);
} else {
this.$xianyu.setXianyuTitle({ title: this.title });
}
}
}, 100);
... ...
... ... @@ -165,6 +165,7 @@ export default {
.coupon-name {
font-size: 24px;
font-weight: bold;
color: #002b47;
margin-bottom: 10px;
}
... ...
... ... @@ -4,20 +4,19 @@
<div class="left-content">
<Scroll>
<div class="category-left-item-root"
v-for="(item, index) in categoryParent"
:key="index"
:data-id="item"
@click="onClick(item)">
<div :class="{'category-left-item-select-flag' : item.isSelect }"></div>
<p
class="category-left-item-title"
:class="{'category-left-item-select' : item.isSelect }">
{{item.name}}
</p>
v-for="(item, index) in categoryParent"
:key="index"
:class="{'category-left-item-select-flag' : item.isSelect }"
:data-id="item"
@click="onClick(item)">
<p
class="category-left-item-title"
:class="{'category-left-item-select' : item.isSelect }">
{{item.name}}
</p>
</div>
</Scroll>
</div>
<div class="left-right-split-line"></div>
<div class="right-content">
<Scroll>
<div v-for="(itemSub, index) in categorySubList" :key="index">
... ... @@ -27,8 +26,7 @@
v-for="(item, index) in itemSub.sub"
:key="index"
:data-id="item.id"
:class="item.className"
>
:class="item.className">
<LayoutLink :href="item.url">
<div :class="item.type ? 'item-imge-div-brand' : 'item-imge-div'" @click="goProductList(item,index, itemSub)">
<ImgSize
... ... @@ -170,22 +168,19 @@ export default {
background-color: #FFFFFF;
}
.left-right-split-line {
height: 100%;
width: 2px;
background-color: #EEEEEE;
}
.left-content {
width: 30%;
width: 28%;
height: 100%;
border-right: 1px solid #EEEEEE;
flex-shrink: 0;
}
.right-content {
display: flex;
flex-direction: column;
width: 70%;
flex-grow: 1;
height: 100%;
margin: 0 20px;
}
.category-left-item-root {
... ... @@ -195,6 +190,7 @@ export default {
align-items: center;
height: 104px;
line-height: 104px;
position: relative;
}
.category-left-item-title {
... ... @@ -210,17 +206,19 @@ export default {
}
.category-left-item-select {
font-size: 48px;
font-size: 44px;
color: #000000;
}
.category-left-item-select-flag {
width: 9px;
.category-left-item-select-flag:before {
content: "";
width: 6px;
height: 48px;
margin-bottom: 10px;
margin-top: 10px;
position: absolute;
left: 0;
top: 50%;
margin-top: -24px;
background-color: #000000;
justify-self: flex-start;
}
.category-sub-root {
... ... @@ -277,8 +275,8 @@ export default {
}
.item-imge-div {
height: 100%;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
... ... @@ -312,7 +310,6 @@ export default {
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
}
.item-a-div {
... ...
<template>
<LayoutApp :show-back="true" title="绑定支付宝">
<div class="body" ref="body">
<Scroll class="scroll-content">
<div class="account-form">
<p class="form-title">账号</p>
<div class="form-input-block">
... ... @@ -14,6 +15,7 @@
<div class="account-footer">
<CubeButton class="submit-btn" :disabled="canSubmit" @click="submitBind">提交</CubeButton>
</div>
</Scroll>
</div>
<myDialog :isShow="dialogShow" :data="{name,account}" @cancel-click="cancel" @confirm-click="confirm"></myDialog>
</LayoutApp>
... ... @@ -22,7 +24,7 @@
<script>
import { createNamespacedHelpers } from 'vuex';
import {Input, Button, Style} from 'cube-ui';
import {Input, Button, Scroll, Style} from 'cube-ui';
import myDialog from './components/bindModel';
const {mapState, mapActions} = createNamespacedHelpers('home/bindAccount');
export default {
... ... @@ -70,6 +72,7 @@ export default {
},
components: {
Style,
Scroll,
CubeInput: Input,
CubeButton: Button,
myDialog
... ... @@ -85,6 +88,9 @@ export default {
background-color: white;
padding: 0 40px;
}
/deep/ .cube-scroll-content {
height: 100%;
}
.account-form {
margin-top: 40px;
}
... ... @@ -117,8 +123,8 @@ export default {
.account-footer {
position: absolute;
padding: 28px 0;
left: 40px;
right: 40px;
left: 0;
right: 0;
bottom: 40px;
.submit-btn {
height: 88px;
... ...
... ... @@ -84,7 +84,8 @@ export default {
bounce: {
top: false
},
pullUpLoad: true
pullUpLoad: true,
pullDownRefresh: false
},
type: 'unused',
list: [],
... ... @@ -218,6 +219,7 @@ export default {
.item-price {
font-size: 72px;
font-weight: bold;
color: #002B47;
}
... ...
<template>
<LayoutApp :show-back="true" :title="title">
<Scroll
ref="scrolllist"
:scroll-events="['scroll-end','scroll']"
@scroll-end="fetchList(isMore)"
v-if="favoriteProductList.list.length"
class="fav-scroll-bg"
>
<LayoutApp :show-back="true" :title="title" class="favorite-wrapper">
<Scroll
ref="scrolllist"
:scroll-events="['scroll-end', 'scroll']"
@scroll-end="fetchList(isMore)"
v-if="favoriteProductList.list.length"
class="fav-scroll-bg"
>
<ProductList :list="favoriteProductList.list"></ProductList>
</Scroll>
<!-- <empty-list v-show="!isShowEmpty" /> -->
<UfoNoItem :tip="`暂无数据`" v-else></UfoNoItem>
<UfoNoItem class="empty" :tip="`暂无数据`" v-else></UfoNoItem>
</LayoutApp>
</template>
<script>
import ProductList from '../../list/components/productList';
import ProductList from "../../list/components/productList";
import EmptyList from "../../order/order-list/components/empty";
import UfoNoItem from '../../../components/ufo-no-item'
import {Scroll} from 'cube-ui';
import {createNamespacedHelpers} from 'vuex';
import UfoNoItem from "../../../components/ufo-no-item";
import { Scroll } from "cube-ui";
import { createNamespacedHelpers } from "vuex";
const {mapState, mapActions} = createNamespacedHelpers('home/favorite');
const { mapState, mapActions } = createNamespacedHelpers("home/favorite");
export default {
name: 'list',
name: "list",
components: {
ProductList,
Scroll,
... ... @@ -34,22 +34,22 @@ export default {
return {
scrollToY: -200,
scrollToTime: 700,
scrollToEasing: 'bounce',
scrollToEasing: "bounce",
scrollToEasingOptions: [
{
text: 'bounce',
value: 'bounce'
text: "bounce",
value: "bounce"
},
{
text: 'swipe',
value: 'swipe'
text: "swipe",
value: "swipe"
},
{
text: 'swipeBounce',
value: 'swipeBounce'
text: "swipeBounce",
value: "swipeBounce"
}
],
title: '我的收藏',
title: "我的收藏",
scrollOptions: {
bounce: {
top: false
... ... @@ -62,39 +62,38 @@ export default {
// mounted() {
// this.fetchFavoriteList();
// },
activated(){
console.log('favorite====activated')
activated() {
console.log("favorite====activated");
let params = {
isReset: true,
isReset: true
};
this.fetchFavoriteList({isReset: true});
this.fetchFavoriteList({ isReset: true });
// this.scrollToTop();
},
methods: {
...mapActions(['fetchFavoriteList']),
...mapActions(["fetchFavoriteList"]),
scrollToTop() {
// let height = this.$refs.scroll.scrollHeight
console.log(this.$refs)
console.log(this.$refs.scrolllist)
console.log(this.$refs);
console.log(this.$refs.scrolllist);
this.$refs.scroll.scrollTo(
0,
this.scrollToY,
this.scrollToTime,
ease[this.scrollToEasing]
)
);
},
async fetchList(isMore) {
if(this.isMore){
if (this.isMore) {
let params = {
isReset: false,
isReset: false
};
await this.fetchFavoriteList({isReset: false});
await this.fetchFavoriteList({ isReset: false });
}
},
}
// scroll({ y }) {
// const height = this.$refs.banner.$el.offsetHeight + this.$refs.header.offsetHeight;
... ... @@ -105,15 +104,27 @@ export default {
// }
// }
},
computed: {
...mapState(['favoriteProductList','isMore']),
},
...mapState(["favoriteProductList", "isMore"])
}
};
</script>
<style scoped>
.fav-scroll-bg {
background-color: #f5f5f5;
<style lang="scss" scoped>
.favorite-wrapper {
/deep/ .layout-context {
display: flex;
flex-direction: column;
}
.empty {
flex: 1;
}
}
.fav-scroll-bg {
background-color: #f5f5f5;
}
</style>
... ...
... ... @@ -4,7 +4,7 @@
<Scroll>
<div v-for="(value, key) in getMineList" :key="key">
<tab-item v-if="key === 'board'" :data="value" noLine icon="cubeic-notification" small grey>
<niticelScroll></niticelScroll>
<noticeScroll></noticeScroll>
</tab-item>
<template v-else-if="key === 'resource1' || key === 'resource2'">
<div v-if="value.data.template_name ==='single_image'" class="marg">
... ... @@ -70,7 +70,7 @@ export default {
components: {
tabItem,
order,
niticelScroll: scroll,
noticeScroll: scroll,
singleImage,
bind,
Style,
... ...
... ... @@ -36,6 +36,7 @@ export default {
.news-list-title {
margin-top: 60px;
font-size: 40px;
font-weight: bold;
color: #000000;
}
.news-list-content {
... ...
... ... @@ -29,7 +29,7 @@ export default {
},
data() {
return {
};
},
components: {
... ... @@ -48,6 +48,7 @@ export default {
.total-income {
color: #000;
font-size: 40px;
font-weight: bold;
margin-bottom: 44px;
}
.income {
... ...
... ... @@ -55,9 +55,11 @@ export default {
watch: {
"incomeData.list": function(val) {
if(val.length === 0) {
this.$refs.scroll.disable()
this.options.pullUpLoad.txt.noMore = ''
// this.$refs.scroll.disable()
} else {
this.$refs.scroll.enable()
this.options.pullUpLoad.txt.noMore = '到底啦~'
// this.$refs.scroll.enable()
}
}
},
... ...
<template>
<div class="bg">
<div class="item" v-if="list.length" v-for="(product,index) in list" @click="goDetail(product)"
<div class="product-list-item" v-if="list.length" v-for="(product,index) in list" @click="goDetail(product, index)"
:key="index" :class="(index) % 2 === 0 && 'magrin-right'">
<div class="item-top">
<div class="item-price">
... ... @@ -21,15 +21,87 @@ import ImgSize from '../../../components/img-size';
export default {
props: {
list: Array,
yasParams: Object,
},
data: function() {
return {
yasFirstId: 0,
};
},
methods: {
goDetail(product) {
goDetail(product, index) {
if (this.yasParams && Object.keys(this.yasParams).length) {
this.yasDetail(product.id, index);
}
this.$router.push({
name: 'ProductDetail',
params: {
productId: product.id,
}
});
},
yasShowEvent(height) {
// 获取列表单个元素高度
let index = 0;
if (height) {
// 获取第一个曝光元素
let item = document.querySelector('.product-list-item');
let itemHeight = item.offsetHeight;
let row = parseInt((height - 12) / itemHeight) + 1;
index = row * 2 - 2;
}
// 获取曝光列表
let list = [];
for (let i = 0; i < 6; i++) {
if (this.list[i + index]) {
list.push(this.list[i + index]);
}
}
// 判断是否是重复曝光
if (list.length && list[0].id !== this.yasFirstId) {
this.yasFirstId = list[0].id;
// 1.P_NAME:页面名称,XY_UFOSearchList,XY_UFOSeriesList,XY_UFOBrandList、XY_UFOProductPoolList等;
// 2.TYPE_ID:列表页入口类型,1-搜索结果页,2-系列,3-品牌,4-商品池;
// 3.P_PARAM:页面参数,搜索关键词,系列ID,品牌ID,商品池ID;
// 4.TAB_ID:tab切id,1-人气,2-价格,3-新品;
// 5.TAB_NAME:tab切名称,人气,价格,新品;
// 6.I_INDEX:曝光顺序;
// 7.PRD_ID:商品id;
let DATA = [];
list.map((value, i) => {
DATA.push({...this.yasParams, I_INDEX: i + index, PRD_ID: value.id});
});
this.$store.dispatch('reportYas', {
params: {
param: {DATA},
appop: 'XY_UFO_SHOW_EVENT'
}
});
}
},
yasDetail(id, index) {
// XY_UFO_PRD_LIST_C
// 1.P_NAME:页面名称,XY_UFOSearchList,XY_UFOSeriesList,XY_UFOBrandList、XY_UFOProductPoolList等;
// 2.TYPE_ID:列表页入口类型,1-搜索结果页,2-系列,3-品牌,4-商品池;
// 3.P_PARAM:页面参数,搜索关键词,系列ID,品牌ID,商品池ID;
// 4.TAB_ID:tab切id,1-人气,2-价格,3-新品;
// 5.TAB_NAME:tab切名称,人气,价格,新品;
// 6.I_INDEX:商品顺序号,从1开始递增;
// 7.PRD_ID:商品id
this.$store.dispatch('reportYas', {
params: {
param: {...this.yasParams, I_INDEX: index, PRD_ID: id },
appop: 'XY_UFO_PRD_LIST_C'
}
});
}
},
components: {
... ... @@ -44,11 +116,11 @@ export default {
margin-right: 14px;
}
.item {
.product-list-item {
border-radius: 16px;
width: 344px;
padding: 24px;
height: 498px;
padding: 24px 24px 32px;
// height: 498px;
background: #fff;
margin-bottom: 16px;
}
... ... @@ -57,7 +129,7 @@ export default {
height: 40px;
display: flex;
justify-content: space-between;
margin-bottom: 38px;
margin-bottom: 32px;
align-items: center;
}
... ... @@ -79,7 +151,6 @@ export default {
letter-spacing: 0;
line-height: 40px;
margin-top: 14px;
margin-bottom: 8px;
word-break: break-all;
display: -webkit-box;
-webkit-line-clamp: 2;
... ...
... ... @@ -45,6 +45,9 @@ import {Scroll} from 'cube-ui';
export default {
name: 'Filtrate',
components: {ImgSize, Scroll},
props: {
yasParams: Object,
},
data() {
return {
showType: false,
... ... @@ -130,9 +133,39 @@ export default {
params[row.filterId] = row.itemList[0].itemId;
}
});
let ENT_PARAMS = {}, ENT_ID = [], ENT_NAME = [];
for (let key in params) {
if (key === 'sort' && params[key]) {
ENT_PARAMS.category = params[key];
ENT_ID.push(params[key]);
ENT_NAME.push('品类');
}
if (key === 'brand' && params[key]) {
ENT_PARAMS.brand = params[key];
ENT_ID.push(params[key]);
ENT_NAME.push('品牌');
}
if (key === 'size' && params[key]) {
ENT_PARAMS.size = params[key];
ENT_ID.push(params[key]);
ENT_NAME.push('尺寸');
}
if (key === 'gender' && params[key]) {
ENT_PARAMS.sex = params[key];
ENT_ID.push(params[key]);
ENT_NAME.push('性别');
}
}
this.yasParams.ENT_PARAMS = JSON.stringify(ENT_PARAMS);
this.yasParams.ENT_ID = ENT_ID.toString();
this.yasParams.ENT_NAME = ENT_NAME.toString();
params.isReset = true;
this.yas(this.yasParams)
this.$parent.fetchList(params);
this.$parent.$refs.scroll.scrollTo(0, 0, 300)
this.$parent.$refs.scroll.scrollTo(0, 0, 300);
this.hide();
},
... ... @@ -169,7 +202,6 @@ export default {
for (let key in filter) {
filterParams[key] = filter[key];
}
console.log(filterParams);
this.filterParams = filterParams;
}
},
... ... @@ -179,6 +211,14 @@ export default {
},
hide() {
this.showType = false;
},
yas(param) {
this.$store.dispatch('reportYas', {
params: {
param,
appop: 'XY_UFO_PRD_LIST_SCREEN_C'
}
});
}
}
};
... ...
... ... @@ -19,15 +19,17 @@
</div>
</div>
<Scroll ref="scroll" class="product-list" v-show="!productList.isEmpty"
:scroll-events="['scroll-end']"
:options="scrollOptions"
:data="productList.list"
@scroll-end="scrollHandler"
@pulling-up="onPullingUp">
<ProductList :list="productList.list"></ProductList>
<ProductList ref="product" :list="productList.list" :yasParams="yasParams"></ProductList>
</Scroll>
<EmptyList class="empty-wrapper product-list" :tip="`暂无数据`" v-show="productList.isEmpty" >
<EmptyList class="empty-wrapper product-list" :tip="`暂无数据`" v-show="productList.isEmpty">
</EmptyList>
</LayoutApp>
<Filtrate ref="filtrate"></Filtrate>
<Filtrate ref="filtrate" :yasParams="yasParams"></Filtrate>
</div>
</template>
<script>
... ... @@ -48,19 +50,21 @@ export default {
Filtrate,
EmptyList
},
data() {
data: function() {
return {
scrollOptions: {
bounce: {
top: false
},
pullUpLoad: true
pullUpLoad: true,
pullDownRefresh: false
},
fixed: false,
selectedType: 2, // tab类型高亮
priceDesc: true,
arrowImage: '',
title: '',
yasParams: {P_NAME: 'XY_UFOSearchList', TYPE_ID: 1},
productList: {
showErrorPage: false,
isFetching: false,
... ... @@ -90,7 +94,7 @@ export default {
},
};
},
activated: function() {
activated: async function() {
if (this.yoho.direction === 'forword') {
this.$refs.filtrate.hide();
Object.assign(this.$data, this.$options.data());
... ... @@ -104,8 +108,10 @@ export default {
} else {
this.title = '商品列表';
}
this.setYasParam({param: params, tab: {index: 1, name: '人气'}});
!params.order && (params.order = 'sale_desc');
this.fetchList({...params, isReset: true});
await this.fetchList({...params, isReset: true});
this.yasShowPage();
},
computed: {
... ... @@ -120,6 +126,12 @@ export default {
await this.fetchList();
},
scrollHandler({y}) {
let height = -y;
this.$refs.product.yasShowEvent(height);
},
// 查询商品列表
fetchList: async function(params) {
let searchParams = this.searchParams;
... ... @@ -175,7 +187,7 @@ export default {
},
// 点击tab flag, 0: 推荐, 1: 价格, 2: 人气, 3: 新品
pressType(flag) {
async pressType(flag) {
if (flag === this.selectedType && flag !== 1) {
return;
}
... ... @@ -190,19 +202,24 @@ export default {
this.selectedType = flag;
if (flag === 1) {
this.setYasParam({tab: {index: 2, name: '价格'}});
this.priceDesc = !this.priceDesc;
params.order = this.priceDesc ? 'p_desc' : 'p_asc';
params.order = this.priceDesc ? 'availableNowPrice:asc' : 'availableNowPrice:desc';
} else if (flag === 2) {
this.setYasParam({tab: {index: 1, name: '人气'}});
this.priceDesc = true;
params.order = 'sale_desc';
} else if (flag === 3) {
this.setYasParam({tab: {index: 3, name: '新品'}});
this.priceDesc = true;
params.order = 'st_desc';
}
params.isReset = true;
this.fetchList(params);
this.$refs.scroll.scrollTo(0, 0, 300)
await this.fetchList(params);
this.$refs.scroll.scrollTo(0, 0, 300);
this.changeArrow();
this.yasShowPage();
this.yasTab();
},
goSearch() {
this.$router.push({
... ... @@ -215,6 +232,65 @@ export default {
},
goFilter() {
this.$refs.filtrate.show();
},
setYasParam: function({param, tab}) {
if (param && typeof param === 'object' && Object.keys(param).length) {
let P_NAME = 'XY_UFOSearchList', TYPE_ID = 1, P_PARAM = [];
for (let key in param) {
if (key === 'brand' && param[key] && param.type !== 6) {
P_NAME = 'XY_UFOBrandList';
TYPE_ID = 3;
}
if (key === 'series' && param[key] && param.type !== 6) {
P_NAME = 'XY_UFOSeriesList';
TYPE_ID = 2;
}
if (key === 'productPool' && param[key] && param.type !== 6) {
P_NAME = 'XY_UFOProductPoolList';
TYPE_ID = 4;
}
if (!param[key]) {
delete param[key];
}
P_PARAM.push(param[key]);
}
Object.assign(this.yasParams, {
P_NAME,
P_PARAM: P_PARAM.toString(),
TYPE_ID,
TAB_ID: this.tabIndex || '',
TAB_NAME: this.tabName || ''
});
}
if (tab && typeof tab === 'object' && Object.keys(tab).length) {
this.yasParams.TAB_ID = tab.index;
this.yasParams.TAB_NAME = tab.name;
}
},
yasShowPage() {
let {total, list} = this.productList;
let PRD_LIST = [];
for (let item of list) {
PRD_LIST.push(item.id);
}
PRD_LIST = PRD_LIST.toString();
this.$store.dispatch('reportYas', {
params: {
param: {...this.yasParams, TOTAL: total, PRD_LIST},
appop: 'XY_UFO_PRD_LIST_L'
}
});
},
yasTab() {
this.$store.dispatch('reportYas', {
params: {
param: {...this.yasParams},
appop: 'XY_UFO_PRD_LIST_TAB_C'
}
});
}
}
};
... ...
... ... @@ -3,7 +3,7 @@
<form action="javascript:void(0)">
<div class="search-header middle">
<div class="search-img"></div>
<input class="search-input" type="search" v-model="query" placeholder="Search" @input="suggest"
<input class="search-input" type="search" v-model="query" placeholder="Search" @input="suggest" @focus="yasFocus"
@keyup.13="searchGoods"/>
<div class="search-clear" :class="query && 'search-clear-img'" @click="clear()"></div>
</div>
... ... @@ -11,7 +11,7 @@
<Scroll v-show="!query.length" :options="scrollOptions">
<div class="recent title middle" v-if="searchWord && searchWord.length">热门推荐</div>
<div class="content middle">
<div class="item" v-if="searchWord && searchWord.length" v-for="item of searchWord" @click="goSearch({query : item.search_word})">
<div class="item" v-if="searchWord && searchWord.length" v-for="item of searchWord" @click="goSearch({query : item.search_word} ,2)">
{{item.search_word}}
</div>
</div>
... ... @@ -20,12 +20,12 @@
<div class="search-clear search-clear-img" @click="clearLocalHistory()"></div>
</div>
<div class="content middle">
<div class="item" v-if="localHistory && localHistory.length" v-for="item of localHistory" @click="goSearch({query : item})">{{item}}
<div class="item" v-if="localHistory && localHistory.length" v-for="item of localHistory" @click="goSearch({query : item} ,1)">{{item}}
</div>
</div>
</Scroll>
<Scroll v-show="query.length" :options="scrollOptions" :data="searchSuggestList">
<div class="item-line middle" v-if="searchSuggestList.length" v-for="item of searchSuggestList" @click="goSearch({query : item.item})">
<div class="item-line middle" v-if="searchSuggestList.length" v-for="item of searchSuggestList" @click="goSearch({query : item.item} ,0)">
{{item.item}}
</div>
</Scroll>
... ... @@ -70,6 +70,7 @@ export default {
},
searchGoods: function() {
this.addLocalWord();
this.yasInput(0);
this.$router.push({
name: 'List',
query: {
... ... @@ -81,9 +82,10 @@ export default {
suggest: function() {
this.fetchSearchSuggest(this.query);
},
goSearch: function(parameters) {
goSearch: function(parameters, type) {
let query = parameters.query;
this.yasInput(type);
this.$router.push({
name: 'List',
query: {
... ... @@ -118,6 +120,28 @@ export default {
localStorage.setItem('@YohoUFOStore:searchHistory', this.query);
}
}
},
yasFocus() {
this.$store.dispatch('reportYas', {
params: {
param: {SEARCH_POS: 3},
appop: 'XY_UFO_SEARCH_CLICK'
}
});
},
yasInput: function(type) {
this.$store.dispatch('reportYas', {
params: {
param: {
SEARCH_POS: 3,
KEYWORD: this.query,
POS_ID: type,
TYPE_ID: type,
FLR_INDEX: type,
},
appop: 'XY_UFO_HOME_KEYWORD_SEARCH_C'
}
});
}
}
};
... ...
<!--买家求购确认页-->
<template>
<LayoutApp :show-back="true" title="出价求购">
<cube-scroll :options="options">
<div class="body" ref="body">
<div class="topContainer">
<!--<div class="topView">-->
<!--<div class="title"></div>-->
... ... @@ -73,19 +75,22 @@
<div class="line"></div>
</div>
</div>
</cube-scroll>
<div class="bottomContainer">
<OrderAgree :value="isAgreeTerms" @input="isAgreeTerms = !isAgreeTerms" class="agree-wrapper" :desc="agreeDesc" :url="url"></OrderAgree>
<div class="btn-wrapper">
<YohoButton class="submit-btn" :txt="submitText" :disable="!isAgreeTerms" @click="submitClick"></YohoButton>
</div>
</div>
</LayoutApp>
</template>
<script>
import {Input, Button} from 'cube-ui';
import {Input, Button, Scroll} from 'cube-ui';
import OrderAddress from './components/confirm/address';
import DayChoose from './components/askorder/day-choose';
import OrderAgree from './components/confirm/agree';
... ... @@ -103,6 +108,7 @@ export default {
Input,
OrderAddress,
Button,
'cube-scroll': Scroll,
},
data() {
return {
... ... @@ -111,6 +117,7 @@ export default {
url: 'https://activity.yoho.cn/feature/6775.html?share_id=9481&title=%E9%97%B2%E9%B1%BC%E4%B9%B0%E5%AE%B6%E5%8D%8F%E8%AE%AE',
agreeDesc: '有货买家协议',
submitText: '提交',
options: {pullDownRefresh: false}
};
},
... ...
<template>
<LayoutApp :title="title">
<LayoutApp ref="layout" :title="title">
<div class="order-page">
<div class="product">
<ImgSize
... ... @@ -119,20 +119,20 @@
</template>
<script>
import LayoutApp from '../../../components/layout/layout-app';
import ScrollView from '../../../components/layout/scroll-view';
import ImgSize from '../../../components/img-size';
import { createNamespacedHelpers } from 'vuex';
import InputUfo from './components/input-ufo';
import { Checkbox } from 'cube-ui';
import { get } from 'lodash';
import Modal from './components/modal';
import OrderCheck from '../components/confirm/agree';
const { mapState, mapActions } = createNamespacedHelpers('order/priceChange');
import LayoutApp from "../../../components/layout/layout-app";
import ScrollView from "../../../components/layout/scroll-view";
import ImgSize from "../../../components/img-size";
import { createNamespacedHelpers } from "vuex";
import InputUfo from "./components/input-ufo";
import { Checkbox } from "cube-ui";
import { get } from "lodash";
import Modal from "./components/modal";
import OrderCheck from "../components/confirm/agree";
const { mapState, mapActions } = createNamespacedHelpers("order/priceChange");
// orderCode = 1233499619151
export default {
name: 'noEntryDetail',
name: "noEntryDetail",
components: {
OrderCheck,
Modal,
... ... @@ -144,35 +144,35 @@ export default {
},
data() {
return {
title: '调价',
title: "调价",
agreementURL:
'https://activity.yoho.cn/feature/3187.html?share_id=5851&title=ufo-%E5%8D%96%E5%AE%B6%E5%8D%8F%E8%AE%AE',
"https://activity.yoho.cn/feature/3187.html?share_id=5851&title=ufo-%E5%8D%96%E5%AE%B6%E5%8D%8F%E8%AE%AE",
platformFeeModalVisible: false,
platformFee: {
amount: '-¥0',
appraiseFee: '¥0.00',
packageFee: '¥0.00',
serviceFee: '¥0.00',
goodsPaymentRatePercent: '0.00%',
payChannelPercentage: '0.00%'
amount: "-¥0",
appraiseFee: "¥0.00",
packageFee: "¥0.00",
serviceFee: "¥0.00",
goodsPaymentRatePercent: "0.00%",
payChannelPercentage: "0.00%"
},
bankTransferFee: '-¥0',
income: '¥0',
errorTip: '',
chgPrice: '',
bankTransferFee: "-¥0",
income: "¥0",
errorTip: "",
chgPrice: "",
calced: false,
earnestMoney: '¥0',
earnestMoney: "¥0",
// 保证金
earnestPrice: 0,
isAgree: false,
labelOption: {
label: '我已阅读并同意'
label: "我已阅读并同意"
},
time: 15000
};
},
asyncData({ store, router }) {
return store.dispatch('order/priceChange/fetchOrder', {
return store.dispatch("order/priceChange/fetchOrder", {
orderCode: router.params.orderCode
});
},
... ... @@ -181,7 +181,7 @@ export default {
// this.inputChange = debounce(this.onChange.bind(this), 500);
},
computed: {
...mapState(['noEntryOrderInfo']),
...mapState(["noEntryOrderInfo"]),
goodsInfo() {
return this.noEntryOrderInfo.goodsInfo || {};
},
... ... @@ -193,37 +193,37 @@ export default {
chgPrice() {
this.calced = false;
this.platformFee = {
amount: '-¥0',
appraiseFee: '¥0.00',
packageFee: '¥0.00',
serviceFee: '¥0.00',
goodsPaymentRatePercent: '0.00%',
payChannelPercentage: '0.00%'
amount: "-¥0",
appraiseFee: "¥0.00",
packageFee: "¥0.00",
serviceFee: "¥0.00",
goodsPaymentRatePercent: "0.00%",
payChannelPercentage: "0.00%"
};
this.bankTransferFee = '-¥0';
this.income = '¥0';
this.earnestMoney = '¥0';
this.bankTransferFee = "-¥0";
this.income = "¥0";
this.earnestMoney = "¥0";
this.earnestPrice = 0;
}
},
methods: {
...mapActions([
'fetchOrder',
'postNoEntryCalcPrice',
'postNoEntryChangePrice'
"fetchOrder",
"postNoEntryCalcPrice",
"postNoEntryChangePrice"
]),
checkPrice(price) {
let valid = false;
if (!price) {
this.errorTip = '没有价格';
this.errorTip = "没有价格";
return false;
} else if (!/^\d+$/.test(price)) {
this.errorTip = '价格只能为正整数';
this.errorTip = "价格只能为正整数";
} else if (!/9$/.test(price)) {
this.errorTip = '出售价格必须以9结尾';
this.errorTip = "出售价格必须以9结尾";
} else {
this.errorTip = '';
this.errorTip = "";
valid = true;
}
console.log(this.errorTip, valid);
... ... @@ -233,15 +233,15 @@ export default {
// 点击提交按钮
if (this.isAgree && this.calced) {
this.$createDialog({
type: 'confirm',
content: '重新出售后本次出售保证金原路返回',
type: "confirm",
content: "重新出售后本次出售保证金原路返回",
confirmBtn: {
text: '我再想想',
text: "我再想想",
active: true,
disabled: false
},
cancelBtn: {
text: '重新出售',
text: "重新出售",
active: false,
disabled: false
},
... ... @@ -264,11 +264,11 @@ export default {
console.log(result);
if (result && result.code === 200) {
this.platformFee = get(result, 'data.platformFee', '');
this.bankTransferFee = get(result, 'data.bankTransferFee', '');
this.income = '¥' + get(result, 'data.income', '');
this.earnestMoney = '¥' + get(result, 'data.earnestMoney', '');
this.earnestPrice = get(result, 'data.earnestMoney', 0);
this.platformFee = get(result, "data.platformFee", "");
this.bankTransferFee = get(result, "data.bankTransferFee", "");
this.income = "¥" + get(result, "data.income", "");
this.earnestMoney = "¥" + get(result, "data.earnestMoney", "");
this.earnestPrice = get(result, "data.earnestMoney", 0);
this.calced = true;
} else {
if (result.message) {
... ... @@ -278,7 +278,7 @@ export default {
this.$createToast({
txt: this.errorTip,
type: 'txt'
type: "txt"
}).show();
}
},
... ... @@ -289,7 +289,7 @@ export default {
} else {
this.$createToast({
txt: this.errorTip,
type: 'txt'
type: "txt"
}).show();
}
},
... ... @@ -300,7 +300,7 @@ export default {
showEarnestQuestion() {
// 跳转保证金说明页
console.log('showEarnest');
console.log("showEarnest");
this.$xianyu.goXianyuNewPage({ url: this.agreementURL });
},
... ... @@ -322,14 +322,14 @@ export default {
this.$createOrderPayType({
orderCode: result.data.orderCode,
price: parseFloat(`${earnestPrice}`).toFixed(2),
desc: '保证金',
desc: "保证金",
extra: JSON.stringify({
type: 'sell',
type: "sell",
back: {
name: 'InSaleOrderList'
name: "InSaleOrderList"
},
forward: {
name: 'SellPayOk',
name: "SellPayOk",
query: {
orderCode: result.data.orderCode
}
... ... @@ -338,9 +338,9 @@ export default {
onCloseAction() {
that.clearData();
that.$router.replace({
name: 'sellOrderDetail',
name: "sellOrderDetail",
params: {
owner: 'sell',
owner: "sell",
code: result.data.orderCode
}
});
... ... @@ -348,8 +348,8 @@ export default {
}).show();
} else {
this.$createToast({
txt: result.message || '调价失败',
type: 'txt'
txt: result.message || "调价失败",
type: "txt"
}).show();
}
... ... @@ -360,20 +360,27 @@ export default {
// console.log(this.$router);
this.platformFeeModalVisible = false;
this.platformFee = {
amount: '-¥0',
appraiseFee: '¥0.00',
packageFee: '¥0.00',
serviceFee: '¥0.00',
goodsPaymentRatePercent: '0.00%',
payChannelPercentage: '0.00%'
amount: "-¥0",
appraiseFee: "¥0.00",
packageFee: "¥0.00",
serviceFee: "¥0.00",
goodsPaymentRatePercent: "0.00%",
payChannelPercentage: "0.00%"
};
this.bankTransferFee = '-¥0';
this.income = '¥0';
this.errorTip = '';
this.chgPrice = '';
this.bankTransferFee = "-¥0";
this.income = "¥0";
this.errorTip = "";
this.chgPrice = "";
this.calced = false;
this.earnestMoney = '¥0';
this.earnestMoney = "¥0";
this.isAgree = false;
},
checkScroll(e) {
if (e.currentTarget.scrollTop > 0) {
this.$refs.layout.stopPrevent();
} else {
this.$refs.layout.startPrevent();
}
}
}
};
... ...
<!--卖家求购变现-->
<template>
<LayoutApp :show-back="true" title="变现">
<cube-scroll :options="options">
<div class="body">
<!--<TitleComp txt="变现"></TitleComp>-->
<ProductInfo :data="originProductData" class="product-info" :priceType="'现货最高求购价:'"></ProductInfo>
<div class="inputView">
<span class="inputViewIcon">
... ... @@ -13,18 +15,21 @@
<OrderMargin class="order-item order-margin" :data="computeTip" :url="url" :superSell="isEntry" ></OrderMargin>
<OrderFee class="order-item" :data="computeTip"></OrderFee>
<AddressInfo :data="addressInfo" class="order-item"></AddressInfo>
</div>
</cube-scroll>
<div class="footer">
<OrderAgree :value="isAgreeTerms" @input="isAgreeTerms = !isAgreeTerms" class="agree-wrapper" :desc="agreeDesc" :url="url"></OrderAgree>
<div class="btn-wrapper">
<YohoButton :txt="submitText"class="submit-btn" :disable="!isAgreeTerms" @click="submitClick"></YohoButton>
</div>
</div>
</LayoutApp>
</template>
<script>
import {Button} from 'cube-ui';
import {Button, Scroll} from 'cube-ui';
import ProductInfo from './components/confirm/product';
import InputPrice from './components/confirm/input-price';
import AddressInfo from './components/confirm/address';
... ... @@ -41,10 +46,7 @@ const { mapState, mapActions, mapMutations, mapGetters} = createNamespacedHelper
export default {
name: 'seller-ask-order',
props: {
skup: Number,
price: Number,
},
props: ['skup', 'price'],
components: {
Button,
ProductInfo,
... ... @@ -53,7 +55,8 @@ export default {
TitleComp,
OrderMargin,
OrderFee,
OrderAgree
OrderAgree,
'cube-scroll': Scroll,
},
data() {
... ... @@ -64,6 +67,7 @@ export default {
url: 'http://m.yohobuy.com/activity/student/detail/renzhen?openby:yohobuy={\"action\":\"go.h5\",\"params\":{\"url\":\"https://activity.yoho.cn/feature/3187.html?title=卖家协议\"}}',
isEntry: false,
submitText: '提交',
options: {pullDownRefresh: false},
};
},
... ...
... ... @@ -15,34 +15,48 @@
<!-- </Scroll>-->
</div>
<div class="footer">
<OrderAgree :value="agree" @input="changeAgree" class="agree-wrapper" :desc="agreeDesc" :url="url"></OrderAgree>
<OrderAgree
:value="agree"
@input="changeAgree"
class="agree-wrapper"
:desc="agreeDesc"
:url="url"
></OrderAgree>
<div class="btn-wrapper">
<YohoButton :txt="txt" class="submit-btn" @click="onClick" :disable="!agree"></YohoButton>
<YohoButton
:txt="txt"
class="submit-btn"
@click="onClick"
:disable="!agree"
></YohoButton>
</div>
</div>
</LayoutApp>
</template>
<script>
import ProductInfo from './components/confirm/product';
import InputPrice from './components/confirm/input-price';
import AddressInfo from './components/confirm/address';
import TitleComp from './components/confirm/title';
import OrderMargin from './components/confirm/order-margin';
import OrderFee from './components/confirm/order-fee';
import OrderAgree from './components/confirm/agree';
import { Types, UserType } from 'store/order/order-confirm';
import { Scroll } from 'cube-ui';
import { get } from 'lodash';
import { createNamespacedHelpers, mapState } from 'vuex';
const { mapState: mapOrderState, mapActions: mapOrderAction, mapMutations: mapOrderMutations } = createNamespacedHelpers('order/orderConfirm');
import ProductInfo from "./components/confirm/product";
import InputPrice from "./components/confirm/input-price";
import AddressInfo from "./components/confirm/address";
import TitleComp from "./components/confirm/title";
import OrderMargin from "./components/confirm/order-margin";
import OrderFee from "./components/confirm/order-fee";
import OrderAgree from "./components/confirm/agree";
import { Types, UserType } from "store/order/order-confirm";
import { Scroll } from "cube-ui";
import { get } from "lodash";
import { createNamespacedHelpers, mapState } from "vuex";
const {
mapState: mapOrderState,
mapActions: mapOrderAction,
mapMutations: mapOrderMutations
} = createNamespacedHelpers("order/orderConfirm");
export default {
name: 'SellOrderConfirm',
props: ['productId', 'storageId'],
name: "SellOrderConfirm",
props: ["productId", "storageId"],
components: {
Scroll,
ProductInfo,
... ... @@ -55,56 +69,78 @@ export default {
},
data() {
return {
txt: '提交',
txt: "提交",
error: false,
agreeDesc: '有货卖家协议',
url: 'https://activity.yoho.cn/feature/6773.html?share_id=9479&title=%E9%97%B2%E9%B1%BC%E6%BD%AE%E5%8D%96%E5%AE%B6%E5%8D%8F%E8%AE%AE',
agreeDesc: "有货卖家协议",
url:
"https://activity.yoho.cn/feature/6773.html?share_id=9479&title=%E9%97%B2%E9%B1%BC%E6%BD%AE%E5%8D%96%E5%AE%B6%E5%8D%8F%E8%AE%AE",
superSell: false,
addNumError: false,
scrollOption: {
bounce: false,
click: true
},
tipUrl: 'https://activity.yoho.cn/feature/6773.html?share_id=9479&title=%E9%97%B2%E9%B1%BC%E6%BD%AE%E5%8D%96%E5%AE%B6%E5%8D%8F%E8%AE%AE'
tipUrl:
"https://activity.yoho.cn/feature/6773.html?share_id=9479&title=%E9%97%B2%E9%B1%BC%E6%BD%AE%E5%8D%96%E5%AE%B6%E5%8D%8F%E8%AE%AE"
};
},
activated() {
this.fetchUserStatus().then(result => {
this.superSell = get(result, 'data.entrySellerType', 0) !== 0;
this.superSell = get(result, "data.entrySellerType", 0) !== 0;
});
this.fetchOrderAddress({ tabType: UserType.sell });
this.$store.dispatch('product/getSelectedTradeProduct', {
this.$store.dispatch("product/getSelectedTradeProduct", {
productId: this.productId,
storageId: this.storageId
});
},
beforeRouteLeave(to, from, next) {
if (to.name !== 'address') {
if (to.name !== "address") {
this[Types.CLEAR_SELL_STATUS]();
}
next();
},
computed: {
...mapOrderState(['address', 'fee', 'price', 'agree', 'num']),
...mapOrderState(["address", "fee", "price", "agree", "num"]),
...mapState({
productDetail: state => {
const leastPrice = get(state.product.selectedProductInfo, 'size.least_price', 0);
const storageNum = get(state.product.selectedProductInfo, 'size.storage_num', 0);
const suggestHighPrice = get(state.product.selectedProductInfo, 'size.suggest_high_price', 0);
const suggestLowPrice = get(state.product.selectedProductInfo, 'size.suggest_low_price', 0);
const bidPrice = get(state.product.selectedProductInfo, 'size.bid_moster_price', 0);
let priceType = '最低现货价:';
let goodPrice = '';
let priceBidType = '最高求购价:';
let goodBidPrice = '¥-';
const leastPrice = get(
state.product.selectedProductInfo,
"size.least_price",
0
);
const storageNum = get(
state.product.selectedProductInfo,
"size.storage_num",
0
);
const suggestHighPrice = get(
state.product.selectedProductInfo,
"size.suggest_high_price",
0
);
const suggestLowPrice = get(
state.product.selectedProductInfo,
"size.suggest_low_price",
0
);
const bidPrice = get(
state.product.selectedProductInfo,
"size.bid_moster_price",
0
);
let priceType = "最低现货价:";
let goodPrice = "";
let priceBidType = "最高求购价:";
let goodBidPrice = "¥-";
if (!storageNum) {
if (suggestHighPrice && suggestLowPrice) {
priceType = '建议售价:';
priceType = "建议售价:";
goodPrice = `¥${suggestLowPrice}-¥${suggestHighPrice}`;
} else {
goodPrice = '¥-';
goodPrice = "¥-";
}
} else {
goodPrice = `¥${leastPrice}`;
... ... @@ -117,13 +153,33 @@ export default {
}
return {
goodImg: get(state.product.selectedProductInfo, 'product.goods_list[0].image_list[0].image_url', ''),
productName: get(state.product.selectedProductInfo, 'product.product_name', ''),
productId: get(state.product.selectedProductInfo, 'product.product_id', ''),
colorName: get(state.product.selectedProductInfo, 'product.goods_list[0].color_name', ''),
sizeName: get(state.product.selectedProductInfo, 'size.size_name', ''),
skup: get(state.product.selectedProductInfo, 'size.skup', ''),
bidSkup: get(state.product.selectedProductInfo, 'size.bid_skup', ''),
goodImg: get(
state.product.selectedProductInfo,
"product.goods_list[0].image_list[0].image_url",
""
),
productName: get(
state.product.selectedProductInfo,
"product.product_name",
""
),
productId: get(
state.product.selectedProductInfo,
"product.product_id",
""
),
colorName: get(
state.product.selectedProductInfo,
"product.goods_list[0].color_name",
""
),
sizeName: get(
state.product.selectedProductInfo,
"size.size_name",
""
),
skup: get(state.product.selectedProductInfo, "size.skup", ""),
bidSkup: get(state.product.selectedProductInfo, "size.bid_skup", ""),
goodPrice,
priceType,
goodBidPrice,
... ... @@ -137,44 +193,62 @@ export default {
})
},
methods: {
...mapOrderAction(['fetchOrderAddress', 'fetchUserStatus', 'fetchOrderPrice', 'submitOrder', 'fetchPayList']),
...mapOrderMutations([Types.CHANGE_PRICE, Types.CHANGE_AGREE, Types.CLEAR_SELL_STATUS, Types.CHANGE_SELL_NUM]),
...mapOrderAction([
"fetchOrderAddress",
"fetchUserStatus",
"fetchOrderPrice",
"submitOrder",
"fetchPayList"
]),
...mapOrderMutations([
Types.CHANGE_PRICE,
Types.CHANGE_AGREE,
Types.CLEAR_SELL_STATUS,
Types.CHANGE_SELL_NUM
]),
onClick() {
this.submit();
},
compute() {
if (this.productDetail.bidPrice && (Number(this.price) > 0) && (Number(this.price) <= this.productDetail.bidPrice)) {
if (
this.productDetail.bidPrice &&
Number(this.price) > 0 &&
Number(this.price) <= this.productDetail.bidPrice
) {
this.$createDialog({
type: 'confirm',
type: "confirm",
title: `最高求购价${this.productDetail.bidPrice}`,
content: '已有求购高于您的出价,可直接变现',
content: "已有求购高于您的出价,可直接变现",
confirmBtn: {
text: '我再想想',
text: "我再想想",
active: true,
disabled: false,
disabled: false
},
cancelBtn: {
text: '确定变现',
text: "确定变现",
active: false,
disabled: false
},
onCancel: () => {
this.$store.commit('order/sellerAskOrder/SELLER_ASK_SET_PRODUCTINFO', {
goodImg: this.productDetail.goodImg,
colorName: this.productDetail.colorName,
sizeName: this.productDetail.sizeName,
goodPrice: this.productDetail.bidPrice,
productId: this.productDetail.productId,
bid_moster_price: this.productDetail.bidPrice,
});
this.$store.commit(
"order/sellerAskOrder/SELLER_ASK_SET_PRODUCTINFO",
{
goodImg: this.productDetail.goodImg,
colorName: this.productDetail.colorName,
sizeName: this.productDetail.sizeName,
goodPrice: this.productDetail.bidPrice,
productId: this.productDetail.productId,
bid_moster_price: this.productDetail.bidPrice
}
);
// 跳转变现
this.$router.push({
name: 'sellAskOrder',
name: "sellAskOrder",
query: {
skup: this.productDetail.bidSkup,
price: this.productDetail.bidPrice,
price: this.productDetail.bidPrice
}
});
}
... ... @@ -186,7 +260,7 @@ export default {
address_id: this.address?.address_id,
num: this.num,
price: this.price,
storage_id: this.storageId,
storage_id: this.storageId
}).then(result => {
if (result.error) {
this.error = result.error;
... ... @@ -194,7 +268,7 @@ export default {
this.$createToast({
time: 1500,
txt: result.error,
type: 'txt'
type: "txt"
}).show();
if (result.code === 438) {
... ... @@ -214,8 +288,8 @@ export default {
if (!this.address) {
this.$createToast({
time: 1500,
txt: '请选择地址',
type: 'txt'
txt: "请选择地址",
type: "txt"
}).show();
return false;
}
... ... @@ -229,22 +303,21 @@ export default {
if (this.productDetail.isSuggest) {
if (Number(this.price) > this.productDetail.suggestHighPrice) {
this.$createDialog({
type: 'confirm',
content: '超出建议售价将被限制展示,建议下调至合理价格区间',
type: "confirm",
content: "超出建议售价将被限制展示,建议下调至合理价格区间",
confirmBtn: {
text: '修改价格',
text: "修改价格",
active: true,
disabled: false,
disabled: false
},
cancelBtn: {
text: '仍要上架',
text: "仍要上架",
active: false,
disabled: false
},
onCancel: () => {
this.submitHandler();
}
}).show();
} else {
this.submitHandler();
... ... @@ -270,14 +343,14 @@ export default {
address_id: this.address?.address_id,
num: this.num,
price: this.price,
storage_id: this.storageId,
storage_id: this.storageId
});
if (orderResult.code !== 200) {
this.$createToast({
time: 1500,
txt: orderResult.message,
type: 'txt'
type: "txt"
}).show();
return;
}
... ... @@ -288,13 +361,13 @@ export default {
time: 1500,
txt: orderResult.message,
mask: true,
type: 'txt'
type: "txt"
}).show();
await this.delay(1500);
this.$router.replace({
name: 'ProductDetail',
name: "ProductDetail",
params: {
productId: this.productId
}
... ... @@ -304,18 +377,18 @@ export default {
this.$createOrderPayType({
price: parseFloat(`${this.fee.earnestMoney}`).toFixed(2),
desc: '保证金',
desc: "保证金",
orderCode: orderResult.data.orderCode,
extra: JSON.stringify({
type: UserType.sell,
back: {
name: 'ProductDetail',
name: "ProductDetail",
params: {
productId: this.productId
}
},
forward: {
name: 'SellPayOk',
name: "SellPayOk",
query: {
orderCode: orderResult.data.orderCode
}
... ... @@ -328,7 +401,7 @@ export default {
},
onClose(orderCode) {
this.$router.replace({
name: 'sellOrderDetail',
name: "sellOrderDetail",
params: {
owner: UserType.sell,
code: orderCode
... ... @@ -337,7 +410,7 @@ export default {
},
onNumChange({ count, type }) {
console.log(count, type, this.addNumError);
if (type === 'add' && this.addNumError) {
if (type === "add" && this.addNumError) {
return;
}
... ... @@ -351,7 +424,7 @@ export default {
},
backAction() {
this.$router.replace({
name: 'ProductDetail',
name: "ProductDetail",
params: {
productId: this.productId
}
... ... @@ -384,6 +457,7 @@ export default {
width: 100%;
border-top: 1px solid #eee;
z-index: 1;
background: #fff;
}
.btn-wrapper {
... ... @@ -406,5 +480,4 @@ export default {
line-height: 80px;
font-size: 28px;
}
</style>
... ...
<template>
<layout-app title="商品列表" class="brand-product-list">
<scroll-view
ref="scroll"
:data="brandProductList"
:options="scrollOption"
@pulling-down="onPullingDown">
<div class="list-wrapper" v-if="brandProductList != null">
<product-list :list="brandProductList" />
</div>
</scroll-view>
</layout-app>
</template>
<script>
import { createNamespacedHelpers } from 'vuex';
import ScrollView from 'components/layout/scroll-view';
import ProductList from '../list/components/productList';
const STORE_PATH = 'product';
const { mapActions, mapState } = createNamespacedHelpers(STORE_PATH);
export default {
name: 'BrandProductList',
props: ['productId'],
components: {
ProductList,
ScrollView,
},
data() {
return {
inLoading: false,
scrollOption: {
pullDownRefresh: {
threshold: 70,
stop: 90
},
observeDOM: false,
pullUpLoad: false,
},
};
},
computed: {
...mapState(['topLists']),
brandProductList() {
return this.topLists[this.$route.params.productId];
},
},
asyncData({store, router}) {
return store.dispatch(`${STORE_PATH}/fetchBrandTop`, {productId: router.params.productId});
},
methods: {
...mapActions(['fetchBrandTop']),
onPullingDown() {
this.fetchBrandTop({productId: this.productId});
},
},
};
</script>
<style lang="scss" scoped>
.brand-product-list /deep/ .scroll-view {
background: #f5f5f5;
}
</style>
... ...
... ... @@ -66,12 +66,12 @@ export default {
}
span {
font-size: 0.8em;
line-height: 1.4;
border: 1px solid #f00;;
color: #f00;
font-size: 0.7em;
line-height: 1.8;
border: 1px solid #feabac;
color: #feabac;
text-align: center;
padding: 0 0.9em;
padding: 0 1.2em;
margin-right: 0.8em;
display: inline-block;
position: relative;
... ... @@ -91,7 +91,7 @@ export default {
.sub {
color: #999;
font-size: 0.8em;
font-size: 22px;
}
}
</style>
... ...
... ... @@ -206,6 +206,7 @@ export default {
align-items: baseline;
font-size: 40px;
letter-spacing: 0;
font-family: $num-font;
span:nth-child(2) {
font-size: 0.8em;
... ...
... ... @@ -200,7 +200,7 @@ export default {
li {
box-sizing: border-box;
width: 25%;
width: 25%; // 当前固定为4列
float: left;
border: 1px solid #ddd;
margin-right: -1px;
... ... @@ -245,6 +245,7 @@ export default {
.size-info {
color: #000;
font-family: $num-font;
font-weight: bold;
font-size: 40px;
display: inline-block;
... ...
... ... @@ -225,6 +225,7 @@ export default {
i {
float: right;
color: #999;
}
}
... ... @@ -232,7 +233,8 @@ export default {
padding: 0 40px 16px;
}
.select-size, .select-type {
.select-size,
.select-type {
display: flex;
flex-direction: column;
height: 60vh;
... ... @@ -254,7 +256,6 @@ export default {
padding-top: 30px;
font-size: 32px;
color: #000;
font-family: "Alte DIN 1451 Mittelschrift";
}
}
}
... ... @@ -335,6 +336,10 @@ export default {
overflow: scroll;
}
.crash-info {
font-family: $num-font;
}
.footer {
padding: 16px 0;
display: flex;
... ... @@ -344,9 +349,9 @@ export default {
span {
font-size: 28px;
margin-left: 8px;
i {
font-family: "Alte DIN 1451 Mittelschrift";
font-size: 20px;
font-style: normal;
}
... ...
... ... @@ -5,12 +5,12 @@
<div @click="onAllClick">全部 <i class="cubeic-arrow"></i></div>
</div>
<div class="row">
<div class="col" v-for="(product, idx) in list" :key="idx">
<div class="product-item" @click="onItemClick(product)">
<div class="col" v-for="(product, idx) in viewList" :key="idx" @click="onItemClick(product)">
<div class="product-item">
<square-img :src="product.default_images" :width="300" :height="300" />
<div class="name"><span>{{product.product_name}}</span></div>
<div class="price"><i>¥</i>{{product.price}}</div>
</div>
<div class="name"><span>{{product.product_name}}</span></div>
<div class="price"><i>¥</i>{{product.price}}</div>
</div>
</div>
</div>
... ... @@ -30,6 +30,11 @@ export default {
default: [],
},
},
computed: {
viewList() {
return this.list && this.list.slice(0, 3) || [];
},
},
methods: {
onItemClick(item) {
this.$emit('itemClick', item);
... ... @@ -61,26 +66,30 @@ export default {
font-size: 36px;
font-weight: bold;
color: #000;
font-weight: bold;
}
.row {
overflow: hidden;
margin: 0 -8px;
margin: 0 -6px;
.col {
width: 33.3333%;
width: 222px;
padding: 0 8px;
float: left;
}
}
.product-item {
margin-top: 10px;
margin: 10px auto 0;
width: 180px;
text-align: center;
overflow: hidden;
}
.name {
width: 200px;
margin: 0 auto 8px;
height: 64px;
display: flex;
flex-direction: column;
... ... @@ -98,13 +107,15 @@ export default {
}
.price {
font-family: $num-font;
font-weight: bold;
font-size: 24px;
font-size: 32px;
color: #d0021b;
text-align: center;
i {
font-style: normal;
font-size: 0.9em;
font-size: 24px;
vertical-align: baseline;
}
}
... ...
... ... @@ -7,4 +7,9 @@ export default [{
productId: parseInt(params.productId, 10),
};
},
}, {
name: 'BrandProductList',
path: '/xianyu/brand-product/:productId.html',
component: () => import(/* webpackChunkName: "product" */ './brand-product-list'),
props: true,
}];
... ...
$primary-color : #08304b;
$sub-color : #64ad88;
$num-font: "DINAlternate-Bold", "din alternate", "PingFang SC", "HiraginoSansGB-W3", "SanFranciscoText-Regular", Helvetica, Roboto, "Heiti SC", "黑体", Arial;
@mixin cube-ufo-btn {
[type="button"] {
... ...
... ... @@ -19,8 +19,8 @@
<div class="info">
<div class="info-price">
<template v-if="productDetail.least_price >= 0"> ¥{{productDetail.least_price}}</template>
<template v-else>&nbsp;</template>
<template v-if="productDetail.least_price == null">{{'\u200E'}}</template>
<template v-else><i>¥</i>{{productDetail.least_price}}</template>
</div>
<div class="info-name">{{productDetail.product_name}}</div>
</div>
... ... @@ -55,15 +55,23 @@
<div class="footer">
<div class="heart">
<div class="icon-fav" v-if="isFav" @click="_toggleFav(false)">
<svg id="icon-heart" style="width: 1rem; height: 1rem;" viewBox="0 0 28 28">
<title>heart</title>
<path d="M14 26c-0.25 0-0.5-0.094-0.688-0.281l-9.75-9.406c-0.125-0.109-3.563-3.25-3.563-7 0-4.578 2.797-7.313 7.469-7.313 2.734 0 5.297 2.156 6.531 3.375 1.234-1.219 3.797-3.375 6.531-3.375 4.672 0 7.469 2.734 7.469 7.313 0 3.75-3.437 6.891-3.578 7.031l-9.734 9.375c-0.187 0.187-0.438 0.281-0.688 0.281z"></path>
<svg style="width: 1rem; height: 1rem;" viewBox="0 0 24 24">
<title>已收藏</title>
<g id="icon/已收藏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g fill="#002B47">
<path d="M11.9998882,18.7717254 L6.90760779,20.9153484 C6.3574449,21.1469424 5.72370571,20.8886913 5.49211167,20.3385284 C5.42388696,20.1764573 5.39623656,20.0001874 5.41155922,19.8250107 L5.88943154,14.3617254 L5.88943154,14.3617254 L2.2755824,10.2271262 C1.88274872,9.77768578 1.92863753,9.09488771 2.37807795,8.70205402 C2.51228845,8.58474724 2.67342863,8.50245519 2.84714548,8.46250776 L8.22341829,7.22619542 L8.22341829,7.22619542 L11.0754231,2.5175655 C11.3846728,2.00699755 12.0492663,1.84379684 12.5598342,2.15304652 C12.708963,2.24337339 12.8340264,2.36843679 12.9243532,2.5175655 L15.7763581,7.22619542 L15.7763581,7.22619542 L21.1526309,8.46250776 C21.734369,8.59628261 22.097515,9.1763205 21.9637402,9.75805866 C21.9237928,9.93177551 21.8415007,10.0929157 21.7241939,10.2271262 L18.1103448,14.3617254 L18.1103448,14.3617254 L18.5882171,19.8250107 C18.6402311,20.4196615 18.200337,20.9438868 17.6056863,20.9959008 C17.4305096,21.0112235 17.2542397,20.9835731 17.0921686,20.9153484 L11.9998882,18.7717254 L11.9998882,18.7717254 Z"></path>
</g>
</g>
</svg>
</div>
<div class="icon-fav" v-else @click="_toggleFav(true)">
<svg id="icon-heart-o" style="width: 1rem; height: 1rem;" viewBox="0 0 28 28">
<title>heart-o</title>
<path d="M26 9.312c0-4.391-2.969-5.313-5.469-5.313-2.328 0-4.953 2.516-5.766 3.484-0.375 0.453-1.156 0.453-1.531 0-0.812-0.969-3.437-3.484-5.766-3.484-2.5 0-5.469 0.922-5.469 5.313 0 2.859 2.891 5.516 2.922 5.547l9.078 8.75 9.063-8.734c0.047-0.047 2.938-2.703 2.938-5.563zM28 9.312c0 3.75-3.437 6.891-3.578 7.031l-9.734 9.375c-0.187 0.187-0.438 0.281-0.688 0.281s-0.5-0.094-0.688-0.281l-9.75-9.406c-0.125-0.109-3.563-3.25-3.563-7 0-4.578 2.797-7.313 7.469-7.313 2.734 0 5.297 2.156 6.531 3.375 1.234-1.219 3.797-3.375 6.531-3.375 4.672 0 7.469 2.734 7.469 7.313z"></path>
<svg id="icon-heart-o" style="width: 1rem; height: 1rem;" viewBox="0 0 24 24">
<title>未收藏</title>
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g stroke="#B2B2B2" stroke-width="1.62123234">
<path d="M6.59310422,20.1682298 L11.9998882,17.892215 L17.4066721,20.1682298 C17.4471899,20.185286 17.4912574,20.1921986 17.5350516,20.188368 C17.6837143,20.1753645 17.7936878,20.0443081 17.7806843,19.8956454 L17.2727172,14.088301 L21.113856,9.69365996 C21.1431827,9.66010733 21.1637558,9.61982229 21.1737426,9.57639307 C21.2071863,9.43095853 21.1163998,9.28594906 20.9709653,9.25250535 L15.2606075,7.93936778 L12.2310044,2.93752506 C12.2084227,2.90024288 12.1771569,2.86897703 12.1398747,2.84639531 C12.0122327,2.76908289 11.8460843,2.80988307 11.7687719,2.93752506 L8.73916885,7.93936778 L3.02881107,9.25250535 C2.98538186,9.26249221 2.94509681,9.28306522 2.91154419,9.31239191 C2.79918408,9.41060033 2.78771188,9.58129985 2.8859203,9.69365996 L6.72705916,14.088301 L6.21909207,19.8956454 C6.21526141,19.9394396 6.22217401,19.9835071 6.23923019,20.0240249 C6.2971287,20.1615656 6.4555635,20.2261284 6.59310422,20.1682298 Z"></path>
</g>
</g>
</svg>
</div>
收藏
... ... @@ -193,7 +201,7 @@ export default {
next();
},
methods: {
...mapActions(['fetchProductInfo', 'fetchTop3', 'fetchFav', 'toggleFav', 'updateTradeInfo', 'getSelectedTradeProduct', 'payment', 'resetSelectedSize']),
...mapActions(['fetchProductInfo', 'fetchBrandTop', 'fetchFav', 'toggleFav', 'updateTradeInfo', 'getSelectedTradeProduct', 'payment', 'resetSelectedSize']),
refresh() {
this.$refs.slide.refresh();
},
... ... @@ -210,7 +218,7 @@ export default {
loadData(productId = this.productId, loading) {
loading && loading.show();
this.fetchTop3({productId});
this.fetchBrandTop({productId});
this.fetchFav({productId});
return this.fetchProductInfo({productId}).then(() => {
... ... @@ -265,23 +273,11 @@ export default {
});
},
gotoBrand() {
// type: 4,品牌;5,系列
const query = {
type: 5,
};
if (this.productDetail.seriesId && this.productDetail.series_name) {
query.series = this.productDetail.seriesId;
query.title = this.productDetail.series_name;
} else {
query.type = 4;
query.brand = this.productDetail.brandId;
query.title = this.productDetail.brand_name;
}
this.$router.push({
name: 'List',
query,
name: 'BrandProductList',
params: {
productId: this.productId,
},
});
},
showActivity() {
... ... @@ -407,6 +403,8 @@ export default {
}
.slide {
height: 520px;
.square-img-container {
display: block;
width: 520px;
... ... @@ -467,8 +465,8 @@ export default {
span {
display: inline-block;
border: 1px solid #f00;
color: #f00;
border: 1px solid #feabac;
color: #feabac;
line-height: 1.8;
margin-right: 15px;
font-size: 0.8em;
... ... @@ -486,8 +484,10 @@ export default {
&-price {
color: #d0021b;
font-size: 48px;
font-family: $num-font;
font-weight: bold;
text-align: center;
letter-spacing: 0;
i {
font-style: normal;
... ... @@ -553,6 +553,7 @@ export default {
display: flex;
text-align: center;
padding: 16px 30px;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.08);
@include cube-ufo-btn;
... ...
... ... @@ -54,7 +54,15 @@ export default function() {
buyAgree: false,
orderDetail: {},
orderDetail: {
promotionFormulaList: [
{ promotion: '商品金额', promotionAmount: '¥0.00' },
{ promotion: '运费', promotionAmount: '+ ¥0.00' },
{ promotion: '优惠券', promotionAmount: '- ¥0.00' },
{ promotion: '运费券', promotionAmount: '- ¥0.00' },
{ promotion: '实付金额', promotionAmount: '¥0.00' }
]
},
selectedCouponList: [],
selectedPromotion: null,
couponList: []
... ... @@ -101,7 +109,15 @@ export default function() {
},
[Types.CLEAR_BUY_STATUS](state) {
state.buyAgree = false;
state.orderDetail = {};
state.orderDetail = {
promotionFormulaList: [
{ promotion: '商品金额', promotionAmount: '¥0.00' },
{ promotion: '运费', promotionAmount: '+ ¥0.00' },
{ promotion: '优惠券', promotionAmount: '- ¥0.00' },
{ promotion: '运费券', promotionAmount: '- ¥0.00' },
{ promotion: '实付金额', promotionAmount: '¥0.00' }
]
};
state.selectedCouponList = [];
state.selectedPromotion = null;
state.couponList = [];
... ...
... ... @@ -62,13 +62,13 @@ export default {
commit(Types.UPDATE_PRODUCT_FAV, { productId, isFav });
},
async fetchTop3({ commit }, { productId }) {
async fetchBrandTop({ commit }, { productId }) {
const result = await this.$api.post('/api/ufo/product/top', { product_id: productId });
if (result.code === 200) {
const productList = result.data.product_list || [];
commit(Types.UPDATE_PRODUCT_TOP3, { productId, topList: productList.slice(0, 3) });
commit(Types.UPDATE_BRAND_PRODUCT_TOP_LIST, { productId, topList: productList});
}
},
async toggleFav({ commit }, { productId, isFav }) {
... ...
... ... @@ -30,7 +30,7 @@ export default {
state.products = {...state.products, [payload.product_id]: payload};
ensureSelectedProduct(state, payload.product_id);
},
[Types.UPDATE_PRODUCT_TOP3](state, { productId, topList }) {
[Types.UPDATE_BRAND_PRODUCT_TOP_LIST](state, { productId, topList }) {
state.topLists = {...state.topLists, [productId]: topList};
},
[Types.UPDATE_PRODUCT_FAV](state, { productId, isFav }) {
... ...
... ... @@ -3,4 +3,4 @@ export const ENSURE_PRODUCT_DETAIL = 'ENSURE_PRODUCT_DETAIL';
export const UPDATE_PRODUCT_FAV = 'UPDATE_PRODUCT_FAV';
export const UPDATE_SELECTED_PRODUCT_SIZE = 'UPDATE_SELECTED_PRODUCT_SIZE';
export const RESET_SELECTED_PRODUCT_SIZE = 'RESET_SELECTED_PRODUCT_SIZE';
export const UPDATE_PRODUCT_TOP3 = 'UPDATE_PRODUCT_TOP3';
export const UPDATE_BRAND_PRODUCT_TOP_LIST = 'UPDATE_BRAND_PRODUCT_TOP_LIST';
... ...
... ... @@ -113,7 +113,7 @@ module.exports = {
'/api/ufo/coupon/list': {
ufo: true,
auth: true,
path: '/ufo-gateway/coupon',
path: 'coupon',
api: 'ufo.coupons.list',
param: {}
},
... ...
... ... @@ -4,4 +4,14 @@ module.exports = [
cacheTime: 60,
cache: true,
},
{
route: /xianyu\/index/,
cacheTime: 60,
cache: true,
},
{
route: /xianyu\/index\/category/,
cacheTime: 30,
cache: true,
},
];
... ...
... ... @@ -124,9 +124,7 @@ const render = (route) => {
res.setHeader('X-YOHO-Version', pkg.version);
const isDegrade = _.get(req.app.locals.wap, 'webapp.degrade', false);
if (route.accessLog) {
logger.info(`${req.yoho.clientIp} | ${req.url} | uid:${req.user.uid} | ${new Date()}`);
}
logger.info(`${req.yoho.clientIp} | ${req.url} | uid:${req.user.uid} | ua:${req.get('user-agent')} | ${new Date()}`);
if (isDegrade) {
return res.send(degradeHtml);
... ...
{
"name": "xianyu-ufo-app-web",
"version": "0.0.2-beta-35",
"version": "0.0.2-beta-38",
"private": true,
"description": "Xianyu Project With Express",
"repository": {
... ...