Authored by baoss

Merge branch 'develop' of git.yoho.cn:fe/xianyu-ufo-app-web into develop

... ... @@ -86,7 +86,7 @@ export default {
...mapOrderAction(['payAction']),
show() {
this.$refs.actionSheet.show();
this.pay()
this.pay();
},
hide() {
this.$refs.actionSheet.hide();
... ... @@ -127,7 +127,8 @@ export default {
appop: this.appOp().pay,
param: {
ORD_NUM: this.orderCode,
PAY_TYPE: 1
PAY_TYPE: 1,
ORD_TYPE: this.appOp().type
},
},
});
... ... @@ -139,44 +140,18 @@ export default {
time: 1500,
type: 'txt'
}).show();
//数据埋点
this.$store.dispatch('reportYas', {
params: {
appop: this.appOp().result,
param: {
ORD_NUM: this.orderCode,
PAY_TYPE: 1, //1支付宝支付,2微信支付
PAY_RES: 0, //0支付失败,1支付成功
ORDER_AMOUNT: this.price
},
},
});
},
onSuccess(result) {
this.hide();
this.$emit('paySuccess');
//数据埋点
this.$store.dispatch('reportYas', {
params: {
appop: this.appOp().result,
param: {
ORD_NUM: this.orderCode,
PAY_TYPE: 1,
PAY_RES: 1,
ORDER_AMOUNT: this.price
},
},
});
this.$router.replace({
name: 'OrderPay',
query: {
orderCode: this.orderCode,
payParams: result.data.payParams,
extra: this.extra
extra: this.extra,
price: this.price
}
});
... ... @@ -211,19 +186,29 @@ export default {
case 'sell': {
return {
pay: 'XY_UFO_SALE_PAY',
result: 'XY_UFO_SALE_PAY_RES'
result: 'XY_UFO_SALE_PAY_RES',
type: 1,
};
}
case 'buy': {
return {
pay: 'XY_UFO_SC_PAY',
result: 'XY_UFO_SC_PAY_RES'
pay: 'XY_UFO_SALE_PAY',
result: 'XY_UFO_SALE_PAY_RES',
type: 2,
};
}
case 'qiugou_buy': {
return {
pay: 'XY_UFO_WTBUY_PAY',
result: 'XY_UFO_WTBUY_PAY_RES'
pay: 'XY_UFO_SALE_PAY',
result: 'XY_UFO_SALE_PAY_RES',
type: 3
};
}
case 'bianxian': {
return {
pay: 'XY_UFO_SALE_PAY',
result: 'XY_UFO_SALE_PAY_RES',
type: 4
};
}
default: {
... ...
... ... @@ -77,7 +77,7 @@ Vue.use(ChangeBidPriceDialog);
initClient(store);
xianyu.$router = router;
yoho.auth = async (args) => {
yoho.auth = async(args) => {
let {
refer,
loginUrl,
... ... @@ -108,7 +108,7 @@ yoho.auth = async (args) => {
}
};
yoho.authRealName = async () => {
yoho.authRealName = async() => {
if (await yoho.auth()) {
let res = await api.get('/api/ufo/sellerOrder/entryStatus');
... ...
... ... @@ -169,8 +169,6 @@
});
}
})();
window.appBaseLogs = {events: [{}], device: {ak: '', udid: ''}, status: [{av: '', udid: '', sid: ''}]};
</script>
</body>
</html>
... ...
... ... @@ -5,8 +5,8 @@
<CInput
label="收货人"
place-holder="请写姓名"
v-model="model.consignee"
:textValue="model.consignee"
v-model="consignee"
:textValue="consignee"
type="text"
></CInput>
</FormItem>
... ... @@ -14,8 +14,8 @@
<CInput
label="手机号"
place-holder="请填写手机号"
v-model="model.mobile"
:textValue="model.mobile"
v-model="mobile"
:textValue="mobile"
></CInput>
</FormItem>
... ... @@ -24,8 +24,8 @@
<div class="wrapper-area">
<label class="input-label">所在区域</label>
<div class="wrapper-arrow" @click="chooseArea">
<template v-if="model.area">
<label class="text-label">{{ model.area }}</label>
<template v-if="area">
<label class="text-label">{{ area }}</label>
</template>
<template v-else>
<label class="choose-area">请选择</label>
... ... @@ -40,8 +40,8 @@
<CInput
label="详细地址"
place-holder="请输入详细地址"
v-model="model.address"
:textValue="model.address"
v-model="address"
:textValue="address"
></CInput>
</FormItem>
<!-- 订单修改地址隐藏 -->
... ... @@ -53,8 +53,8 @@
<Radio
class="tag-radio"
:label="{ text: `${tag.name}`, value: `${tag.code}` }"
v-model="model.tag_code"
checked="tag.code === model.tag_code"
v-model="tag_code"
:checked="tag.code === tag_code"
></Radio>
</div>
</RadioGroup>
... ... @@ -66,8 +66,8 @@
class="radio"
:label="{ text: '设为默认地址', value: true }"
style="flex: 0 1 100%;"
checked="model.is_default"
v-model="model.is_default"
checked="is_default"
v-model="is_default"
></Radio>
</div>
</div>
... ... @@ -117,20 +117,19 @@ export default {
isMobileNumEdit: false,
title: '',
orderCode: '',
model: {
consignee: '',
address_id: '',
mobile: '',
area_code: '',
area: '',
address: '',
tag_code: '',
is_default: false
}
consignee: '',
address_id: '',
mobile: '',
area_code: '',
area: '',
address: '',
tag_code: '',
is_default: false
};
},
watch: {
'model.mobile': function(val) {
mobile: function(val) {
if (val === this.updateMobileNum) {
this.isMobileNumEdit = false;
} else {
... ... @@ -150,10 +149,10 @@ export default {
},
inNotEmpty() {
return (
this.model.consignee &&
this.model.mobile &&
this.model.area &&
this.model.address
this.consignee &&
this.mobile &&
this.area &&
this.address
);
}
},
... ... @@ -209,8 +208,7 @@ export default {
}
},
validator() {
let info = this.model;
let username = info.consignee.replace(/(^\s+)|(\s+$)/g, '');
let username = this.consignee.replace(/(^\s+)|(\s+$)/g, '');
// 简单的表单校验
if (!username) {
... ... @@ -230,38 +228,38 @@ export default {
reg = /^[0123456789]{11}$/;
}
if (!info.mobile) {
if (!this.mobile) {
this.showToast('手机号不能为空');
return false;
} else {
if (!reg.test(info.mobile)) {
if (!reg.test(this.mobile)) {
this.showToast('请输入正确11位手机号码');
return;
}
}
if (!info.area_code || !info.area) {
if (!this.area_code || !this.area) {
this.showToast('省市区不能为空');
return false;
}
if (!info.address) {
if (!this.address) {
this.showToast('地址不能为空');
return false;
}
return {
id: info.address_id || '',
id: this.address_id || '',
consignee: username,
mobile: info.mobile,
area_code: info.area_code,
area: info.area,
address: info.address,
is_default: info.is_default ? 'Y' : 'N',
tag_code: info.tag_code
mobile: this.mobile,
area_code: this.area_code,
area: this.area,
address: this.address,
is_default: this.is_default ? 'Y' : 'N',
tag_code: this.tag_code
};
},
async delAddress() {
const result = await this.deleteUserAddress(this.model.address_id);
const result = await this.deleteUserAddress(this.address_id);
if (result && result.code === 200) {
this.$createToast({
type: 'txt',
... ... @@ -282,7 +280,7 @@ export default {
this.isShowProvince = true;
this.$refs.addressAct.parentHandleclick({
areaCode: this.model.area_code
areaCode: this.area_code
});
},
popHidden() {
... ... @@ -292,8 +290,8 @@ export default {
modifyAddressAct(info) {
if (info) {
let that = this;
that.model.area_code = info.code;
that.model.area = info.area;
that.area_code = info.code;
that.area = info.area;
}
},
showToast(tip) {
... ... @@ -325,16 +323,17 @@ export default {
if (addressInfo.isUpdate) {
this.updateMobileNum = addressInfo.mobile;
this.model.consignee = addressInfo.consignee;
this.model.address_id = addressInfo.address_id;
this.model.mobile = addressInfo.mobile;
this.model.area_code = addressInfo.area_code || addressInfo.areaCode;
this.model.area = addressInfo.area;
this.model.address = addressInfo.address;
this.model.tag_code = addressInfo.tag_code;
this.model.is_default = addressInfo.is_default === 'Y' ? true : false;
this.consignee = addressInfo.consignee;
this.address_id = addressInfo.address_id;
this.mobile = addressInfo.mobile;
this.area_code = addressInfo.area_code || addressInfo.areaCode;
this.area = addressInfo.area;
this.address = addressInfo.address;
this.tag_code = addressInfo.tag_code || '';
this.is_default = addressInfo.is_default === 'Y' ? true : false;
} else {
this.model = {};
// 重置data数据
Object.assign(this.$data, this.$options.data());
}
}
};
... ...
... ... @@ -400,8 +400,12 @@ export default {
} else {
list[key] = data[key];
}
if (!data.product_list) {
this.productList.list = [];
}
}
this.productList = list;
}
} catch (e) {
// console.log(e);
... ...
... ... @@ -49,6 +49,8 @@ export default {
...product,
price: product[this.priceKey], // 统一接收端使用的价格key
},
yasParams: this.yasParams,
}
});
},
... ...
... ... @@ -377,9 +377,10 @@ export default {
reportType: 'qiugou_buy',
type: 'buy',
back: {
name: 'ProductDetail',
name: 'buyOrderDetail',
params: {
productId: get(this.originProductData, 'productId', '')
owner: 'buy',
code: get(this.publishresult, 'orderCode', ''),
}
},
forward: {
... ...
... ... @@ -224,9 +224,10 @@ export default {
type: UserType.buy,
reportType: 'buy',
back: {
name: 'ProductDetail',
name: 'buyOrderDetail',
params: {
productId: this.productId
owner: UserType.buy,
code: result.data.orderCode
}
},
forward: {
... ...
... ... @@ -2,15 +2,15 @@
<div class="fee-detail">
<div class="item">
<div>平台费用:<i class="iconfont iconquestion icon-class" @click="onClick"></i></div>
<div>{{data.platformFee.amount || '¥0'}}</div>
<div>{{feeInfo.platformFee.amount || '¥0'}}</div>
</div>
<div class="item">
<div>银行转账费(1%):</div>
<div>{{data.bankTransferFee || '¥0'}}</div>
<div>{{feeInfo.bankTransferFee || '¥0'}}</div>
</div>
<div class="item">
<div class="total-fee">实际收入:</div>
<div class="fee">{{data.income || '¥0'}}</div>
<div class="fee">{{feeInfo.income || '¥0'}}</div>
</div>
<Modal ref="dialog" v-model="showModal">
... ... @@ -20,17 +20,17 @@
<div class="item item2">
<span>商品鉴定费</span>
<span>{{data.platformFee.appraiseFee}}</span>
<span>{{feeInfo.platformFee.appraiseFee}}</span>
</div>
<div class="item item2">
<span>商品包装费</span>
<span>{{data.platformFee.packageFee}}</span>
<span>{{feeInfo.platformFee.packageFee}}</span>
</div>
<div class="item item2">
<span>平台服务费({{data.platformFee.goodsPaymentRatePercent}})</span>
<span>{{data.platformFee.serviceFee}}</span>
<span>平台服务费({{feeInfo.platformFee.goodsPaymentRatePercent}})</span>
<span>{{feeInfo.platformFee.serviceFee}}</span>
</div>
<template slot="footer">
... ... @@ -58,7 +58,8 @@ export default {
data() {
return {
confirmBtn: {},
showModal: false
showModal: false,
feeInfo: this.$props.data || {platformFee: {}}
};
},
components: {
... ... @@ -67,7 +68,7 @@ export default {
},
methods: {
onClick() {
if (!this.data.income) {
if (!this.feeInfo.income) {
return this.$createToast({
txt: '没有价格',
time: 1500,
... ...
<template>
<div>
<div class="tip" v-if="!superSell">需支付保证金:<span class="red">{{data.earnestMoneyStr || '¥0'}}</span><i v-if="!hiddenIcon"
class="iconfont iconquestion icon-class"
@click="onClick"></i></div>
<div class="tip2">所有商品必须为国内现货,且承诺36小时内发货,交易成功后将自动退还保证金</div>
<div class="tip" v-if="!superSell">
需支付保证金:<span class="red">{{ earnestInfo.earnestMoneyStr || "¥0" }}</span>
<i
v-if="!hiddenIcon"
class="iconfont iconquestion icon-class"
@click="onClick"
></i>
</div>
<div class="tip2">
所有商品必须为国内现货,且承诺36小时内发货,交易成功后将自动退还保证金
</div>
</div>
</template>
<script>
export default {
name: 'OrderFee',
name: "OrderFee",
props: {
data: {
type: Object,
... ... @@ -31,13 +38,18 @@ export default {
},
url: {
type: String,
default: ''
default: ""
}
},
data() {
return {
earnestInfo: this.$props.data || {}
}
},
methods: {
onClick() {
if (this.url) {
this.$xianyu.goXianyuNewPage({url: this.url});
this.$xianyu.goXianyuNewPage({ url: this.url });
}
}
}
... ...
<template>
<layout-app class="address-wrapper" title="商品回寄地址">
<SellOrderAddress :isOnlyShowBack="true" />
<layout-app title="商品回寄地址">
<div class="address-wrapper">
<SellOrderAddress :isOnlyShowBack="true" />
</div>
</layout-app>
</template>
... ...
... ... @@ -20,6 +20,7 @@ export default [
orderCode: route.query.orderCode,
payParams: route.query.payParams,
extra: route.query.extra,
price: route.query.price
}),
},
{
... ...
... ... @@ -3,7 +3,6 @@
<layout-app
:title="'\u200E'"
class="buyer-order-detail-wrapper"
:backAction="onBack"
>
<div class="order-detail-wrapper">
<div class="content">
... ...
... ... @@ -3,7 +3,6 @@
<layout-app
:title="'\u200E'"
class="seller-order-detail-wrapper"
:backAction="onBack"
>
<div class="order-detail-wrapper">
<div class="content">
... ...
... ... @@ -18,7 +18,6 @@ const routers = [
};
},
beforeEnter: (to, from, next) => {
// ...
next();
},
},
... ...
... ... @@ -22,7 +22,7 @@ const { mapActions: mapOrderAction } = createNamespacedHelpers('order/orderConfi
export default {
name: 'PayPage',
props: ['orderCode', 'payParams', 'extra'],
props: ['orderCode', 'payParams', 'extra', 'price'],
data() {
return {
count: 60,
... ... @@ -68,10 +68,14 @@ export default {
if (this.page.forward) {
this.$router.replace(this.page.forward);
}
this.paySuccess();
}, () => {
if (this.page.back) {
this.$router.replace(this.page.back);
}
this.payError();
});
} else {
const url = config.alipayUrl + '?' + this.payParams;
... ... @@ -175,6 +179,77 @@ export default {
break;
}
}
},
appOp() {
switch (this.page.reportType) {
case 'sell': {
return {
pay: 'XY_UFO_SALE_PAY',
result: 'XY_UFO_SALE_PAY_RES',
type: 1,
};
}
case 'buy': {
return {
pay: 'XY_UFO_SALE_PAY',
result: 'XY_UFO_SALE_PAY_RES',
type: 2,
};
}
case 'qiugou_buy': {
return {
pay: 'XY_UFO_SALE_PAY',
result: 'XY_UFO_SALE_PAY_RES',
type: 3
};
}
case 'bianxian': {
return {
pay: 'XY_UFO_SALE_PAY',
result: 'XY_UFO_SALE_PAY_RES',
type: 4
};
}
default: {
// PASS
return {
pay: 'XY_UFO_SALE_PAY',
result: 'XY_UFO_SALE_PAY_RES'
};
}
}
},
paySuccess() {
//数据埋点
this.$store.dispatch('reportYas', {
params: {
appop: this.appOp().result,
param: {
ORD_NUM: this.orderCode,
PAY_TYPE: 1,
PAY_RES: 1,
ORDER_AMOUNT: this.price,
ORD_TYPE: this.appOp().type
},
},
});
},
payError() {
//数据埋点
this.$store.dispatch('reportYas', {
params: {
appop: this.appOp().result,
param: {
ORD_NUM: this.orderCode,
PAY_TYPE: 1, //1支付宝支付,2微信支付
PAY_RES: 0, //0支付失败,1支付成功
ORDER_AMOUNT: this.price,
ORD_TYPE: this.appOp().type
},
},
});
}
}
};
... ...
... ... @@ -48,7 +48,16 @@ export default {
border-color: #f5f5f5;
}
/deep/ input::-webkit-input-placeholder {
font-size: 0.9rem;
padding: 0.2rem;
bottom: 0.4rem;
}
/deep/ .cube-input-field {
font-family: "DINAlternate-Bold", "ufofont", "PingFang-SC-Regular", sans-serif;
padding: 0.25rem;
font-size: 1rem;
color: #000;
}
}
... ...
... ... @@ -142,7 +142,7 @@ export default {
this.sellerPublish({price: this.price, skup: this.skup, address_id: this.addressInfo.address_id})
.then((res) => {
if (res && res.code && res.code == 200) {
if (res && res.code && res.code === 200) {
this.$createToast({
time: 1000,
type: 'txt',
... ... @@ -169,7 +169,7 @@ export default {
this.sellerPublish({price: this.price, skup: this.skup, address_id: this.addressInfo.address_id})
.then((res) => {
if (res && res.code && res.code == 200) {
if (res && res.code && res.code === 200) {
this.payOrder();
} else {
this.$createToast({
... ... @@ -177,25 +177,26 @@ export default {
type: 'txt',
txt: res.message
}).show();
}
});
}
},
payOrder() {
let vm = this;
this.$createOrderPayType({
price: get(this.computeTip, 'earnestMoney', 0),
desc: '保证金',
orderCode: get(this.publishinfo, 'orderCode', ''),
extra: JSON.stringify({
type: 'sell',
reportType: 'bianxian',
back: {
name: 'ProductDetail',
name: 'sellOrderDetail',
params: {
productId: get(this.originProductData, 'productId', '')
owner: 'sell',
code: get(this.publishinfo, 'orderCode', '')
}
},
forward: {
... ... @@ -209,6 +210,12 @@ export default {
vm.onClose(get(this.publishinfo, 'orderCode', ''));
}
}).show();
this.reportYas('XY_UFO_CASH_ORD', {
ORD_NUM: get(this.publishinfo, 'orderCode', ''),
PRD_ID: get(this.originProductData, 'productId', ''),
PRD_SKU: this.skup
});
},
showToast() {
... ...
... ... @@ -352,12 +352,6 @@ export default {
return;
}
this.reportYas('XY_UFO_SALE_ORD', {
ORD_NUM: orderResult.code.orderCode,
PRD_ID: this.productDetail.productId,
PRD_SKU: this.productDetail.skup
});
// 从定金中走了钱,不用支付宝
if (orderResult.data.orderCode === 0) {
this.$createToast({
... ... @@ -386,9 +380,10 @@ export default {
type: UserType.sell,
reportType: 'sell',
back: {
name: 'ProductDetail',
name: 'sellOrderDetail',
params: {
productId: this.productId
owner: UserType.sell,
code: orderResult.data.orderCode
}
},
forward: {
... ... @@ -402,6 +397,12 @@ export default {
vm.onClose(orderResult.data.orderCode);
}
}).show();
this.reportYas('XY_UFO_SALE_ORD', {
ORD_NUM: orderResult.data.orderCode,
PRD_ID: this.productDetail.productId,
PRD_SKU: this.productDetail.skup
});
},
onClose(orderCode) {
this.$router.replace({
... ...
<template>
<layout-app title="商品列表" class="brand-product-list">
<div class="scroll-view" ref="scroll">
<LayoutScroll
class="scroll-view"
@scroll-end="scrollEndHandler">
<div class="list-wrapper" v-if="brandProductList != null">
<product-list :list="brandProductList" priceKey="price"/>
<product-list ref="productList" :list="brandProductList" priceKey="price" :yas-params="recommendYasParams"/>
</div>
</div>
</LayoutScroll>
</layout-app>
</template>
... ... @@ -14,7 +16,7 @@ import ScrollView from 'components/layout/scroll-view';
import ProductList from '../list/components/productList';
const STORE_PATH = 'product';
const { mapActions, mapState } = createNamespacedHelpers(STORE_PATH);
const { mapState } = createNamespacedHelpers(STORE_PATH);
export default {
name: 'BrandProductList',
... ... @@ -35,6 +37,18 @@ export default {
observeDOM: false,
pullUpLoad: false,
},
/**
* 商品详情页-推荐商品曝光时
* XY_UFO_SHOW_EVENT
* 1.P_NAME:页面名称,UFOProductDetail_LIST;
* 2.P_PARAM:页面参数;
* 3.I_INDEX:曝光顺序;
* 4.PRD_SKN:商品id;
*/
recommendYasParams: {
P_NAME: 'UFOProductDetail_LIST',
},
};
},
computed: {
... ... @@ -52,9 +66,10 @@ export default {
}
},
methods: {
...mapActions(['fetchBrandTop']),
onPullingDown() {
this.fetchBrandTop({productId: this.productId});
scrollEndHandler({y}) {
const scrollTop = Math.abs(y);
this.$refs.productList && this.$refs.productList.yasShowEvent(scrollTop);
},
},
};
... ...
... ... @@ -8,10 +8,10 @@
:emulateMask="true"
:full="true">
<div class="buy-sheet">
<a class="header" @click.prevent="gotoNewPage">求购<i class="cubeic-question question"></i></a>
<a class="header" @click.prevent="gotoNewPage">求购<i class="iconfont iconquestion"></i></a>
<div class="title">
<div class="title-thumbnail">
<square-img :src="imageUrl" :width="300" :height="300"/>
<square-img :src="imageUrl" :width="600" :height="600"/>
</div>
<div>选择尺码填写理想的价格发布求购</div>
<div>{{productDetail.product_name}} {{goodsName}}</div>
... ... @@ -19,9 +19,9 @@
<div class="size-list">
<cube-scroll ref="scroll" :data="sizeViewList">
<ul>
<li :class="['size-item', item.available ? '': 'disable']" v-for="(item, idx) in sizeViewList" :key="idx" @click="buy(item)">
<li class="size-item" v-for="(item, idx) in sizeViewList" :key="idx" @click="buy(item)">
<div class="size"><span>{{item.name}}</span><span v-if="item.subName">{{item.subName}}</span></div>
<div class="price">最高求购价 ¥{{item.price}} <i class="cubeic-arrow"></i></div>
<div class="price">最高求购价 <span>¥{{item.price}}</span> <i class="cubeic-arrow"></i></div>
</li>
</ul>
</cube-scroll>
... ... @@ -75,7 +75,6 @@ export default {
size_name: info.size_name,
price,
storage_id: info.storage_id,
available: info.storage_num > 0 && price !== '-',
skup: info.skup,
least_price: info.least_price,
bid_moster_price: info.bid_moster_price,
... ... @@ -185,11 +184,11 @@ export default {
color: #999;
letter-spacing: 0;
text-align: right;
}
.question {
color: #ccc;
font-size: 28px;
.iconfont {
margin-left: 5px;
font-size: inherit;
}
}
.title-thumbnail {
... ... @@ -220,6 +219,7 @@ export default {
align-items: baseline;
font-size: 40px;
letter-spacing: 0;
@include num;
span:nth-child(2) {
... ... @@ -236,6 +236,12 @@ export default {
letter-spacing: 0;
text-align: right;
span {
margin-left: 5px;
@include num;
}
i {
display: inline-block;
margin-left: 5px;
... ...
... ... @@ -224,9 +224,6 @@ export default {
.size-scroll {
width: 100%;
position: absolute;
top: 0;
bottom: 0;
}
li {
... ... @@ -242,7 +239,7 @@ export default {
}
.size-price {
font-family: "PingFang SC", "HiraginoSansGB-W3", "SanFranciscoText-Regular", Helvetica, Roboto, "Heiti SC", "黑体", Arial;
font-family: $size-font;
}
&.selected {
... ... @@ -278,6 +275,7 @@ export default {
height: 0;
padding-bottom: 100%;
position: relative;
box-sizing: border-box;
}
.size {
... ...
... ... @@ -5,11 +5,11 @@
<div class="title" @click="hide">{{config.title}}<i class="cubeic-close"></i></div>
<div class="selected-info">
<div class="title-thumbnail">
<square-img :src="imageList[0] && imageList[0].image_url" :width="70" :height="70"/>
<square-img :src="imageList[0] && imageList[0].image_url" :width="600" :height="600"/>
</div>
<div class="product">
<div>
<template v-if="product.least_price >= 0"> ¥{{product.least_price}}</template>
<template v-if="selectedPrice != null && selectedPrice >= 0"> ¥{{selectedPrice}}</template>
<template v-else>&nbsp;</template>
</div>
<div>
... ... @@ -89,6 +89,23 @@ export default {
return {};
},
selectedPrice() {
let price = this.product.least_price;
if (this.config.type === 'sell') {
return price;
}
if (this.selectedSize.size_id > 0) {
if (this.selectedSize.least_price > 0) {
price = this.selectedSize.least_price;
} else {
price = '-';
}
}
return price;
},
goods_name() {
return get(this.product, 'goods_list[0].goods_name', '');
},
... ... @@ -201,6 +218,23 @@ export default {
bid_moster_price: get(this.selectedSize, 'bid_moster_price', ''),
});
/**
* 数据埋点
* 商品详情页点击出售/购买/求购按钮
* event: XY_UFO_PRD_DT_SALE_C
* params: 1.TAB_ID:1-出售,2-购买,3-求购, 4-变现;
* 2.PRD_ID:商品ID;
*/
this.$store.dispatch('reportYas', {
params: {
appop: 'XY_UFO_PRD_DT_BUY_SEL_C',
param: {
TAB_ID: 4,
PRD_ID: this.product.product_id,
},
}
});
// 跳转变现
this.$router.push({
name: 'sellAskOrder',
... ... @@ -249,7 +283,7 @@ export default {
height: 60vh;
}
}
.selected-info {
display: flex;
padding-bottom: 20px;
... ... @@ -353,7 +387,7 @@ export default {
}
.footer {
padding: 16px 0;
padding: 16px 0 0;
display: flex;
justify-content: space-between;
... ...
... ... @@ -7,7 +7,7 @@
<div class="row">
<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" />
<square-img :src="product.default_images" :width="600" :height="600" />
</div>
<div class="name"><span>{{product.product_name}}</span></div>
<div class="price"><i>¥</i>{{product.price}}</div>
... ...
... ... @@ -14,7 +14,7 @@ export default {
return this.productDetail.goods_list[0].image_list;
},
resource() {
return this.productDetail.resource;
return this.productDetail.resource || {};
},
activity() {
return this.productDetail.activity;
... ...
$primary-color : #08304b;
$sub-color : #64ad88;
$size-font: "PingFang SC", "HiraginoSansGB-W3", "SanFranciscoText-Regular", Helvetica, Roboto, "Heiti SC", "黑体", Arial, serif;
@mixin cube-ufo-btn {
[type="button"] {
box-sizing: border-box;
... ...
<template>
<div class="layout">
<LayoutHeader class="layout-header" :show-back="true" :title="'\u200E'"></LayoutHeader>
<LayoutHeader class="layout-header" :show-back="true" title="商品详情"></LayoutHeader>
<div class="layout-context fixscroll">
<div class="cube-scroll-wrapper" ref="pageScroll">
<LayoutScroll
ref="pageScroll"
class="cube-scroll-wrapper"
@scroll-end="scrollEndHandler">
<div class="slide">
<cube-slide ref="slide" :data="imageList">
<cube-slide-item v-for="(item, index) in imageList" :key="index">
... ... @@ -27,8 +30,8 @@
</div>
<div class="info-name"><div>{{productDetail.product_name}}</div></div>
</div>
<a class="banner" @click.prevent="gotoNewPage">
<img-size v-if="resource" ref="resourceImg" :src="sizeImg(resource.src)"/>
<a class="banner" v-if="resource.src" @click.prevent="gotoNewPage">
<img-size ref="resourceImg" :src="sizeImg(resource.src)"/>
</a>
<div class="info">
<transition-group name="info-list" tag="div" class="info-list">
... ... @@ -44,7 +47,8 @@
<div class="info-list-value">{{desc.value}}</div>
</div>
</transition-group>
<top-list v-if="topList && topList.length !== 0" :list="topList" @itemClick="gotoProduct" @allClick="gotoBrand" />
<!-- 相关商品 -->
<top-list ref="topList" v-if="topList && topList.length !== 0" :list="topList" @itemClick="gotoProduct" @allClick="gotoBrand" />
<img class="ref-img" v-lazy="prdDetailTip"/>
</div>
... ... @@ -53,7 +57,7 @@
<div class="recommend" v-if="recommend"><h2>相关推荐</h2>
<product-list ref="recommendList" :list="recommend" priceKey="price" :yas-params="recommendYasParams"/>
</div>
</div>
</LayoutScroll>
<div class="footer">
<div class="fav">
<div class="icon-fav" @click="_toggleFav">
... ... @@ -240,6 +244,28 @@ export default {
immediate: true,
});
}
// yas
/**
* 商品详情页打开时
* XY_UFO_PRD_DT_INFO
* 1.FP_NAME:来源页面名称;eg:XY_UFOSearchList,XY_UFOSeriesList,XY_UFOBrandList、XY_UFOProductPoolList、UFOProductDetail_LIST等;
* 2.FP_PARAM:页面参数;搜索关键词,系列ID,品牌ID,商品池ID;
* 3.TAB_ID:tab切id,1-人气,2-价格,3-新品;
* 4.TAB_NAME:tab切名称,人气,价格,新品;
* 5.PRD_ID:商品id;
*/
this.$store.dispatch('reportYas', {
params: {
appop: 'XY_UFO_PRD_DT_INFO',
param: {
FP_NAME: `XY_${this.$route.name}`,
FP_PARAM: this.productId,
PRD_ID: this.productId,
...this.$route.params.yasParams
},
}
});
},
deactivated() {
if (this._resourceImgWatcher) {
... ... @@ -247,7 +273,7 @@ export default {
this._resourceImgWatcher = null;
}
},
beforeRouteUpdate(to, from ,next) {
beforeRouteUpdate(to, from, next) {
if (this.historyBackGuard() === false) {
return next(false);
}
... ... @@ -277,6 +303,49 @@ export default {
refresh() {
this.$refs.slide && this.$refs.slide.refresh && this.$refs.slide.refresh();
},
scrollEndHandler({y}) {
const scrollTop = Math.abs(y);
const pageScrollHeight = this.$refs.pageScroll.$el.offsetHeight;
// 相关商品
if (!this._topListYas && this.$refs.topList) {
if (this._topListTop === undefined) {
this._topListTop = this.$refs.topList.$el.offsetTop;
}
if (scrollTop < this._topListTop && (scrollTop + pageScrollHeight) > this._topListTop) {
const DATA = this.topList.slice(0, 3).map((value, i) => {
return {...this.recommendYasParams, I_INDEX: i, PRD_ID: value.id, PRD_SKN: value.id};
});
this.$store.dispatch('reportYas', {
params: {
param: {DATA},
appop: 'XY_UFO_SHOW_EVENT'
}
});
this._topListYas = true;
}
}
// 推荐商品
if (this._productItemHeight === undefined) {
let item = document.querySelector('.product-list-item');
if (item) {
this._productItemHeight = item.offsetHeight;
}
}
if (this.$refs.recommendList) {
const listTop = this.$refs.recommendList.$el.offsetTop;
const productListScrollTop = scrollTop + pageScrollHeight - listTop - this._productItemHeight;
if (productListScrollTop > 0) {
this.$refs.recommendList.yasShowEvent(productListScrollTop);
}
}
},
yasResourceVisible() {
/**
* 商品详情页中的资源位曝光
... ... @@ -675,7 +744,6 @@ export default {
i {
font-style: normal;
font-size: 36px;
vertical-align: text-bottom;
}
}
... ... @@ -781,11 +849,10 @@ export default {
width: 3em;
color: #888;
font-size: 22px;
line-height: 32px;
.icon-star-fill,
.icon-star-outline {
font-size: 48px;
font-size: 42px;
}
.icon-star-outline {
... ...
... ... @@ -59,7 +59,7 @@ export default function() {
list && list.map((item) => {
if (item.unReadCount > 0) {
state.showMsg = true;
}
}
});
},
},
... ...
... ... @@ -27,7 +27,7 @@ export default {
let [detail, resource, activity, recommend] = await Promise.all(queryTasks);
resource = get(resource, '[0].data[0]', null);
resource = get(resource, '[0].data[0]', {});
commit(Types.UPDATE_PRODUCT_DETAIL, Object.assign(detail.product_info, {
resource,
... ...
import Vue from 'vue';
import cookie from 'yoho-cookie';
import xianyu from '../common/xianyu';
const setWindowSize = (store) => {
const { clientWidth, clientHeight } = document.body;
... ... @@ -36,6 +38,44 @@ const initClient = (store) => {
img.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA';
};
function getUdid() {
return cookie.get('udid') || '';
}
window.appBaseLogs = {
status: [
{
ca: '',
lo: '',
cy: 'CN',
av: '',
udid: getUdid(),
ln: '',
ab: '',
sid: '',
net: '',
la: ''
}
],
device: {
res: '',
ifa: '',
mac: '',
osv: '',
ifv: '',
ps: '',
os: xianyu.isiOS ? 'iOS' : 'android',
ak: 'yoho-xianyu_' + (xianyu.isiOS ? 'iOS' : 'android'),
sv: '',
ch: '',
dm: '',
tdid: '',
afp: '',
udid: getUdid()
},
events: [{}]
};
export {
initClient
};
... ...
... ... @@ -65,7 +65,7 @@ module.exports = (app) => {
cookie: {
domain: 'yohobuy.com',
httpOnly: true,
maxAge: 1000 * 60 * 60 * 24 * 7 // 7
maxAge: 1000 * 60 * 60 * 24 * 30 // 30
},
store: new RedisStore(Object.assign(config.redis.session, {
logErrors: (e) => {
... ...
... ... @@ -121,8 +121,6 @@
s.parentNode.insertBefore(hm, s);
})();
}());
window.appBaseLogs = {events: [{}], device: {ak: '', udid: ''}, status: [{av: '', udid: '', sid: ''}]};
}, 500);
</script>
... ...
{
"name": "xianyu-ufo-app-web",
"version": "0.0.1-beta-39",
"version": "0.0.1-beta-40",
"private": true,
"description": "Xianyu Project With Express",
"repository": {
... ...