Authored by 邱骏

求购调价

<template><!--求购用调价对话框-->
<div class="dialog-wrapper" :class="[visible ? 'show' : '']">
<div class="change-bid-price-wrapper">
<div class="change-bid-price-container">
<p class="price-item">
<span>我的求购价:</span>
<span>¥{{ goodsInfo.goodPrice }}</span>
</p>
<p class="price-item">
<span>当前最高求购价:</span>
<span>¥{{ goodsInfo.bidHighestPrice }}</span>
</p>
<p v-if="goodsInfo.leastPrice" class="price-item">
<span>最低现货价:</span>
<span>¥{{ goodsInfo.leastPrice }}</span>
</p>
<InputUfo
type="number"
placeholder="定价需以9结尾 例如1999"
:maxlength="8"
:class="[errorTip ? 'ipt-number show-error' : 'ipt-number', 'ufo-font']"
v-model="chgPrice"
>
<span class="prepend" slot="prepend">¥</span>
</InputUfo>
<p class="error-tip">{{ errorTip }}</p>
<p
:class="
i === computePriceList.length - 1
? 'promotion-list-item last'
: 'promotion-list-item'
"
v-for="(priceInfo, i) in computePriceList"
:key="i"
>
<span>{{ priceInfo.promotion }}:</span>
<span>{{ priceInfo.promotionAmount }}</span>
</p>
<p class="tip">Tip: 调整求购价成功后,当前的求购将被关闭</p>
</div>
<div class="buttons-container">
<button class="btn-cancel" @click="closeAction">取消</button>
<button class="btn-confirm" @click="confirmAction">调整求购价</button>
</div>
</div>
</div>
</template>
<script>
import { createNamespacedHelpers } from 'vuex';
import InputUfo from './input-ufo';
import { debounce } from 'lodash';
const { mapActions } = createNamespacedHelpers('order/orderList');
export default {
name: 'change-bid-price-dialog',
components: { InputUfo },
props: {
computePriceInfo: {
type: Object,
default: () => ({})
},
goodsInfo: {
type: Object,
default: () => ({})
},
orderCode: {
type: Number,
default: 0
}
},
data() {
return {
visible: false,
chgPrice: '',
errorTip: '',
computePrice: null,
calced: false
};
},
computed: {
computePriceList() {
const priceInfo = this.computePrice || this.computePriceInfo;
return priceInfo.promotionFormulaList.filter(
({ promotion }) => promotion === "运费" || promotion === "实付金额"
);
}
},
mounted() {
// debounce防抖动,输入数字后延迟500毫秒提交
this.inputChange = debounce(this.onChange.bind(this), 500);
},
methods: {
...mapActions(["computeChangePrice"]),
async onChange(price) { // 预先算费
if (this.checkPrice(price)) {
const res = await this.computeChangePrice({
price,
orderCode: this.orderCode
});
if (typeof res === "string") {
this.errorTip = res;
this.calced = false;
} else {
this.computePrice = res;
this.calced = true;
}
}
},
show() {
this.clearData();
this.visible = true;
},
hide() {
this.visible = false;
},
checkPrice(price) {
let valid = false;
if (!price) {
this.errorTip = '没有价格';
return false;
} else if (!/^\d+$/.test(price)) {
this.errorTip = '价格只能为正整数';
} else if (!/9$/.test(price)) {
this.errorTip = '出售价格必须以9结尾';
} else if (+price === +this.goodsInfo.goodPrice) {
this.errorTip = '前后价格没有变化';
} else {
this.errorTip = '';
valid = true;
}
return valid;
},
closeAction() {
this.hide();
this.clearData();
this.$emit('closeAction');
},
confirmAction() {
if (this.calced) {
let price = this.chgPrice;
this.hide();
this.clearData();
this.$emit('confirmAction', price);
}
},
clearData() {
this.chgPrice = '';
this.errorTip = '',
this.computePrice = null;
this.calced = false;
}
},
watch: {
chgPrice(newVal) {
this.calced = false;
this.inputChange(newVal);
}
}
};
</script>
<style lang="scss" scoped>
.dialog-wrapper {
position: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 99;
display: none;
align-items: center;
justify-content: center;
&.show {
display: flex;
}
}
.change-bid-price-wrapper {
position: absolute;
width: 600px;
background-color: #fff;
}
.change-bid-price-container {
background-color: #fff;
font-size: 12px;
color: #000;
padding: 60px 38px 0 38px;
letter-spacing: 0;
.price-item {
font-size: 24px;
line-height: 34px;
margin-bottom: 10px;
}
.ipt-number {
margin: 30px 0;
/deep/ .prepend {
width: 40px;
margin-left: 20px;
text-align: left;
}
&.show-error {
margin-bottom: 0;
}
}
.error-tip {
color: #d0021b;
margin-bottom: 10px;
}
.promotion-list-item {
display: flex;
justify-content: space-between;
align-items: center;
color: #999;
margin-bottom: 10px;
&.last {
color: #000;
}
}
.tip {
color: #999;
margin: 40px auto;
}
}
.buttons-container {
width: 100%;
height: 100px;
display: flex;
border-top: 1px solid #f0f0f0;
button {
width: 100%;
text-align: center;
line-height: 100px;
font-size: 32px;
}
}
</style>
... ...
import ChangeBidPriceDialog from './change-bid-price-dialog';
import createApi from 'utils/create-api';
ChangeBidPriceDialog.install = function(Vue) {
Vue.component(ChangeBidPriceDialog.name, ChangeBidPriceDialog);
createApi(
Vue,
ChangeBidPriceDialog,
['closeAction', 'confirmAction'],
true
);
};
export default ChangeBidPriceDialog;
... ...
<template>
<CubeInput v-bind="$attrs" v-bind:value="value" v-on="inputListeners" :maxlength="8" class="input-number">
<span slot="prepend">
<slot name="prepend"></slot>
</span>
<span slot="append">
<slot name="append"></slot>
</span>
</CubeInput>
</template>
<script>
import {Input} from 'cube-ui';
export default {
name: 'InputUfo',
props: ['value'],
computed: {
inputListeners() {
return Object.assign({},
this.$listeners,
{
input: (value) => {
this.$emit('input', value);
},
blur: () => {
this.$emit('blur', this.value);
}
}
);
}
},
methods: {
},
components: {CubeInput: Input}
};
</script>
<style lang="scss" scoped>
.input-number {
margin-bottom: 15px;
background-color: #f5f5f5;
border-radius: 10px;
font-size: 36px;
&:after {
border-radius: 20px;
border-color: #f5f5f5;
}
/deep/ .cube-input-field {
color: #000;
}
}
</style>
... ...
... ... @@ -25,6 +25,7 @@ import xianyu from 'common/xianyu';
import OrderPayType from 'components/order-pay-type';
import OrderCouponList from 'components/order-coupon-list';
import OrderPromotionList from 'components/order-promotion-list';
import ChangeBidPriceDialog from 'components/change-bid-price-dialog';
import Bind from 'components/bind';
import ConfirmDialog from 'components/confirm-dialog';
import 'video.js/dist/video-js.css';
... ... @@ -71,6 +72,7 @@ Vue.use(OrderCouponList);
Vue.use(OrderPromotionList);
Vue.use(Bind);
Vue.use(ConfirmDialog);
Vue.use(ChangeBidPriceDialog);
initClient(store);
... ...
... ... @@ -190,52 +190,39 @@ export default {
}).show();
return;
}
let that = this;
this.$createDialog(
{
type: 'prompt',
confirmBtn: { text: '调整求购价' },
cancelBtn: { active: true },
onConfirm: async () => {
if (!this.changePrice) {
return;
}
const { isOk, errMsg = '' } = await this.confirmChangePrice({
price: this.changePrice,
orderCode,
});
this.$createChangeBidPriceDialog({
computePriceInfo,
goodsInfo,
orderCode,
onCloseAction() {
},
onConfirmAction: async(price) => {
const { isOk, errMsg = '' } = await that.confirmChangePrice({
price: price,
orderCode,
});
if (isOk) {
if (isDetail) {
this.fetchOrderDetail(this.$route.params);
} else {
this.resetData();
this.fetchData(this.$route.params);
}
if (isOk) {
if (isDetail) {
that.$router.back();
// that.fetchOrderDetail(this.$route.params);
} else {
if (errMsg) {
this.$createToast({
type: 'alert',
txt: errMsg,
});
}
that.resetData();
that.fetchData(this.$route.params);
}
},
},
createElement => {
return [
createElement(DialogChangeBidPrice, {
props: {
computePriceInfo,
goodsInfo,
orderCode,
onChangePrice: v => (this.changePrice = v),
},
slot: 'content',
}),
];
},
).show();
} else {
if (errMsg) {
that.$createToast({
type: 'alert',
txt: errMsg,
});
}
}
}
}).show();
break;
}
default:
... ...
... ... @@ -179,6 +179,7 @@ export default function() {
orderCode: `${orderCode}`,
price: +price,
});
console.log(res);
if (res.code === 200) {
return { errMsg: '', isOk: true };
... ...