Authored by huangyCode

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

Showing 60 changed files with 2130 additions and 392 deletions
... ... @@ -80,7 +80,7 @@ const xianyu = {
pageName = 'List';
break;
case 'productDetail':
pageName = 'List';
pageName = 'ProductDetail';
break;
default:
break;
... ...
... ... @@ -19,6 +19,8 @@
<div class="coupon-time">{{item.coupon_validity}}</div>
</div>
<Check class="check" :value="item.selected === 'Y'"></Check>
<div class="time-up" v-if="item.is_expired_soon === 'Y'"></div>
</div>
</div>
</slot>
... ... @@ -115,6 +117,7 @@ export default {
align-items: center;
background: url(~statics/image/order/bg@3x.png) no-repeat;
background-size: cover;
position: relative;
}
.check {
... ... @@ -179,4 +182,15 @@ export default {
font-size: 22px;
color: #999;
}
.time-up {
background: url(~statics/image/coupon/time-up@3x.png) no-repeat;
background-size: cover;
position: absolute;
top: 0;
right: 0;
width: 80px;
height: 80px;
}
</style>
... ...
... ... @@ -35,7 +35,7 @@ export const sellerOrderStatusList = [
},
{
value: 5,
text: '交易完成',
text: '交易成功',
},
{
value: 6,
... ... @@ -50,10 +50,10 @@ export const buyerOrderStatusList = [
text: '全部',
},
// {
// value: 7,
// text: '求购',
// },
{
value: 7,
text: '求购',
},
{
value: 2,
text: '待付款',
... ...
... ... @@ -52,13 +52,14 @@ Vue.use(ConfirmDialog);
initClient(store);
xianyu.$router = router;
yoho.auth = async loginUrl => {
yoho.auth = async (args) => {
let { refer, loginUrl } = args || {};
let user = await sdk.getUser(true);
if (user && user.uid) {
return user;
} else {
cookie.set('third_backurl', location.href, {
cookie.set('third_backurl', refer || location.href, {
domain: '.yohobuy.com',
path: '/',
});
... ...
... ... @@ -27,9 +27,7 @@
:data-item="JSON.stringify(item)"
:data-add="0"
@click="toEditorPage"
>
编辑
</div>
>编辑</div>
</div>
<p class="address">{{ item.area }}{{ item.address }}</p>
</div>
... ... @@ -47,7 +45,10 @@
import Layout from "../../../components/layout/layout-app";
import { get } from "lodash";
import { Scroll, Loading } from "cube-ui";
import { SET_USER_ADDRESS_INFO } from "store/address/address/types";
import {
SET_USER_ADDRESS_INFO,
STORE_UPDATE_ADDRESS_INFO
} from "store/address/address/types";
import { createNamespacedHelpers } from "vuex";
const { mapState, mapMutations, mapActions } = createNamespacedHelpers(
... ... @@ -74,7 +75,7 @@ export default {
...mapState(["addressList"])
},
methods: {
...mapMutations({ SET_USER_ADDRESS_INFO }),
...mapMutations(["SET_USER_ADDRESS_INFO", "STORE_UPDATE_ADDRESS_INFO"]),
...mapActions(["fetchUserAddressList"]),
toOrderPage(item) {
this.SET_USER_ADDRESS_INFO(item);
... ... @@ -101,12 +102,12 @@ export default {
}
}
let addressInfo = JSON.parse(item || "{}");
Object.assign(addressInfo, { isUpdate: !isAdd, orderCode: "" });
this.STORE_UPDATE_ADDRESS_INFO(addressInfo);
this.$router.push({
name: "addressEdit",
params: {
item: item,
update: !isAdd
}
name: "addressEdit"
});
}
},
... ... @@ -155,17 +156,17 @@ export default {
display: flex;
padding-top: 40px;
padding-bottom: 44px;
padding-left: 28px;
padding-right: 40px;
align-items: center;
.check-item {
margin-left: 28px;
width: 40px;
height: 40px;
background: url(~statics/image/address/selected.png) no-repeat;
background-size: cover;
}
.uncheck-item {
margin-left: 28px;
width: 40px;
height: 40px;
background: url(~statics/image/address/unselected.png) no-repeat;
... ... @@ -173,65 +174,64 @@ export default {
}
.user-info {
flex-grow: 1;
overflow: hidden;
margin-left: 32px;
}
width: calc(100% - 140px);
.extra {
display: flex;
flex-direction: row;
.extra {
display: flex;
flex-direction: row;
.name {
font-size: 28px;
font-weight: 400;
color: #000000;
line-height: 40px;
}
.name {
font-size: 28px;
font-weight: 400;
color: #000000;
line-height: 40px;
}
.mobile {
display: block;
margin-left: 20px;
font-size: 28px;
font-weight: 400;
color: #000000;
line-height: 40px;
}
.mobile {
display: block;
margin-left: 20px;
font-size: 28px;
font-weight: 400;
color: #000000;
line-height: 40px;
}
.tag-btn {
width: 80px;
line-height: 44px;
font-size: 22px;
text-align: center;
background-color: #002b47;
margin-left: 18px;
color: white;
border-radius: 4px;
.tag-btn {
width: 80px;
line-height: 44px;
font-size: 22px;
text-align: center;
background-color: #002b47;
margin-left: 18px;
color: white;
border-radius: 4px;
}
.option-btn {
display: block;
width: 48px;
line-height: 44px;
letter-spacing: -0.29;
color: black;
font-size: 24px;
position: absolute;
right: 40px;
}
}
.option-btn {
display: block;
width: 48px;
line-height: 44px;
letter-spacing: -0.29;
color: black;
.address {
font-size: 24px;
position: absolute;
right: 40px;
line-height: 34px;
margin-top: 16px;
color: #999;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
}
.address {
width: 100%;
font-size: 24px;
line-height: 34px;
margin-top: 16px;
color: #999;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
}
.add-btn {
... ...
... ... @@ -40,7 +40,7 @@
></CInput>
</FormItem>
<!-- 订单修改地址隐藏 -->
<div v-if="!$route.params.code" class="wrapper-tag">
<div v-if="!orderCode" class="wrapper-tag">
<p class="tag-text">设置标签:</p>
<RadioGroup class="wrapper-radio">
<div v-for="(tag, index) in addressTags" :key="index">
... ... @@ -54,7 +54,7 @@
</RadioGroup>
</div>
<!-- 订单修改地址隐藏 -->
<div v-if="!$route.params.code" class="wrapper-del">
<div v-if="!orderCode" class="wrapper-del">
<Radio
class="radio"
:label="{ text: '设为默认地址', value: true }"
... ... @@ -104,7 +104,10 @@ export default {
return {
isShowProvince: false,
isUpdate: false,
updateMobileNum: "",
isMobileNumEdit: false,
title: "",
orderCode: "",
model: {
consignee: "",
address_id: "",
... ... @@ -117,8 +120,17 @@ export default {
}
};
},
watch: {
"model.mobile": function(val) {
if (val === this.updateMobileNum) {
this.isMobileNumEdit = false;
} else {
this.isMobileNumEdit = true;
}
}
},
computed: {
...mapState(["addressTags"]),
...mapState(["addressTags", "updateAddressInfo"]),
submitClass() {
return [
"sure-btn",
... ... @@ -142,13 +154,14 @@ export default {
"fetchAddressTags",
"addUserAddress",
"updateUserAddress",
"deleteUserAddress"
"deleteUserAddress",
"updateReceiptAddressInOrder"
]),
async onSubmit() {
let that = this;
let data = this.validator();
// 订单编辑地址
const orderCode = this.orderCode;
if (!data) {
return;
... ... @@ -158,7 +171,14 @@ export default {
if (this.isUpdate) {
//更新和添加地址接口不同
result = await this.updateUserAddress(data);
if (orderCode) {
result = await this.updateReceiptAddressInOrder({
...data,
orderCode
});
} else {
result = await this.updateUserAddress(data);
}
} else {
result = await this.addUserAddress(data);
}
... ... @@ -195,7 +215,7 @@ export default {
}
let reg;
if (this.isUpdate) {
if (this.isUpdate && !this.isMobileNumEdit) {
reg = /^[0123456789*]{11}$/;
} else {
reg = /^[0123456789]{11}$/;
... ... @@ -283,24 +303,27 @@ export default {
},
activated() {
let { update, title, item, code } = this.$route.params;
let addressInfo = this.updateAddressInfo;
this.isUpdate = addressInfo.isUpdate;
this.orderCode = addressInfo.orderCode;
this.title = addressInfo.isUpdate ? "编辑地址" : "添加地址";
// 订单编辑 不查标签
if (!code) {
if (!this.orderCode) {
this.fetchAddressTags();
}
this.isUpdate = update;
this.title = update ? "编辑地址" : "添加地址";
if (update) {
item = JSON.parse(item || "{}");
this.model.consignee = item.consignee;
this.model.address_id = item.address_id;
this.model.mobile = item.mobile;
this.model.area_code = item.area_code || item.areaCode;
this.model.area = item.area;
this.model.address = item.address;
this.model.tag_code = item.tag_code;
this.model.is_default = item.is_default === "Y" ? true : false;
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;
} else {
this.model = {};
}
... ...
... ... @@ -6,7 +6,7 @@ export default [
},
{
name: 'addressEdit',
path: '/xianyu/address/edit/:code?', // code 订单编码
path: '/xianyu/address/edit/:orderCode?', // code 订单编码
component: () => import(/* webpackChunkName: "address" */ './addressEdit'),
},
];
... ...
... ... @@ -85,11 +85,13 @@ export default {
}
},
goProductList(item) {
let query = {};
let key = item.linkType;
// console.log('===category=='+key);
query[key] = item.id;
this.$router.push({
name: 'List',
query: {
brand: item.id
},
query,
});
}
},
... ... @@ -115,14 +117,14 @@ export default {
}
.left-content {
width: 25%;
width: 30%;
height: 100%;
}
.right-content {
display: flex;
flex-direction: column;
width: 75%;
width: 70%;
height: 100%;
}
... ... @@ -140,6 +142,11 @@ export default {
font-size: 30px;
width: 100%;
text-align: center;
text-overflow: ellipsis;
-webkit-line-clamp: 1;
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
}
.category-left-item-select {
... ...
... ... @@ -9,6 +9,7 @@
@scroll="scrollHandler"
:options="options"
@pulling-up="onPullingUp"
@pulling-down="onPullingDown"
:data="productList.list">
<div class="channel-body" ref="body">
<div ref="topSource" class="channel-html">
... ... @@ -53,10 +54,15 @@ export default {
data() {
return {
options: {
bounce: {
top: false
},
pullUpLoad: true
// bounce: {
// top: false
// },
scrollbar: true,
pullUpLoad: true,
pullDownRefresh: true,
pullDownRefresh: {
txt: '刷新成功',
}
},
scrollEvents: ['scroll'],
scrollY: 0,
... ... @@ -129,7 +135,11 @@ export default {
this.params.isReset = false
await this.fetchProductList(this.params);
}
}
},
onPullingDown() {
this.params.isReset = true
this.fetchProductList(this.params);
},
},
components: {
Swiper,
... ...
<template>
<div>
<div ref='copy' class="btn" @click="onClick">
<div ref="copy" class="btn" @click="onClick">
立即邀请
</div>
</div>
</template>
<script>
import {createNamespacedHelpers} from 'vuex';
import { get } from 'lodash';
import Clipboard from 'clipboard';
import { createNamespacedHelpers } from "vuex";
import { get } from "lodash";
import Clipboard from "clipboard";
const {mapActions} = createNamespacedHelpers('gain');
const { mapActions } = createNamespacedHelpers("gain");
export default {
name: 'GainFooter',
name: "GainFooter",
data() {
return {
isUnionType: false,
shareUrl: 'https://activity.yoho.cn/feature/5475.html?share_id=8169&title=新人礼遇'
shareUrl:
"https://activity.yoho.cn/feature/5475.html?share_id=8169&title=新人礼遇"
};
},
mounted() {
... ... @@ -30,24 +31,23 @@ export default {
}
});
this.copyBtn.on('success', function() {
this.copyBtn.on("success", function() {
if (vm.isUnionType) {
vm.$createToast({
txt: '邀请链接已复制,快去粘贴吧~',
type: 'txt'
txt: "邀请链接已复制,快去粘贴吧~",
type: "txt"
}).show();
}
});
this.copyBtn.on('error', function() {
});
this.copyBtn.on("error", function() {});
this.fetchUnionStatus().then(result => {
this.isUnionType = get(result, 'data.unionType', false);
this.isUnionType = get(result, "data.unionType", false);
});
},
methods: {
...mapActions(['fetchUnionStatus']),
...mapActions(["fetchUnionStatus"]),
async onClick() {
let vm = this;
... ... @@ -61,24 +61,24 @@ export default {
if (!vm.isUnionType) {
this.$yoho.goNewPage({
url: 'http://m.yohobuy.com/activity/have-gain/apply?title=有货有赚介绍&openby:yohobuy={"action":"go.h5","params":{"title":"有货有赚介绍","url":"http://m.yohobuy.com/activity/have-gain/apply"}}'
url:
'http://m.yohobuy.com/activity/have-gain/apply?title=有货有赚介绍&openby:yohobuy={"action":"go.h5","params":{"title":"有货有赚介绍","url":"http://m.yohobuy.com/activity/have-gain/apply"}}'
});
return;
}
},
}
}
};
</script>
<style lang="scss" scoped>
.btn {
font-size: 32px;
width: 100%;
height: 98px;
line-height: 98px;
color: white;
text-align: center;
background: #444;
}
.btn {
font-size: 32px;
width: 100%;
height: 98px;
line-height: 98px;
color: white;
text-align: center;
background: #444;
}
</style>
... ...
... ... @@ -81,6 +81,11 @@ export default [
path: '/xianyu/channel',
component: () => import(/* webpackChunkName: "channel" */ './channel/channel')
},
{
name: 'home',
path: '/',
component: () => import(/* webpackChunkName: "channel" */ './channel/channel')
},
...news,
...Mine,
...Trade,
... ...
... ... @@ -33,7 +33,9 @@ export default {
break;
}
case 2: {
this.$yoho.auth().then((res) => {
this.$yoho.auth({
refer: '/xianyu/index/news'
}).then((res) => {
if(res) {
this.go('NewsPage');
}
... ... @@ -41,7 +43,9 @@ export default {
break;
}
case 3: {
this.$yoho.auth().then((res) => {
this.$yoho.auth({
refer: '/xianyu/index/mine'
}).then((res) => {
if(res) {
this.go('MinePage');
}
... ...
... ... @@ -3,8 +3,11 @@
<div class="news-list-title" v-if="isTitle">最新消息</div>
<ul class="news-list-content">
<li v-for="(item, key) in list" :key="key">
<div class="news-list-name">{{ item.content }}</div>
<div class="news-list-time">{{ item.createTime }}</div>
<LayoutLink :href="item.action || ''" class="img-link">
<div class="news-list-name">{{ item.content }}</div>
<div class="news-list-time">{{ item.createTime }}</div>
</LayoutLink>
</li>
</ul>
</div>
... ... @@ -32,7 +35,7 @@ export default {
<style lang="scss" scoped>
.news-list {
.news-list-title {
margin-top: 80px;
margin-top: 60px;
font-size: 40px;
color: #000000;
}
... ...
... ... @@ -37,7 +37,10 @@ export default {
.news-tab {
width: 100%;
overflow: hidden;
margin-top: 90px;
margin-top: 60px;
background: #F2F2F2;
border-radius: 16px;
padding: 40px 0;
.tab-item {
width: 33%;
float: left;
... ...
... ... @@ -53,7 +53,12 @@ export default {
methods: {
...mapActions(['fetchNewsList', 'fetchNewsTabList']),
async onPullingUp() {
await this.fetchNewsList();
if (!this.newsList.isMoreData ) return false;
let params = {
type: '',
isPage: false
};
await this.fetchNewsList(params);
this.$refs.scroll.forceUpdate();
}
},
... ...
... ... @@ -55,6 +55,7 @@ export default {
methods: {
...mapActions(['fetchNewsList']),
async onPullingUp() {
if (!this.newsDeatilList.isMoreData ) return false;
let params = {
type: this.type,
isPage: false
... ...
... ... @@ -9,13 +9,13 @@
<!--商品信息-->
<div class="productDetail">
<div class="productImageWrapper">
<!--<ImageFormat class="image" :lazy="lazy" :src="" :width="136" :height="180"></ImageFormat>-->
<ImageFormat class="image" :lazy="lazy" :src="originProductData.image" :width="136" :height="180"></ImageFormat>
</div>
<div class="productPrice">
<span class="size">{{sizeInfo}}</span>
<div class="pricedetail">
<span class="priceTitle">最低售价</span>
<span class="price">{{''}}</span>
<span class="priceTitle">最低售价: </span>
<span class="price">{{originProductData.least_price || '-'}}</span>
</div>
</div>
</div>
... ... @@ -23,49 +23,46 @@
<span class="inputViewIcon">
¥
</span>
<Input class="wordText" v-model="inputPrice" clearable="true" type="number" placeholder="定价需以9为结尾,例如1999"></Input>
<Input class="wordText" v-model="inputPrice" type="number" placeholder="定价需以9为结尾" @input="onTextChange"></Input>
</div>
<div>
<div class="sales">
<span class="tipHeaderText">需要支付保证金:</span>
<span class="tipPriceText">¥{{''}}</span>
<span class="tipPriceText">¥{{computeInfo.depositAmount}}</span>
</div>
</div>
<div class="saleDetailTips">
{{terms}}
{{configTip.tips}}
</div>
<div class="space"></div>
<div class="line"></div>
<div class="space"></div>
<div>
<span>商品金额:</span>
<span>{{''}}</span>
</div>
<div>
<span>运费:</span>
<span>{{''}}</span>
</div>
<div>
<span>预计实付金额:</span>
<span>{{''}}</span>
<div class="feeContainer" v-for="(item,index ) in computeInfo.promotionFormulaList">
<span :class="{'feeCommonText': true, 'feeTotalLeft':index === computeInfo.promotionFormulaList.length - 1}">{{item.promotion}}</span>
<span :class="{'feeCommonText': true, 'feeTotalRight':index === computeInfo.promotionFormulaList.length - 1}">{{item.promotionAmount}}</span>
</div>
<div class="space"></div>
<div class="line"></div>
<div class="space"></div>
<order-address></order-address>
<order-address :data="addressInfo"></order-address>
<div class="line"></div>
<div class="space"></div>
<day-choose></day-choose>
<day-choose :value="chooseDay" :options="dayOptions" :choose="BUYER_ASK_SET_CHOOSEDAY"></day-choose>
<div class="space"></div>
<div class="line"></div>
<div class="bottomContainer">
<Button type="submit" disabled="true">提交</Button>
<OrderAgree :value="isAgreeTerms" @input="isAgreeTerms = !isAgreeTerms" class="agree-wrapper"></OrderAgree>
<div>
<Button :disabled="!isAgreeTerms" type="submit" @click="submitClick">提交</Button>
</div>
</div>
</div>
... ... @@ -79,13 +76,19 @@
import {Input, Button} from 'cube-ui';
import OrderAddress from './components/confirm/address';
import DayChoose from './components/askorder/day-choose';
import OrderAgree from './components/confirm/agree';
import { createNamespacedHelpers } from 'vuex';
import {debounce, get} from 'lodash';
const {mapState, mapActions, mapMutations, mapGetters} = createNamespacedHelpers(
'order/buyerAskOrder'
);
export default {
name: 'BuyerAskOrder',
components: {Button, DayChoose, OrderAddress},
components: {Button, Input, DayChoose, OrderAddress, OrderAgree},
props: {
lazy: Boolean,
product: Object,
storageId: Number,
},
component: {
Input,
... ... @@ -95,18 +98,198 @@ export default {
data() {
return {
inputPrice: '',
terms: '求购须支付定金。\n卖家接单后,你需要在24小时内支付商品款。卖家将在你付款后36小时内发货。'
isAgreeTerms: false,
};
},
computed: {
...mapState([
'notFirstOrder',
'addressInfo',
'originProductData',
'configTip',
'computeInfo',
'isShowToast',
'toasMessage',
'chooseDay',
'isShowDialog',
'preTip',
'publishresult',
]),
...mapGetters([
'dayOptions',
'chooseDayId',
]),
sizeInfo: {
get() {
return '44'
// return goodsInfo ? goodsInfo.colorName + ',' + goodsInfo.sizeName : ''
return this.originProductData.colorName + ', ' + this.originProductData.sizeName + '码';// '黑色, 48码';
}
},
},
mounted() {
this.BUYER_ASK_SET_STORAGEID(this.storageId);
this.fetchBuyerOrderCount({ tabType: 'buy'});
this.fetchConfig();
this.$on("addressinfo", function (address) {
console.log(address)
})
},
watch: {
isShowToast(val) {
if (val) {
this.showToast();
}
},
isShowDialog(val) {
if (val) {
this.showDialog();
}
}
},
methods: {
...mapMutations([
'BUYER_ASK_SET_SHOWTOAST',
'BUYER_ASK_SET_CHOOSEDAY',
'BUYER_ASK_SET_SHOWDIALOG',
'BUYER_ASK_SET_STORAGEID',
]),
...mapActions([
'fetchConfig',
'fetchBuyerOrderCount',
'buyerCompute',
'buyerPrePublish',
'buyerPublish',
]),
onTextChange: debounce(function() {
if (this.originProductData.least_price && this.originProductData.skup && this.originProductData.least_price <= this.inputPrice) {
this.showBuyDialog();
} else {
this.buyerCompute({price: this.inputPrice, storage_id: this.storageId });
}
}, 500, {leading: false, trailing: true}),
showToast() {
this.BUYER_ASK_SET_SHOWTOAST(false);
this.$createToast({
time: 1000,
type: 'txt',
txt: this.toasMessage
}).show();
},
showBuyDialog() {
this.$createDialog({
type: 'confirm',
title: '求购价格过高',
content: '您的出价高于当前售价,建议直接购买',
confirmBtn: {
text: '去购买',
active: true,
disabled: false,
href: 'javascript:;',
},
cancelBtn: {
text: '取消',
active: false,
disabled: false,
href: 'javascript:;'
},
onConfirm: () => {
this.$router.push({
name: 'OrderBuyConfirm',
query: {
storageId: this.storageId || '',
skup: this.originProductData.skup || '',
productId: this.originProductData.productId || '',
},
});
},
onCancel: () => {
this.buyerCompute({price: this.inputPrice, storage_id: this.storageId });
}
}).show();
},
showDialog() {
this.BUYER_ASK_SET_SHOWDIALOG(false);
if (this.preTip) {
this.$createDialog({
type: 'confirm',
title: this.preTip.title || '',
content: this.preTip.content || `确认以${this.inputPrice}元的价格求购`,
confirmBtn: {
text: this.preTip.confirm,
active: true,
disabled: false,
href: 'javascript:;',
},
cancelBtn: {
text: this.preTip.cancel,
active: false,
disabled: false,
href: 'javascript:;'
},
onConfirm: () => {
this.publishProduct()
},
onCancel: () => {
}
}).show();
} else {
this.publishProduct()
}
},
submitClick() {
this.buyerPrePublish({price: this.inputPrice, storage_id: this.storageId, address_id: this.addressInfo.address_id});
},
publishProduct() {
this.buyerPublish({price: this.inputPrice, storage_id: this.storageId, address_id: this.addressInfo.address_id, time_limit_id: this.chooseDayId}).then(() => {
this.payOrder();
});
},
payOrder() {
let vm = this;
this.$createOrderPayType({
price: get(this.publishresult, 'depositAmount', ''),
desc: '保证金',
orderCode: get(this.publishresult, 'orderCode', ''),
extra: JSON.stringify({
type: 'buy',
back: {
name: 'ProductDetail',
params: {
productId: get(this.originProductData, 'productId', '')
}
},
forward: {
name: 'SellPayOk',
query: {
orderCode: get(this.publishresult, 'orderCode', ''),
}
}
}),
onCloseAction() {
// vm.onClose(orderResult.data.orderCode);
}
}).show();
}
}
};
</script>
... ... @@ -119,9 +302,10 @@ export default {
}
.topContainer {
height: calc(100% - 100px);
padding-left: 20px;
padding-right: 20px;
height: calc(100% - 100*2px);
padding-left: 20*2px;
padding-right: 20*2px;
margin-bottom: 200px;
}
.topView {
... ... @@ -135,50 +319,51 @@ export default {
.title {
font-weight: bold;
font-size: 34px;
font-size: 34*2px;
color: #000;
letter-spacing: 0.41px;
line-height: 41px;
margin-left: 20px;
margin-top: 5px;
letter-spacing: 0.41*2px;
line-height: 41*2px;
margin-left: 20*2px;
margin-top: 5*2px;
}
.productDetail {
display: flex;
flex-direction: row;
width: calc(100% - 40);
height: 120px;
margin-left: 20px;
width: calc(100% - 40*2px);
height: 120*2px;
margin-left: 20*2px;
align-items: center;
margin-top: 5px;
margin-top: 5*2px;
background-color: white;
}
.productImageWrapper {
width: 120px;
height: 120px;
width: 120*2px;
height: 120*2px;
background-color: white;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.productImage {
width: 110px;
height: 110px;
width: 110*2px;
height: 110*2px;
}
.productPrice {
width: calc(100% - 120px - 40px - 10px);
height: 120px;
margin-left: 10px;
width: calc(100% - 120*2px - 40*2px - 10*2px);
height: 120*2px;
margin-left: 10*2px;
}
.size {
margin-top: 37px;
margin-top: 37*2px;
font-family: "PingFang SC";
font-size: 12px;
font-size: 12*2px;
color: #999;
letter-spacing: 0;
}
... ... @@ -186,39 +371,39 @@ export default {
.pricedetail {
display: flex;
flex-direction: row;
height: 30px;
margin-top: 5px;
height: 30*2px;
margin-top: 5*2px;
align-items: flex-end;
}
.priceTitle {
font-family: "PingFang SC";
font-size: 14px;
font-size: 14*2px;
color: #000;
letter-spacing: 0;
}
.price {
font-family: "DIN Alternate";
font-size: 14px;
font-size: 14*2px;
color: #000;
line-height: 20.5px;
line-height: 20.5*2px;
letter-spacing: 0px;
}
.priceTip {
font-family: "PingFang SC";
font-size: 12px;
font-size: 12*2px;
color: #D0021B;
letter-spacing: 0px;
width: 80px;
width: 80*2px;
text-align: right;
}
.inputView {
width: calc(100% - 40px);
height: 50px;
border-radius: 5px;
width: calc(100%);
height: 50*2px;
border-radius: 5*2px;
display: flex;
flex-direction: row;
align-items: center;
... ... @@ -226,16 +411,18 @@ export default {
}
.inputViewIcon{
line-height: 50px;
font-size: 20px;
line-height: 50*2px;
font-size: 20*2px;
color: #000;
margin-left: 10px;
margin-left: 10*2px;
}
.wordText {
margin-left: 10px;
margin-left: 10*2px;
font-family: "DIN Alternate";
font-size: 16px;
font-size: 28*2px;
height: 100%;
line-height: 100%;
color: #000;
width: 100%;
background-color: transparent;
... ... @@ -249,59 +436,95 @@ export default {
.tipHeaderText {
font-family: "PingFang SC";
font-size: 14px;
font-size: 14*2px;
color:#000;
letter-spacing: 0;
margin-left: 20px;
margin-top: 15px;
//<!--margin-left: 20*2px;-->
margin-top: 15*2px;
}
.tipPriceText {
font-family: "PingFang SC";
font-size: 14px;
font-size: 14*2px;
color: #D0021B;
letter-spacing: 0;
margin-top: 15px;
margin-top: 15*2px;
}
.saleDetailTips {
font-family: "PingFang SC";
font-size: 12px;
font-size: 12*2px;
color: #999;
letter-spacing: 0px;
margin-top: 5px;
margin-left: 20px;
width: calc(100% - 40px);
margin-top: 5*2px;
//<!--margin-left: 20*2px;-->
width: calc(100% - 40*2px);
}
.space {
width: 100%;
background-color: white;
height: 20px;
height: 20*2px;
}
.line {
width: 100%;
height: 1px;
height: 1*2px;
background-color: #eee;
}
.priceCell {
display: flex;
width: 100%;
height: 25px;
height: 25*2px;
align-items: center;
justify-content: space-between;
}
.feeContainer {
display: flex;
align-items: center;
justify-content: space-between;
flex-direction: row;
margin-bottom: 6*2px;
}
.feeCommonText {
font-family: PingFang-SC-Regular;
font-size: 14*2px;
color: #999999;
letter-spacing: 0;
}
.feeTotalLeft {
font-family: PingFang-SC-Regular;
font-size: 14*2px;
color: #000000;
letter-spacing: 0;
}
.feeTotalRight {
font-family: PingFangSC-Regular;
font-size: 14px;
color: #D0021B;
letter-spacing: 0;
text-align: right;
}
.bottomContainer {
position: absolute;
bottom: 0px;
height: 100px;
display: flex;
align-items: stretch;
/*height: 100px;*/
width: 100%;
left: 0px;
}
.agree-wrapper {
height: 60px;
background-color: white;
border-top: 1px solid #eee;
padding: 0 40px;
line-height: 60px;
}
</style>
... ...
... ... @@ -143,7 +143,7 @@ export default {
compute() {
return this.computeOrder({
skup: this.productDetail.skup,
addressId: this.address.address_id,
addressId: this.address?.address_id,
couponCode: get(this.orderDetail, 'recommendedCouponInfo.coupon_code', ''),
promotionId: get(this.orderDetail, 'promotionTips.promotionIds', '')
}).then(result => {
... ...
... ... @@ -11,7 +11,7 @@
</div>
</div>
<Select
v-model="value"
v-model="chooseday"
:title="title"
:options="options"
@change="change"
... ... @@ -27,12 +27,37 @@ import {Select} from 'cube-ui';
export default {
name: 'DayChoose',
props: {
options: {
type: Array,
default: [],
},
value: {
type: String,
default: '',
},
choose: {
type: Function,
default: ()=>{},
}
},
components: {Select},
computed: {
chooseday: {
get() {
return this.value;
},
set(val) {
}
}
},
data() {
return {
options: ['1天', '3天', '7天', '15天', '30天'],
value: '7天',
// options: ['1天', '3天', '7天', '15天', '30天'],
// value: '7天',
title: '选择求购时限',
};
... ... @@ -40,6 +65,7 @@ export default {
methods: {
change(value, index, text) {
console.log('change', value, index, text);
this.choose && this.choose(value);
}
}
... ...
... ... @@ -38,7 +38,7 @@ export default {
this.$router.push({
name: 'address',
query: {
address_id: this.data.address_id
address_id: this.data?.address_id
}
});
}
... ...
... ... @@ -15,6 +15,7 @@ import { orderActionsMap, ownType } from "constants/order-constants";
import { createNamespacedHelpers } from "vuex";
const { mapActions } = createNamespacedHelpers("order/orderList");
const { mapMutations } = createNamespacedHelpers("address/address");
export default {
props: {
... ... @@ -35,13 +36,16 @@ export default {
"cancelTrade",
"confirmReceipt"
]),
...mapMutations(["STORE_UPDATE_ADDRESS_INFO"]),
onActionHandler(action) {
const { owner = ownType.SELL } = this.$route.params;
const {
orderCode,
priceInfo = {},
goodsInfo = {},
addressInfo = {}
// 订单类表和订单详情地址信息返回地段不一致
addressInfo,
userAddress
} = this.order;
const { productId, storageId, skup } = goodsInfo;
... ... @@ -77,7 +81,7 @@ export default {
case orderActionsMap.SHOW_EXPRESS.name:
this.$router.push({
name: "orderLogisticsInfo",
params: { owner, orderCode }
params: { owner, code: orderCode }
});
break;
// 调价
... ... @@ -106,16 +110,17 @@ export default {
break;
// 修改地址
case orderActionsMap.MODIFY_ADDRESS.name:
case orderActionsMap.MODIFY_ADDRESS.name: {
// 保存地址到store
let info = JSON.stringify(addressInfo || userAddress || {});
let updateInfo = JSON.parse(info || "{}");
Object.assign(updateInfo, { isUpdate: true, orderCode: orderCode });
this.STORE_UPDATE_ADDRESS_INFO(updateInfo);
this.$router.push({
name: "addressEdit",
params: {
code: orderCode,
update: true,
item: JSON.stringify(addressInfo)
}
name: "addressEdit"
});
break;
}
default:
this.$emit("on-action", action);
... ...
... ... @@ -15,8 +15,9 @@
isGoingOn && i === 0 ? 'content-wrapper active' : 'content-wrapper'
"
>
<p class="content">{{ deliveryDetail.acceptRemark }}</p>
<p class="remark">{{ deliveryDetail.acceptRemark }}</p>
<p class="time">{{ deliveryDetail.createTimeStr }}</p>
<slot name="content" :detail="deliveryDetail"></slot>
</div>
</li>
</ul>
... ... @@ -65,11 +66,11 @@ export default {
margin-top: -8px;
line-height: 1;
&.active {
&.active .remark {
color: #000;
}
.content {
.remark {
margin-bottom: 20px;
}
}
... ...
... ... @@ -52,6 +52,19 @@ export default [
name: 'buyerAskOrder', // 买家求购确认
path: '/xianyu/order/buyeraskorder.html',
component: () => import('./buyer-ask-order'),
props: route => ({
storageId: route.query.storageId
})
},
{
name: 'sellAskOrder', // 卖家求购确认
path: '/xianyu/order/selleraskorder.html',
component: () => import('./seller-ask-order'),
props: route => ({
skup: route.query.skup,
price: route.query.price,
})
},
// 物流信息
... ...
... ... @@ -48,6 +48,7 @@
<p>
<span class="label">订单编号:</span>
<span>{{ orderDetail.orderCode }}</span>
<i ref="copy" class="copy"></i>
</p>
<p v-if="orderDetail.paymentStr">
<span class="label">支付方式:</span>
... ... @@ -87,6 +88,7 @@
<script>
import { createNamespacedHelpers } from "vuex";
import { Button } from "cube-ui";
import Clipboard from "clipboard";
import AddressInfo from "./components/address-info";
import OrderItemInfo from "./components/order-detail-item";
... ... @@ -113,6 +115,19 @@ export default {
DetailHeader,
DetailFooter
},
activated() {
this.copyBtn = new Clipboard(this.$refs.copy, {
text: () => {
return this.orderDetail.orderCode;
}
});
this.copyBtn.on("success", () => {
this.$createToast({
txt: "复制成功",
type: "txt"
}).show();
});
},
asyncData({ store, router }) {
return store.dispatch(`${STORE_PATH}/fetchOrderDetail`, router.params);
},
... ... @@ -227,6 +242,15 @@ export default {
& > :first-child + p {
margin: 20px 0;
}
.copy {
width: 50px;
height: 25px;
display: inline-block;
background: url("~statics/image/order/copy@3x.png") no-repeat;
background-size: contain;
background-position: center;
}
}
.label {
... ...
... ... @@ -52,6 +52,7 @@
<p>
<span class="label">订单编号:</span>
<span>{{ orderDetail.orderCode }}</span>
<i ref="copy" class="copy"></i>
</p>
<p v-if="orderDetail.paymentStr">
<span class="label">支付方式:</span>
... ... @@ -96,6 +97,7 @@
<script>
import { createNamespacedHelpers } from "vuex";
import { Button } from "cube-ui";
import Clipboard from "clipboard";
import AddressInfo from "./components/address-info";
import OrderItemInfo from "./components/order-detail-item";
... ... @@ -125,6 +127,19 @@ export default {
asyncData({ store, router }) {
return store.dispatch(`${STORE_PATH}/fetchOrderDetail`, router.params);
},
activated() {
this.copyBtn = new Clipboard(this.$refs.copy, {
text: () => {
return this.orderDetail.orderCode;
}
});
this.copyBtn.on("success", () => {
this.$createToast({
txt: "复制成功",
type: "txt"
}).show();
});
},
computed: {
...mapState(["orderDetail"]),
...mapGetters([
... ... @@ -239,6 +254,15 @@ export default {
.trade-info {
font-size: 28px;
.copy {
width: 50px;
height: 25px;
display: inline-block;
background: url("~statics/image/order/copy@3x.png") no-repeat;
background-size: contain;
background-position: center;
}
& > p {
margin: 20px 0;
}
... ...
... ... @@ -11,8 +11,8 @@
</div>
<div class="item-info">
<div class="price-status">
<span v-if="order.realPrice" class="price"
>¥{{ order.realPrice }}</span
<span v-if="goodsInfo.goodPrice" class="price"
>¥{{ goodsInfo.goodPrice }}</span
>
<span class="order-status">{{ order.statuStr }}</span>
</div>
... ...
<template>
<layout-app title="物流详情">
<layout-app :title="logisticInfo.expressSender">
<div class="logistics-wrapper">
<div class="header">
<!-- <p class="title">{{ logisticInfo.expressSender }}</p> -->
<img class="step" alt="" :src="stageImgUrl" />
</div>
<div class="content">
<!-- 物流信息 -->
<div v-if="logisticInfo.wayBillCode" class="platform-delivery-info">
<div class="icon-wrapper">
<i class="icon"></i>
<i />
</div>
<div>
<div class="info">
<p>
<span>快递公司:</span>
<span class="label">快递公司:</span>
<span>
{{ logisticInfo.expressCompanyName }}
</span>
<span class="platform-info">{{ platformName }}</span>
<!-- <span class="platform-info">{{ platformName }}</span> -->
</p>
<p>
<span>快递单号:</span>
<span class="label">快递单号:</span>
<span>
{{ logisticInfo.wayBillCode }}
</span>
<i ref="copy" class="copy"></i>
</p>
</div>
</div>
... ... @@ -34,10 +34,43 @@
:key="i"
>
<span class="title">{{ detailInfo.title }}</span>
<time-line
:isGoingOn="i === 0"
:deliveryList="detailInfo.detailList"
/>
<time-line :isGoingOn="i === 0" :deliveryList="detailInfo.detailList">
<template #content="{detail: {miniFaultConfirm} }">
<div class="judge-content-wrapper" v-if="miniFaultConfirm">
<p class="tip">
{{ miniFaultConfirm.text }},
<span>
请在<count-down
:leftTime="miniFaultConfirm.leftTime"
:isShowIcon="false"
class="judge-count-down"
/>之前确定是否接受
</span>
</p>
<ul class="img-wrapper">
<li
v-for="(imgUrl, i) in miniFaultConfirm.imageUrls"
:key="i"
>
<ImageFormat
:data-secc="imgUrl"
:src="imgUrl"
alt=""
:width="70"
:height="70"
/>
</li>
<li v-if="miniFaultConfirm.imageUrls.length > 3">
<Button class="more">查看更多</Button>
</li>
</ul>
<div class="actions-wrapper">
<Button>不接受</Button>
<Button>接受,请发货</Button>
</div>
</div>
</template>
</time-line>
</div>
</div>
</div>
... ... @@ -48,24 +81,32 @@
import { createNamespacedHelpers } from "vuex";
import TimeLine from "./components/time-line";
import { expressTypeEnum } from "constants/logistics-constants";
import CountDown from "./components/count-down";
import { Button } from "cube-ui";
import Clipboard from "clipboard";
const STORE_PATH = "order/logisticsInfo";
const { mapActions, mapState, mapGetters } = createNamespacedHelpers(
STORE_PATH
);
const { mapActions, mapState } = createNamespacedHelpers(STORE_PATH);
export default {
components: {
TimeLine
TimeLine,
CountDown,
Button
},
computed: {
...mapState(["logisticInfo"]),
...mapGetters(["stageImgUrl"]),
platformName() {
const { expressType: type } = this.logisticInfo;
return expressTypeEnum[type];
},
stageImgUrl() {
const { stage } = this.logisticInfo;
return stage
? require(`../../statics/image/order/logistics_progress_${stage}@3x.png`)
: "";
},
detailList() {
const {
// 物流信息
... ... @@ -89,7 +130,7 @@ export default {
title: supplementExpressInfoDetailTitle,
detailList: supplementExpressInfoDetailList
}
].filter(item => !!item.title);
].filter(item => item.detailList.length > 0);
}
},
... ... @@ -98,14 +139,90 @@ export default {
},
methods: {
...mapActions(["fetchLogisticInfo"])
},
activated() {
this.copyBtn = new Clipboard(this.$refs.copy, {
text: () => {
return this.logisticInfo.wayBillCode;
}
});
this.copyBtn.on("success", () => {
this.$createToast({
txt: "复制成功",
type: "txt"
}).show();
});
}
};
</script>
<style lang="scss" scoped>
.logistics-wrapper {
height: 100vh;
height: calc(100vh - 90px);
-webkit-box-orient: vertical;
overflow-x: auto;
.judge-content-wrapper {
font-size: 24px;
color: #000;
line-height: 1.5;
margin-bottom: 20px;
.actions-wrapper {
display: flex;
margin-top: 60px;
button {
font-size: 28px;
background: #fff;
color: #000;
border-radius: 35px;
padding: 16px 36px 14px 36px;
width: 240px;
border: 1px solid #ccc;
line-height: 1.3;
&:last-child {
border: none;
background: #002b47;
color: #fff;
margin-left: 40px;
}
}
}
.tip {
margin-top: 20px;
margin-bottom: 10px;
}
.judge-count-down {
color: #d0021b;
font-size: 12px;
display: inline-block;
}
.img-wrapper {
// display: inline-block;
display: flex;
.more {
background: #fff;
font-size: 24px;
height: 100%;
width: 100%;
color: #999;
padding: 0;
}
li {
min-width: 3.5rem;
height: 3.5rem;
display: inline-block;
text-align: center;
}
}
}
.content {
padding: 0 40px;
... ... @@ -119,16 +236,47 @@ export default {
}
}
.icon-wrapper {
width: 48px;
height: 48px;
i {
display: block;
background: url("~statics/image/order/logistics-icon@3x.png") no-repeat;
background-size: contain;
width: 100%;
height: 100%;
&.sf {
background: url("~statics/image/order/sf-logo.png") no-repeat;
}
}
}
.platform-delivery-info {
display: flex;
align-items: center;
margin-bottom: 64px;
.icon-wrapper {
width: 48px;
background-color: red;
.copy {
width: 50px;
height: 25px;
display: inline-block;
background: url("~statics/image/order/copy@3x.png") no-repeat;
background-size: contain;
background-position: center;
}
.info {
margin-left: 20px;
.label {
color: #999;
padding-right: 10px;
}
.icon {
display: block;
padding-bottom: 100%;
& > :first-child {
margin-bottom: 10px;
}
}
}
... ...
<!--卖家求购变现-->
<template>
<LayoutApp :show-back="true">
<div class="body">
<TitleComp txt="变现"></TitleComp>
<ProductInfo :data="originProductData" class="product-info"></ProductInfo>
<div class="inputView">
<span class="inputViewIcon">
¥
</span>
<span class="wordText">{{price}}</span>
</div>
<OrderMargin class="order-item order-margin" :data="computeTip"></OrderMargin>
<OrderFee class="order-item" :data="computeTip"></OrderFee>
<AddressInfo :data="addressInfo" class="order-item"></AddressInfo>
</div>
<div class="footer">
<OrderAgree :value="isAgreeTerms" @input="isAgreeTerms = !isAgreeTerms" class="agree-wrapper"></OrderAgree>
<div>
<Button :disabled="!isAgreeTerms" type="submit" @click="submitClick">提交</Button>
</div>
</div>
</LayoutApp>
</template>
<script>
import {Button} from 'cube-ui';
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 {get} from 'lodash'
import { createNamespacedHelpers} from 'vuex';
const { mapState, mapActions, mapMutations, mapGetters} = createNamespacedHelpers(
'order/sellerAskOrder'
);
export default {
name: 'seller-ask-order',
props: {
skup: Number,
price: Number,
},
components: {
Button,
ProductInfo,
AddressInfo,
InputPrice,
TitleComp,
OrderMargin,
OrderFee,
OrderAgree
},
data() {
return {
isAgreeTerms: false,
};
},
computed: {
...mapState([
'originProductData',
// 'price',
'computeTip',
'addressInfo',
'publishinfo',
]),
...mapGetters([
]),
},
mounted() {
this.fetchSellerOrderCount({tabType: 'sell'});// 19268
this.sellerCompute({price: this.price, skup: this.skup});
},
watch: {
},
methods: {
...mapMutations([
]),
...mapActions([
'fetchSellerOrderCount',
'sellerCompute',
'sellerPublish',
]),
submitClick() {
this.sellerPublish({price: this.price, skup: this.skup, address_id: this.addressInfo.address_id})
.then(() => {
this.payOrder();
});
},
payOrder() {
let vm = this;
this.$createOrderPayType({
price: get(this.computeTip, 'earnestMoney', 0),
desc: '保证金',
orderCode: get(this.publishinfo, 'orderCode', ''),
extra: JSON.stringify({
type: 'sell',
back: {
name: 'ProductDetail',
params: {
productId: get(this.originProductData, 'productId', '')
}
},
forward: {
name: 'SellPayOk',
query: {
orderCode: get(this.publishinfo, 'orderCode', '')
}
}
}),
onCloseAction() {
// vm.onClose(orderResult.data.orderCode);
}
}).show();
}
}
};
</script>
<style lang="scss" scoped>
.body {
height: 100%;
margin: 0 40px;
padding-bottom: 200px;
overflow-y: auto;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
z-index: 1;
}
.inputView {
width: calc(100%);
height: 50*2px;
border-radius: 5*2px;
display: flex;
flex-direction: row;
align-items: center;
background-color: #f5f5f5;
}
.inputViewIcon{
line-height: 50*2px;
font-size: 20*2px;
color: #000;
margin-left: 10*2px;
}
.wordText {
margin-left: 10*2px;
font-family: "DIN Alternate";
font-size: 28*2px;
height: 50*2px;
line-height: 50*2px;
color: #000;
width: 100%;
background-color: transparent;
}
.agree-wrapper {
height: 60px;
background-color: white;
border-top: 1px solid #eee;
padding: 0 40px;
line-height: 60px;
}
.order-item {
padding-top: 40px;
padding-bottom: 40px;
}
.order-item + .order-item {
border-top: 1px solid #eee;
}
</style>
... ...
... ... @@ -82,7 +82,7 @@ export default {
},
compute() {
return this.fetchOrderPrice({
address_id: this.address.address_id,
address_id: this.address?.address_id,
num: this.num,
price: this.price,
storage_id: this.storageId,
... ...
... ... @@ -8,7 +8,12 @@
v-show="isVisible"
@mask-click="maskClick">
<transition :name="transition" appear>
<div class="cube-action-sheet-panel" v-show="isVisible" @click.stop>
<div class="cube-action-sheet-panel"
:class="{'with-radius': hasBorderRadius, [`panel-${position}`]: true}"
:style="panelStyle"
v-show="isVisible"
ref="panel"
@click.stop="fakeMask">
<slot></slot>
</div>
</transition>
... ... @@ -26,6 +31,20 @@ export default {
type: String,
default: 'bottom',
},
panelStyle: {
type: Object,
default() {
return {};
},
},
hasBorderRadius: {
type: Boolean,
default: true,
},
emulateMask: {
type: Boolean,
default: false,
},
},
data() {
return {
... ... @@ -59,7 +78,12 @@ export default {
this._shownCallback();
});
}
}
},
fakeMask(e) {
if (this.emulateMask && e.target === this.$refs.panel) {
this.hide();
}
},
},
components: {
'cube-popup': Popup,
... ... @@ -95,6 +119,14 @@ export default {
z-index: -1;
background: #fff;
}
&.panel-right:after {
width: 100px;
height: 100%;
left: auto;
bottom: auto;
top: 0;
right: -100px;
}
}
.cube-action-sheet-bottom-enter, .cube-action-sheet-bottom-leave-active {
... ...
<template>
<action-sheet @hidden="onHidden" position="right" ref="popup">
<action-sheet @hidden="onHidden" position="right" ref="popup"
:panelStyle="{background: 'transparent', paddingLeft: '20%'}"
:hasBorderRadius="false"
:emulateMask="true">
<div class="buy-sheet">
<div class="header">
<div class="back-wrapper flex" @touchend="onBack">
<div class="back"></div>
</div>
</div>
<div class="header">求购<i class="cubeic-question"></i></div>
<div class="title">
<div class="title-thumbnail">
<square-img :src="imageUrl" :width="300" :height="300"/>
</div>
<div>选择尺码填写理想的价格发布求购</div>
<div>{{productDetail.product_name}} {{goodsName}}</div>
</div>
<div class="size-list">
... ... @@ -17,7 +17,7 @@
<ul>
<li :class="['size-item', item.available ? '': 'disable']" 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">最高求购价 ¥{{item.price}} <i class="cubeic-arrow"></i></div>
</li>
</ul>
</cube-scroll>
... ... @@ -29,16 +29,19 @@
<script>
import { Scroll } from 'cube-ui';
import { get } from 'lodash';
import { createNamespacedHelpers } from 'vuex';
import { createNamespacedHelpers, mapActions } from 'vuex';
import ActionSheet from './action-sheet';
import stateShortCutsMixins from '../mixins';
import SquareImg from './square-img';
const { mapActions, mapGetters } = createNamespacedHelpers('product');
const { mapActions: mapProductAction } = createNamespacedHelpers('product');
export default {
name: 'BuySheet',
props: {
productId: Number,
},
mixins: [stateShortCutsMixins],
components: {
SquareImg,
... ... @@ -46,16 +49,15 @@ export default {
'cube-scroll': Scroll,
},
computed: {
...mapGetters(['productDetail']),
sizeList() {
return get(this.productDetail, 'goods_list_tabs.goods_list[0].size_list', []);
return get(this.productDetail, 'goods_list[0].size_list', []);
},
sizeViewList() {
return this.sizeList.map(info => {
let price;
if (info.least_price > 0) {
price = `${info.least_price}`;
if (info.bid_moster_price > 0) {
price = `${info.bid_moster_price}`;
} else {
price = '-';
}
... ... @@ -69,6 +71,7 @@ export default {
price,
storage_id: info.storage_id,
available: info.storage_num > 0 && price !== '-',
skup: info.skup,
};
});
},
... ... @@ -83,26 +86,49 @@ export default {
this.$refs.popup.show();
},
methods: {
...mapActions(['updateTradeInfo']),
...mapActions('order/buyerAskOrder', [
'BUYER_ASK_SET_PRODUCTINFO'
]),
...mapProductAction(['updateTradeInfo']),
onHidden() {
this.$emit('hidden');
},
buy(product) {
if (!product.available) {
return;
}
this.onBack();
this.updateTradeInfo({
productId: this.productDetail.product_id,
sizeInfo: product,
}).then((data) => {
this.$router.push({
name: 'OrderBuyConfirm',
query: data,
});
});
this.$yoho.auth()
.then(() => {
this.hide();
this.updateTradeInfo({
productId: this.productDetail.product_id,
sizeInfo: product,
}).then((data) => {
/**
* 跳转到求购确认页面
* data:
* productId: number
* sizeId: number
* storageId: number
*/
this.$store.commit('order/buyerAskOrder/BUYER_ASK_SET_PRODUCTINFO', {
least_price: this.productDetail.least_price,
sizeName: product.name,
sizeId: get(data, 'sizeId', ''),
colorName: get(this.productDetail, 'goods_list[0].color_name', ''),
product_name: this.goodsName,
productId: get(data, 'productId', ''),
image: this.imageUrl,
skup: product.skup,
})
this.$router.push({
name: 'buyerAskOrder',
query: {
storageId: data.storageId || ''
},
});
});
})
},
onBack() {
hide() {
this.$refs.popup.hide();
},
},
... ... @@ -117,54 +143,39 @@ export default {
display: flex;
flex-direction: column;
position: relative;
.size-list {
flex: 1;
padding: 10px 40px;
overflow: scroll;
}
padding: 0 40px;
background: #fff;
}
.title-thumbnail {
width: 140px;
height: 140px;
margin: 0 auto;
display: block;
.size-list {
flex: 1 0 100%;
overflow: hidden;
}
.header {
width: 100%;
height: 90px;
padding-left: 40px;
padding-right: 40px;
display: flex;
justify-content: flex-end;
align-items: stretch;
box-sizing: border-box;
position: absolute;
top: 0;
right: 40px;
line-height: 88px;
font-size: 28px;
color: #999;
letter-spacing: 0;
text-align: right;
}
.flex {
display: flex;
align-items: center;
}
.back-wrapper {
height: 100%;
}
.back {
width: 48px;
height: 48px;
background: url(~statics/image/address/close.png) no-repeat;
background-size: cover;
}
.title-thumbnail {
width: 200px;
height: 200px;
margin: 0 auto;
display: block;
}
.title {
padding: 20px 40px 80px;
font-size: 24px;
color: #999;
letter-spacing: 0;
text-align: center;
font-weight: bold;
font-size: 0.9em;
border-bottom: 1px solid #ddd;
padding-bottom: 28px;
}
.size-item {
... ... @@ -172,17 +183,14 @@ export default {
justify-content: space-between;
align-items: center;
color: #000;
font-size: 32px;
padding: 40px;
margin-bottom: 40px;
border-bottom: 1px solid #ddd;
line-height: 120px;
border-bottom: 1px solid #eee;
.size {
line-height: 1.8;
display: flex;
font-size: 1.3em;
font-weight: bold;
align-items: baseline;
font-size: 40px;
letter-spacing: 0;
span:nth-child(2) {
font-size: 0.8em;
... ... @@ -194,15 +202,20 @@ export default {
.price {
display: flex;
align-items: center;
font-size: 24px;
letter-spacing: 0;
text-align: right;
i {
display: inline-block;
margin-left: 5px;
color: #999;
color: #888;
}
}
&.disable {
.size, .price {
.size,
.price {
color: #999;
}
}
... ...
... ... @@ -26,8 +26,10 @@
@select="onSelectSize"
@add="onAdd" />
<transition name="slide-up">
<div class="footer" v-if="isTradable">
<cube-button @click="select" class="active">{{config.title}}</cube-button>
<div class="footer" v-if="isAvailable">
<cube-button v-if="config.type === 'sell'" @click="convertToCash" :class="{active: isMarketable}">变现<span> <i>¥</i>{{cashPrice}}</span></cube-button>
<cube-button @click="select" :class="{active: isTradable}">{{config.title}}</cube-button>
</div>
</transition>
</div>
... ... @@ -38,13 +40,13 @@
<script>
import { Scroll, Button } from 'cube-ui';
import { get } from 'lodash';
import { createNamespacedHelpers } from 'vuex';
import { createNamespacedHelpers, mapActions } from 'vuex';
import ActionSheet from './action-sheet';
import SizeList from './size-list';
import SquareImg from './square-img';
const { mapActions, mapState } = createNamespacedHelpers('product');
const { mapActions: mapProductActions, mapState } = createNamespacedHelpers('product');
export default {
name: 'SizeSelectSheet',
... ... @@ -113,12 +115,34 @@ export default {
(this.config.type === 'buy' && this.selectedSize.storage_num > 0 && this.selectedSize.least_price !== '-') ||
(this.config.type === 'sell'));
},
/**
* 变现价格,使用bid_moster_price
*/
cashPrice() {
if (this.selectedSize && this.selectedSize.hasOwnProperty('bid_moster_price')) {
return this.selectedSize.bid_moster_price;
}
return '-';
},
/**
* 可变现
* 通过bid_moster_price或bid_skup判断
*/
isMarketable() {
return this.cashPrice > 0;
}
},
mounted() {
this.$refs.popup.show();
},
methods: {
...mapActions(['updateTradeInfo']),
...mapActions('order/sellerAskOrder', [
'SELLER_ASK_SET_PRODUCTINFO'
]),
...mapProductActions(['updateTradeInfo']),
onHidden() {
this.$emit('hidden');
},
... ... @@ -145,6 +169,37 @@ export default {
bid_skup: this.selectedSize.bid_skup,
});
},
convertToCash() {
if (!this.isMarketable) {
return;
}
this.hide();
if (get(this.selectedSize, 'bid_skup', 0) == 0) {
return;
}
this.$yoho.auth()
.then(() => {
this.$store.commit('order/sellerAskOrder/SELLER_ASK_SET_PRODUCTINFO',{
goodImg: get(this.product, 'goods_list[0].image_list[0].image_url', ''),
colorName: get(this.product, 'goods_list[0].color_name', ''),
sizeName: this.sizeName,
goodPrice: get(this.productDetail, 'least_price', 0),
productId: this.product.product_id
});
// 跳转变现
this.$router.push({
name: 'sellAskOrder',
query: {
skup: get(this.selectedSize, 'bid_skup', 0),
price: get(this.selectedSize, 'bid_moster_price', 0),
}
});
});
},
},
};
</script>
... ...
... ... @@ -21,6 +21,7 @@
<span class="dot" :class="{active: props.current === index}" v-for="(item, index) in props.dots">{{index + 1}}</span>
</template>
</cube-slide>
<div class="qiugou" @click="qiugou"></div>
</div>
<div class="info">
... ... @@ -87,7 +88,7 @@
@select="onSelectTradeProduct"
@add="onRequestSize"/>
<size-request-sheet v-if="showSizeRequestSheet" @hidden="onSizeRequestHidden"/>
<buy-sheet v-if="showBuySheet" @hidden="onBuyHidden"/>
<buy-sheet v-if="showBuySheet" @hidden="onBuyHidden" :productId="productId"/>
</div>
</template>
... ... @@ -284,7 +285,6 @@ export default {
},
async sell() {
await this.$yoho.auth();
this.selectSizeConfig = {
dest: 'OrderSellConfirm',
type: 'sell',
... ... @@ -350,7 +350,12 @@ export default {
onSizeRequestHidden() {
this.showSizeRequestSheet = false;
},
qiugou() {
this.showBuySheet = true;
},
onBuyHidden() {
this.showBuySheet = false;
},
},
};
</script>
... ... @@ -393,6 +398,16 @@ export default {
background-color: #08304b;
}
}
.qiugou {
position: absolute;
top: 0;
right: 58px;
width: 58px;
height: 48px;
background: top left url("~statics/image/product/qiugou@3x.png") no-repeat;
background-size: 100% 100%;
}
}
.cube-slide-item {
... ...
/* eslint-disable no-unused-vars */
import * as Types from './types';
import {
get
} from 'lodash';
import { get } from 'lodash';
export default {
// 获取用户地址列表
async fetchUserAddressList({
commit
}) {
async fetchUserAddressList({ commit }) {
const result = await this.$api.get('/api/address/gethidden');
if (result.code === 200) {
commit(Types.FETCH_USER_ADDRESS_LIST, {
list: get(result, 'data', [])
list: get(result, 'data', []),
});
}
},
// 获取地址标签
async fetchAddressTags({
commit
}) {
async fetchAddressTags({ commit }) {
const result = await this.$api.get('/api/address/getTags');
if (result.code === 200) {
commit(Types.FETCH_ADDRESS_TAGS, {
list: get(result, 'data', [])
list: get(result, 'data', []),
});
}
},
async fetchAddressProvinces({
commit
}, id) {
async fetchAddressProvinces({ commit }, id) {
let result = {};
try {
... ... @@ -48,9 +40,7 @@ export default {
},
// 添加、更新、删除地址,post请求
async addUserAddress({
commit
}, data) {
async addUserAddress({ commit }, data) {
const result = await this.$api.post('/api/address/addAddress', {
address: data.address,
area_code: data.area_code,
... ... @@ -63,9 +53,7 @@ export default {
return result || {};
},
async updateUserAddress({
commit
}, data) {
async updateUserAddress({ commit }, data) {
const result = await this.$api.post('/api/address/updateAddress', {
id: data.id,
address: data.address,
... ... @@ -79,9 +67,7 @@ export default {
return result || {};
},
async deleteUserAddress({
commit
}, addressId) {
async deleteUserAddress({ commit }, addressId) {
const result = await this.$api.post('/api/address/delAddress', {
id: addressId,
});
... ... @@ -90,9 +76,7 @@ export default {
},
// 设置默认地址, post请求 ---- 暂时用不到这个
async setDefaultAddress({
commit
}) {
async setDefaultAddress({ commit }) {
const result = await this.$api.post('/api/address/setDefaultAddress');
if (result.code === 200) {
... ... @@ -101,4 +85,31 @@ export default {
return result || {};
},
// 订单更新收货地址
async updateReceiptAddressInOrder({ commit }, data) {
const {
address,
area,
consignee,
mobile,
orderCode,
area_code: areaCode,
} = data;
const res = await this.$api.get('/api/buyer/modifyAddress', {
tabType: 'buy',
orderCode,
mobile,
areaCode,
consignee,
address,
area,
});
const { code, message } = res || {};
if (code === 200) {
res.message = message || '修改成功';
}
return res || {};
},
};
... ...
... ... @@ -8,7 +8,8 @@ export default function () {
addressList: [],
addressTags: [],
provincesList: [],
addressInfo: {}
addressInfo: {},
updateAddressInfo: {}
},
actions,
mutations,
... ...
... ... @@ -21,5 +21,10 @@ export default {
// 修改根状态
this.state.order.orderConfirm.address = addressInfo;
this.state.order.buyerAskOrder.addressInfo = addressInfo;
this.state.order.sellerAskOrder.addressInfo = addressInfo;
},
[Types.STORE_UPDATE_ADDRESS_INFO](state, addressInfo) {
state.updateAddressInfo = addressInfo || {};
}
};
... ...
... ... @@ -9,3 +9,4 @@ export const DELETE_USER_ADDRESSINFO_SUCCESS = 'DELETE_USER_ADDRESSINFO_SUCCESS'
export const SET_DEFAULT_ADDRESS = 'SET_DEFAULT_ADDRESS';
export const SET_USER_ADDRESS_INFO = 'SET_USER_ADDRESS_INFO';
export const STORE_UPDATE_ADDRESS_INFO = 'STORE_UPDATE_ADDRESS_INFO';
... ...
... ... @@ -11,6 +11,7 @@ export default function() {
page: 0,
limit: 10,
totalPage: 0,
isMoreData: true,
},
newsDeatilList: {
list: [],
... ... @@ -18,6 +19,7 @@ export default function() {
page: 0,
limit: 10,
totalPage: 0,
isMoreData: true,
}
},
mutations: {
... ... @@ -25,12 +27,14 @@ export default function() {
state.newsList.list = state.newsList.list.concat(list.list);
state.newsList.page = list.page;
state.newsList.totalPage = list.totalPage;
list.page < list.totalPage ? state.newsList.isMoreData = true : state.newsList.isMoreData = false;
},
[Types.FETCH_NEWSDETAIL_LIST](state, { list }) {
state.newsDeatilList.list = list.page > 1 ? state.newsDeatilList.list.concat(list.list) : list.list;
state.newsDeatilList.page = list.page;
state.newsDeatilList.totalPage = list.totalPage;
list.page < list.totalPage ? state.newsDeatilList.isMoreData = true : state.newsDeatilList.isMoreData = false;
},
[Types.FETCH_NEWS_TAB_LIST](state, { list }) {
... ... @@ -39,7 +43,6 @@ export default function() {
},
actions: {
async fetchNewsList({ commit, state }, obj) {
console.log(obj);
let page = state.newsList.page + 1;
let limit = state.newsList.limit;
let totalPage = state.newsList.totalPage;
... ... @@ -49,7 +52,7 @@ export default function() {
// 页面跳转重置page页码
isPage ? page = 1 : state.newsList.page + 1;
const result = await this.$api.post('/api/ufo/home/newsList', {
page, type, limit
page, type: type || '', limit, uid: 500031928
});
if (result.code === 200) {
... ...
/**
* buyer-ask-order.js
*@author dennis
*@createtime 9/25/19
*@description 买家求购状态管理
*/
import {Types} from './types';
import {
get
} from 'lodash';
const {
BUYER_ORDERCOUNT_REQUEST,
BUYER_ORDERCOUNT_SUCCESS,
BUYER_ORDERCOUNT_FAILURE,
BUYER_ADDRESS_REQUEST,
BUYER_ADDRESS_SUCCESS,
BUYER_ADDRESS_FAILURE,
BUYER_ASK_CONFIG_SUCCESS,
BUYER_ASK_CONFIG_FAILURE,
BUYER_ASK_COMPUTE_REQUEST,
BUYER_ASK_COMPUTE_SUCCESS,
BUYER_ASK_COMPUTE_FAILURE,
BUYER_ASK_PREPUBLISH_SUCCESS,
BUYER_ASK_PREPUBLISH_FAILURE,
BUYER_ASK_PREPUBLISH_REQUEST,
BUYER_ASK_PUBLISH_REQUEST,
BUYER_ASK_PUBLISH_SUCCESSS,
BUYER_ASK_PUBLISH_FAILURE,
BUYER_ASK_SET_SHOWTOAST,
BUYER_ASK_SET_CHOOSEDAY,
BUYER_ASK_SET_SHOWDIALOG,
BUYER_ASK_SET_STORAGEID,
BUYER_ASK_SET_PRODUCTINFO,
} = Types;
const TIP = '请求失败';
const DEFAULT_COMPUTE_INFO = {
depositAmount: '0',
promotionFormulaList: [
{
promotion: '商品金额',
promotionAmount: '¥-'
},
{
promotion: '运费',
promotionAmount: '¥-'
},
{
promotion: '实付金额',
promotionAmount: '¥-'
}
]
};
const DEFUALT_CONFIG_TIP = {
timeLimit: {
defaultItem: {
desc: '7天',
id: 3
},
items: [
{
desc: '1天',
id: 1
},
{
desc: '3天',
id: 2
},
{
desc: '7天',
id: 3
},
{
desc: '15天',
id: 4
},
{
desc: '30天',
id: 5
}
]
},
tips: '求购须支付定金。卖家接单后,你需要在24小时内支付商品款。卖家将在你付款后36小时内发货。'
};
const TEST_PRODUCT_INFO = {
least_price: 1119.00,
max_price: 20000.00,
max_sort_id: 10,
min_price: 0.01,
offer_price: 200.00,
product_code: 'OMRG001S181851110112',
product_id: 10000068,
product_name: 'Timberland 红色女靴',
sale_time: '2016.01.01',
image: 'http://img11.static.yhbimg.com/goodsimg/2018/10/18/17/0124eed582cab20be7047c796c314cbc76.jpg?imageMogr2/thumbnail/{width}x{height}/background/d2hpdGU=/position/center/quality/80'
};
export default function() {
return {
namespaced: true,
state: {
notFirstOrder: false,
storageId: '10000130',
originProductData: TEST_PRODUCT_INFO,
addressInfo: null,
configTip: DEFUALT_CONFIG_TIP,
iscomputefetch: false,
isprepublish: false,
ispublish: false,
computeInfo: DEFAULT_COMPUTE_INFO,
preTip: null,
publishresult: {},
toasMessage: '',
isShowToast: false,
chooseDay: '7天',
isShowDialog: false,
},
getters: {
dayOptions(state) {
let orginallist = get(state, ['configTip', 'timeLimit', 'items'], []);
return orginallist.map(item => {
return get(item, ['desc'], '');
});
},
chooseDayId(state) {
let orginallist = get(state, ['configTip', 'timeLimit', 'items'], []);
let dayid = 3;
orginallist.forEach(item => {
if (item.desc === state.chooseDay) {
dayid = item.id;
}
});
return dayid;
},
},
mutations: {
[BUYER_ASK_SET_PRODUCTINFO](state, payload) {
state.originProductData = payload
},
[BUYER_ASK_SET_STORAGEID](state, payload) {
state.storageId = payload
},
[BUYER_ASK_SET_SHOWTOAST](state, payload) {
state.isShowToast = payload ? true : false;
},
[BUYER_ASK_SET_SHOWDIALOG](state, payload) {
state.isShowDialog = payload ? true : false;
},
[BUYER_ASK_SET_CHOOSEDAY](state, payload) {
state.chooseDay = payload;
},
[BUYER_ORDERCOUNT_REQUEST](state) {
},
[BUYER_ORDERCOUNT_SUCCESS](state, data) {
state.notFirstOrder = get(data, ['cnt'], 0) > 0;
},
[BUYER_ORDERCOUNT_FAILURE](state, message) {
},
[BUYER_ADDRESS_REQUEST]() {
},
[BUYER_ADDRESS_SUCCESS](state, payload) {
let list = payload || [];
let defaultAddress;
list.forEach(item => {
if (item.is_default === 'Y') {
defaultAddress = item;
}
});
state.addressInfo = defaultAddress;
},
[BUYER_ADDRESS_FAILURE]() {
},
[BUYER_ASK_CONFIG_SUCCESS](state, payload) {
state.configTip = payload;
},
[BUYER_ASK_CONFIG_FAILURE](state, payload) {
},
[BUYER_ASK_COMPUTE_REQUEST](state) {
state.iscomputefetch = true;
},
[BUYER_ASK_COMPUTE_SUCCESS](state, payload) {
state.iscomputefetch = false;
state.computeInfo = payload;
},
[BUYER_ASK_COMPUTE_FAILURE](state, payload) {
state.iscomputefetch = false;
state.computeInfo = DEFAULT_COMPUTE_INFO;
state.toasMessage = payload;
state.isShowToast = true;
},
[BUYER_ASK_PREPUBLISH_REQUEST](state) {
state.isprepublish = true;
},
[BUYER_ASK_PREPUBLISH_SUCCESS](state, payload) {
state.isprepublish = false;
if (payload) {
state.preTip = payload;
} else {
state.preTip = null;
}
state.isShowDialog = true;
},
[BUYER_ASK_PREPUBLISH_FAILURE](state, payload) {
state.isprepublish = false;
state.preTip = null;
state.toasMessage = payload;
state.isShowToast = true;
},
[BUYER_ASK_PUBLISH_REQUEST](state) {
state.ispublish = true;
},
[BUYER_ASK_PUBLISH_SUCCESSS](state, payload) {
state.ispublish = false;
state.publishresult = payload;
},
[BUYER_ASK_PUBLISH_FAILURE](state, payload) {
state.ispublish = false;
state.publishresult = {};
state.toasMessage = payload;
state.isShowToast = true;
}
},
actions: {
fetchBuyerOrderCount({commit, dispatch}, {tabType = 'buy', uid} = {}) {
commit(BUYER_ORDERCOUNT_REQUEST);
this.$api.get('/api/order/ordercount', {
tabType,
uid
}).then(result => {
if (result.code === 200) {
commit(BUYER_ORDERCOUNT_SUCCESS, result.data);
if (get(result, ['data', 'cnt'], 0) > 0) {
dispatch('fetchAddress', {});
} else {
console.log('first order');
}
} else {
commit(BUYER_ORDERCOUNT_FAILURE, result.message);
}
}, error => {
commit(BUYER_ORDERCOUNT_FAILURE, '');
console.log(error);
});
},
fetchAddress({commit}, {uid} = {}) {
commit(BUYER_ADDRESS_REQUEST);
this.$api.get('/api/address/gethidden', {
uid
}).then(result => {
if (result.code === 200) {
commit(BUYER_ADDRESS_SUCCESS, result.data);
} else {
commit(BUYER_ADDRESS_FAILURE, result.message);
}
}, error => {
commit(BUYER_ADDRESS_FAILURE, '');
console.log(error);
});
},
fetchConfig({commit}, {} = {}) {
this.$api.get('/api/order/buyaskconfig', {
}).then(result => {
if (result.code === 200) {
commit(BUYER_ASK_CONFIG_SUCCESS, result.data);
} else {
console.log(result);
}
}, error => {
console.log(error);
});
},
buyerCompute({commit}, {price = 0, storage_id = 0, uid} = {}) {
commit(BUYER_ASK_COMPUTE_REQUEST);
this.$api.get('/api/order/buyeraskcompute', {
uid,
price,
storage_id,
}).then(result => {
if (result.code === 200) {
commit(BUYER_ASK_COMPUTE_SUCCESS, get(result, ['data'], {}));
} else {
commit(BUYER_ASK_COMPUTE_FAILURE, get(result, ['message'], TIP));
}
}, error => {
console.log(error);
commit(BUYER_ASK_COMPUTE_FAILURE, TIP);
});
},
buyerPrePublish({commit, dispatch}, {price = 0, storage_id = 0, uid, address_id = ''} = {}) {
commit(BUYER_ASK_PREPUBLISH_REQUEST);
this.$api.get('/api/order/buyeraskprepublish', {
price,
storage_id,
uid,
address_id,
}).then(result => {
if (result.code === 200) {
commit(BUYER_ASK_PREPUBLISH_SUCCESS, get(result, ['data', 'dialog'], null));
} else {
commit(BUYER_ASK_PREPUBLISH_FAILURE, result.message);
}
}, error => {
console.log(error);
commit(BUYER_ASK_PREPUBLISH_FAILURE, TIP);
});
},
async buyerPublish({commit, dispatch}, {price = 0, storage_id = 0, uid, address_id = '', time_limit_id = ''} = {}) {
commit(BUYER_ASK_PUBLISH_REQUEST);
return this.$api.get('/api/order/buyeraskpublish', {
price,
storage_id,
uid,
address_id,
time_limit_id
}).then(result => {
if (result.code === 200) {
commit(BUYER_ASK_PUBLISH_SUCCESSS, result.data);
} else {
commit(BUYER_ASK_PUBLISH_FAILURE, result.message);
}
}, error => {
console.log(error);
commit(BUYER_ASK_PUBLISH_FAILURE, TIP);
});
}
}
};
}
... ...
... ... @@ -2,8 +2,10 @@ import priceChange from './price-change';
import orderList from './order-list';
import orderConfirm from './order-confirm';
import orderDetail from './order-detail';
import buyerAskOrder from './buyer-ask-order';
import orderLogistics from './order-logistics';
import orderDeliver from './order-deliver';
import sellerAskOrder from './seller-ask-order';
import inSaleOrderList from './in-sale-order-list';
export default function() {
... ... @@ -14,8 +16,10 @@ export default function() {
orderList: orderList(),
orderConfirm: orderConfirm(),
orderDetail: orderDetail(),
buyerAskOrder: buyerAskOrder(),
logisticsInfo: orderLogistics(),
orderDeliver: orderDeliver(),
sellerAskOrder: sellerAskOrder(),
inSaleOrderList: inSaleOrderList(),
},
};
... ...
... ... @@ -20,6 +20,10 @@ export const UserType = {
buy: 'buy'
};
const COUPON_TYPE = {
HUO_DONG: 100
};
export default function() {
return {
namespaced: true,
... ... @@ -97,6 +101,15 @@ export default function() {
state.orderDetail.recommendedCouponInfo.coupon_code =
filter(get(state.orderDetail, 'couponList', []), { selected: 'Y' }).map(i => i.coupon_code).join(',');
// 清除促消活动
if (item.coupon_type === COUPON_TYPE.HUO_DONG) {
get(state.orderDetail, 'promotionList', []).forEach(i => {
i.selected = 'N';
});
state.orderDetail.promotionTips.promotionIds = '';
}
}
},
[Types.CHANGE_SELECT_PROMOTION](state, { promotionId }) {
... ... @@ -117,6 +130,14 @@ export default function() {
});
item.selected = 'Y';
state.orderDetail.promotionTips.promotionIds = promotionId;
// 清除活动优惠券
get(state.orderDetail, 'couponList', []).filter(i => i.coupon_type === COUPON_TYPE.HUO_DONG).forEach(i => {
i.selected = 'N';
});
state.orderDetail.recommendedCouponInfo.coupon_code =
filter(get(state.orderDetail, 'couponList', []), { selected: 'Y' }).map(i => i.coupon_code).join(',');
}
}
... ...
... ... @@ -10,13 +10,6 @@ export default function() {
state.logisticInfo = data;
},
},
getters: {
stageImgUrl: ({ logisticInfo: { stage } }) => {
return stage
? require(`../../statics/image/order/logistics_progress_${stage}@3x.png`)
: '';
},
},
actions: {
/**
* 获取物流信息
... ...
/**
* seller-ask-order.js
*@author dennis
*@createtime 9/29/19
*@description 卖家求购变现状态管理
*/
import {Types} from './types';
import {get} from 'lodash';
const TIP = '请求失败';
const {
SELLER_ORDERCOUNT_REQUEST,
SELLER_ORDERCOUNT_SUCCESS,
SELLER_ORDERCOUNT_FAILURE,
SELLER_ADDRESS_REQUEST,
SELLER_ADDRESS_SUCCESS,
SELLER_ADDRESS_FAILURE,
SELLER_ASK_COMPUTE_REQUEST,
SELLER_ASK_COMPUTE_SUCCESS,
SELLER_ASK_COMPUTE_FAILURE,
SELLER_ASK_PUBLISH_REQUEST,
SELLER_ASK_PUBLISH_SUCCESS,
SELLER_ASK_PUBLISH_FAILURE,
SELLER_ASK_SET_PRICE,
SELLER_ASK_SET_SKUP,
SELLER_ASK_SET_PRODUCTINFO,
} = Types;
const TEST_PRODUCT_INFO = {
least_price: 1119.00,
max_price: 20000.00,
max_sort_id: 10,
min_price: 0.01,
offer_price: 200.00,
product_code: 'OMRG001S181851110112',
product_id: 10000068,
product_name: 'Timberland 红色女靴',
sale_time: '2016.01.01',
goodImg: 'http://img11.static.yhbimg.com/goodsimg/2018/10/18/17/0124eed582cab20be7047c796c314cbc76.jpg?imageMogr2/thumbnail/{width}x{height}/background/d2hpdGU=/position/center/quality/80',
colorName: '黑色',
sizeName: '42码',
goodPrice: 1119.00,
};
export default function() {
return {
namespaced: true,
state: {
originProductData: TEST_PRODUCT_INFO,
price: 1200,
computeTip: null,
addressInfo: null,
publishinfo: null,
},
getter: {
},
mutations: {
[SELLER_ASK_SET_PRODUCTINFO](state, payload) {
state.originProductData = payload
},
[SELLER_ORDERCOUNT_SUCCESS](state, payload) {
},
[SELLER_ADDRESS_SUCCESS](state, payload) {
let list = payload || [];
let defaultAddress;
list.forEach(item => {
if (item.is_default === 'Y') {
defaultAddress = item;
}
});
state.addressInfo = defaultAddress;
},
[SELLER_ASK_COMPUTE_REQUEST](state) {
},
[SELLER_ASK_COMPUTE_SUCCESS](state, payload) {
state.computeTip = payload
},
[SELLER_ASK_COMPUTE_FAILURE](state, payload) {
state.computeTip = null
},
[SELLER_ASK_PUBLISH_REQUEST](state) {
},
[SELLER_ASK_PUBLISH_SUCCESS](state, payload) {
state.publishinfo = payload
},
[SELLER_ASK_PUBLISH_FAILURE](state, payload) {
state.publishinfo = null
}
},
actions: {
fetchSellerOrderCount({commit, dispatch}, {tabType = 'sell', uid} = {}) {
this.$api.get('/api/order/ordercount', {
tabType,
uid
}).then(result => {
if (result.code === 200) {
commit(SELLER_ORDERCOUNT_SUCCESS, result.data);
if (get(result, ['data', 'cnt'], 0) > 0) {
dispatch('fetchSellerAddress', {});
} else {
console.log('first order');
}
} else {
console.log(result.message);
// commit(BUYER_ORDERCOUNT_FAILURE, result.message);
}
}, error => {
console.log(error);
});
},
fetchSellerAddress({commit}, {uid} = {}) {
this.$api.get('/api/address/gethidden', {
uid
}).then(result => {
if (result.code === 200) {
commit(SELLER_ADDRESS_SUCCESS, result.data);
} else {
console.log(result.message);
// commit(BUYER_ADDRESS_FAILURE, result.message);
}
}, error => {
console.log(error);
});
},
sellerCompute({commit}, {price, skup, uid} = {}) {
commit(SELLER_ASK_COMPUTE_REQUEST);
this.$api.get('/api/order/sellask/compute', {
price,
skup,
uid,
}).then(result => {
if (result.code === 200) {
commit(SELLER_ASK_COMPUTE_SUCCESS, result.data);
} else {
commit(SELLER_ASK_COMPUTE_FAILURE, result.message);
}
}, error => {
console.log(error);
commit(SELLER_ASK_COMPUTE_FAILURE, TIP);
});
},
sellerPublish({commit}, {price, skup, address_id, uid} = {}) {
commit(SELLER_ASK_PUBLISH_REQUEST);
return this.$api.get('/api/order/sellask/publish', {
price,
skup,
address_id,
uid,
}).then(result => {
if (result.code === 200) {
commit(SELLER_ASK_PUBLISH_SUCCESS, result.data);
} else {
commit(SELLER_ASK_PUBLISH_FAILURE, result.message);
}
}, error => {
console.log(error);
commit(SELLER_ASK_PUBLISH_FAILURE, TIP);
});
}
},
};
}
... ...
/**
* types.js
*@author dennis
*@createtime 9/25/19
*@description 枚举
*/
export const Types = {
BUYER_ORDERCOUNT_REQUEST: 'BUYER_ORDERCOUNT_REQUEST',
BUYER_ORDERCOUNT_SUCCESS: 'BUYER_ORDERCOUNT_SUCCESS',
BUYER_ORDERCOUNT_FAILURE: 'BUYER_ORDERCOUNT_FAILURE',
BUYER_ADDRESS_REQUEST: 'BUYER_ADDRESS_REQUEST',
BUYER_ADDRESS_SUCCESS: 'BUYER_ADDRESS_SUCCESS',
BUYER_ADDRESS_FAILURE: 'BUYER_ADDRESS_FAILURE',
BUYER_ASK_CONFIG_SUCCESS: 'BUYER_ASK_CONFIG_SUCCESS',
BUYER_ASK_CONFIG_FAILURE: 'BUYER_ASK_CONFIG_FAILURE',
BUYER_ASK_COMPUTE_REQUEST: 'BUYER_ASK_COMPUTE_REQUEST',
BUYER_ASK_COMPUTE_SUCCESS: 'BUYER_ASK_COMPUTE_SUCCESS',
BUYER_ASK_COMPUTE_FAILURE: 'BUYER_ASK_COMPUTE_FAILURE',
BUYER_ASK_PREPUBLISH_SUCCESS: 'BUYER_ASK_PREPUBLISH_SUCCESS',
BUYER_ASK_PREPUBLISH_FAILURE: 'BUYER_ASK_PREPUBLISH_FAILURE',
BUYER_ASK_PREPUBLISH_REQUEST: 'BUYER_ASK_PREPUBLISH_REQUEST',
BUYER_ASK_PUBLISH_REQUEST: 'BUYER_ASK_PUBLISH_REQUEST',
BUYER_ASK_PUBLISH_SUCCESSS: 'BUYER_ASK_PUBLISH_SUCCESSS',
BUYER_ASK_PUBLISH_FAILURE: 'BUYER_ASK_PUBLISH_FAILURE',
BUYER_ASK_SET_SHOWTOAST: 'BUYER_ASK_SET_SHOWTOAST',
BUYER_ASK_SET_CHOOSEDAY: 'BUYER_ASK_SET_CHOOSEDAY',
BUYER_ASK_SET_SHOWDIALOG: 'BUYER_ASK_SET_SHOWDIALOG',
BUYER_ASK_SET_STORAGEID: 'BUYER_ASK_SET_STORAGEID',
BUYER_ASK_SET_PRODUCTINFO: 'BUYER_ASK_SET_PRODUCTINFO',
SELLER_ORDERCOUNT_REQUEST: 'SELLER_ORDERCOUNT_REQUEST',
SELLER_ORDERCOUNT_SUCCESS: 'SELLER_ORDERCOUNT_SUCCESS',
SELLER_ORDERCOUNT_FAILURE: 'SELLER_ORDERCOUNT_FAILURE',
SELLER_ADDRESS_REQUEST: 'SELLER_ADDRESS_REQUEST',
SELLER_ADDRESS_SUCCESS: 'SELLER_ADDRESS_SUCCESS',
SELLER_ADDRESS_FAILURE: 'SELLER_ADDRESS_FAILURE',
SELLER_ASK_COMPUTE_REQUEST: 'SELLER_ASK_COMPUTE_REQUEST',
SELLER_ASK_COMPUTE_SUCCESS: 'SELLER_ASK_COMPUTE_SUCCESS',
SELLER_ASK_COMPUTE_FAILURE: 'SELLER_ASK_COMPUTE_FAILURE',
SELLER_ASK_PUBLISH_REQUEST: 'SELLER_ASK_PUBLISH_REQUEST',
SELLER_ASK_PUBLISH_SUCCESS: 'SELLER_ASK_PUBLISH_SUCCESS',
SELLER_ASK_PUBLISH_FAILURE: 'SELLER_ASK_PUBLISH_FAILURE',
SELLER_ASK_SET_PRICE: 'SELLER_ASK_SET_PRICE',
SELLER_ASK_SET_SKUP: 'SELLER_ASK_SET_SKUP',
SELLER_ASK_SET_PRODUCTINFO: 'SELLER_ASK_SET_PRODUCTINFO',
};
... ...
... ... @@ -92,7 +92,7 @@ export default {
async getSelectedTradeProduct({ state, commit, dispatch }, { productId, storageId }) {
productId = parseInt(productId, 10);
storageId = parseInt(storageId, 10);
if (state.selectedProductInfo.productId !== productId && state.product.product_id !== productId) {
if (state.selectedProductInfo.productId !== productId && !state.products[productId]) {
await dispatch('fetchProductInfo', { productId });
}
... ...
... ... @@ -28,7 +28,7 @@ export default {
},
[Types.UPDATE_PRODUCT_DETAIL](state, payload) {
state.products = {...state.products, [payload.product_id]: payload};
ensureSelectedProduct(state, state.product.product_id);
ensureSelectedProduct(state, payload.product_id);
},
[Types.UPDATE_PRODUCT_TOP3](state, { productId, topList }) {
state.topLists = {...state.topLists, [productId]: topList};
... ...
... ... @@ -2,37 +2,50 @@ module.exports = {
'/api/address/gethidden': {
auth: true,
api: 'app.address.gethidden',
params: {}
params: {},
},
'/api/address/getTags': {
auth: true,
api: 'app.address.getTags',
params: {}
params: {},
},
'/api/address/getProvinces': {
auth: true,
api: 'app.address.provinces',
params: {}
params: {},
},
'/api/address/addAddress': {
auth: true,
api: 'app.address.add',
params: {}
params: {},
},
'/api/address/updateAddress': {
auth: true,
api: 'app.address.update',
params: {}
params: {},
},
'/api/address/delAddress': {
auth: true,
api: 'app.address.del',
params: {}
params: {},
},
'/api/address/setDefaultAddress': {
auth: true,
api: 'app.address.setdefault',
params: {}
params: {},
},
'/api/buyer/modifyAddress': {
auth: true,
ufo: true,
api: 'ufo.buyer.modifyAddress',
params: {
tabType: { type: String, require: true },
orderCode: { type: Number, require: true },
mobile: { type: String, require: true },
consignee: { type: String, require: true },
area: { type: String, require: true },
areaCode: { type: String, require: true },
address: { type: String, require: true },
},
},
};
... ...
// 查询订单数量
const ORDER_COUNT = 'ufo.order.getAllCnt';
//返回求购期限
const BUYER_ASK_CONFIG = 'ufo.buyer.bid.config';
//计算价格
const BUYER_ASK_COMPUTE = 'ufo.buyer.bid.compute';
//预发布,提示
const BUYER_ASK_TIPS = 'ufo.buyer.bid.prePublish';
//发布
const BUYER_ASK_PUBLISH = 'ufo.buyer.bid.publish';
//买家调价计算
const BUYER_ASK_COMPUTE_CHANGE_PRICE = 'ufo.buyer.bid.computeChangePrice';
//买家预调价
const BUYER_ASK_PRE_CHANGE_PRICE = 'ufo.buyer.bid.preChangePrice';
//买家调价
const BUYER_ASK_CHANGE_PRICE = 'ufo.buyer.bid.changePrice';
//变现前计算
const SELLER_ASK_PRE_COMPUTE = 'ufo.seller.bid.compute';
//变现
const SELLER_ASK_PUBLISH = 'ufo.seller.bid.publish';
module.exports = {
ORDER_COUNT,
BUYER_ASK_CONFIG,
BUYER_ASK_COMPUTE,
BUYER_ASK_TIPS,
BUYER_ASK_PUBLISH,
BUYER_ASK_COMPUTE_CHANGE_PRICE,
BUYER_ASK_PRE_CHANGE_PRICE,
BUYER_ASK_CHANGE_PRICE,
SELLER_ASK_PRE_COMPUTE,
SELLER_ASK_PUBLISH,
};
... ...
... ... @@ -4,8 +4,10 @@ const listApi = require('./list-api-map');
const homeApi = require('./home-api-map');
const passportApi = require('./passport-api-map');
const addressApi = require('./address-api-map');
const buyerAskApi = require('./buyerask-api-map')
const orderListApi = require('./order-api-map');
const categoryApi = require('./category-api-map');
const sellerAskApi = require('./sellerask-api-map');
module.exports = {
...orderApi,
... ... @@ -14,6 +16,8 @@ module.exports = {
...homeApi,
...passportApi,
...addressApi,
...buyerAskApi,
...orderListApi,
...categoryApi,
...sellerAskApi,
};
... ...
/**
* buyerask-api-map.js
*@author dennis
*@createtime 9/26/19
*@description 买家求购
*/
const API = require('./api-constants');
module.exports = {
'/api/order/buyaskconfig': {
ufo: true,
auth: true,
path: 'shopping/bid',
api: API.BUYER_ASK_CONFIG,
params: {}
},
'/api/order/buyeraskcompute': {
ufo: true,
auth: true,
path: 'shopping/bid',
api: API.BUYER_ASK_COMPUTE,
params: {
price: {type: Number, required: true},
storage_id: {type: Number, required: true},
}
},
'/api/order/buyeraskprepublish': {
ufo: true,
auth: true,
path: 'shopping/bid',
api: API.BUYER_ASK_TIPS,
params: {
price: {type: Number, required: true},
storage_id: {type: Number, required: true},
address_id: {type: String, required: true},
}
},
'/api/order/buyeraskpublish': {
ufo: true,
auth: true,
path: 'shopping/bid',
api: API.BUYER_ASK_PUBLISH,
params: {
price: {type: Number, required: true},
storage_id: {type: Number, required: true},
address_id: {type: String, required: true},
time_limit_id: {type: Number, required: true}, // 有效期
}
},
'/api/order/buyerask/computechangeprice': {
ufo: true,
auth: true,
path: 'shopping/bid',
api: API.BUYER_ASK_COMPUTE_CHANGE_PRICE,
params: {
price: {type: Number, required: true},
orderCode: {type: String, required: true},
}
},
'/api/order/buyerask/prechangeprice': {
ufo: true,
auth: true,
path: 'shopping/bid',
api: API.BUYER_ASK_PRE_CHANGE_PRICE,
params: {
price: {type: Number, required: true},
orderCode: {type: String, required: true},
}
},
'/api/order/buyerask/changeprice': {
ufo: true,
auth: true,
path: 'shopping/bid',
api: API.BUYER_ASK_CHANGE_PRICE,
params: {
price: {type: Number, required: true},
orderCode: {type: String, required: true},
}
}
};
... ...
... ... @@ -97,8 +97,10 @@ module.exports = {
'/api/ufo/home/newsList': {
ufo: true,
api: 'ufo.users.listInboxs',
params: {},
auth: true,
params: {
uid: {type: Number}
},
// auth: true,
},
'/api/ufo/home/newsListTab': {
ufo: true,
... ...
const API = require('./api-constants');
module.exports = {
// 获取调价商品及尺码信息
'/api/ufo/seller/entryGoodsSizeList': {
... ... @@ -92,7 +94,6 @@ module.exports = {
ufo: true,
auth: true,
api: 'ufo.order.list',
// 类型定义
params: {
limit: { type: Number }, // page size
... ... @@ -225,6 +226,16 @@ module.exports = {
auth: true,
ufo: true,
api: 'ufo.sellerOrder.computePublishPrd',
},
'/api/order/ordercount': {
ufo: true,
auth: true,
api: API.ORDER_COUNT,
params: {
tabType: { type: String, require: true }, // 订单来源
}
},
// 判断用户状态
... ...
/**
* sellerask-api-map.js
*@author dennis
*@createtime 9/29/19
*@description 卖家求购变现
*/
const API = require('./api-constants');
module.exports = {
'/api/order/sellask/compute': {
ufo: true,
auth: true,
path: '',
api: API.SELLER_ASK_PRE_COMPUTE,
params: {
skup: {type: Number, required: true},
price: {type: Number, required: true},
}
},
'/api/order/sellask/publish': {
ufo: true,
auth: true,
path: '',
api: API.SELLER_ASK_PUBLISH,
params: {
skup: {type: Number, required: true},
price: {type: Number, required: true},
address_id: {type: String, required: true},
}
},
}
... ...
... ... @@ -70,7 +70,7 @@ module.exports = async (req, res, next) => {
} else if (apiInfo.ufo) {
result = await apiCtx[method]({
api: ufoAPI,
url: apiInfo.path || '',
url: apiInfo.path ? apiInfo.path : '',
data: params,
param: {
cache: cache,
... ... @@ -86,6 +86,7 @@ module.exports = async (req, res, next) => {
});
}
if (result) {
// console.log(result);
return res.json(handleResult(result, apiInfo));
}
return res.json({
... ...
... ... @@ -45,7 +45,9 @@ module.exports = (req, res, next) => {
}
// Todo 删除 600032996 调价: 500031170 购买: 600043484
// req.user.uid = 600043484;
// 入住商家 50000638
// 梅 500031928
// req.user.uid = 600032996;
res.locals.isLogin = Boolean(req.user.uid); // 用户是否登录
if (_.get(req, 'user.appSessionType') === 'miniapp') {
... ...
... ... @@ -115,6 +115,8 @@ class passportModel extends global.yoho.BaseModel {
domain: 'yohobuy.com',
expires: new Date(Date.now() + 2592000000) // 有效期一年
});
}).catch(e => {
log.info(`[sync profile error] uid: ${uid} | err: ${JSON.stringify(e)}`);
});
}
sendTaobaoBindCode(mobile) {
... ...
{
"name": "xianyu-ufo-app-web",
"version": "0.0.2-beta-6",
"version": "0.0.2-beta-8",
"private": true,
"description": "Xianyu Project With Express",
"repository": {
... ...
declare module 'yoho' {
interface IOrderLogisticInfo {
expressCompanyName: string; // 物流公司名称
expressSender: string; // 订单跟踪
expressType: number;
expressInfoDetailList: object[];
expressInfoDetailTitle: string;
judgeExpressInfoDetailList: IJudgeDetailInfo[];
judgeExpressInfoDetailTitle: string; // 平台鉴定
}
interface IJudgeDetailInfo {
acceptAddress: string;
}
}
... ...