Merge pull request '快递模板更新' (#2) from zzw-one into master
Reviewed-on: #2
This commit is contained in:
commit
e704f5f1fc
261
pages/order/addressSelection.vue
Normal file
261
pages/order/addressSelection.vue
Normal file
@ -0,0 +1,261 @@
|
||||
<!-- 下单界面,收货地址 or 自提门店的选择组件 -->
|
||||
<template>
|
||||
<view class="allAddress" :style="state.isPickUp ? '':'padding-top:10rpx;'">
|
||||
<view class="nav flex flex-wrap">
|
||||
<view class="item font-color" :class="state.deliveryType === 1 ? 'on' : 'on2'"
|
||||
@tap="switchDeliveryType(1)" v-if='state.isPickUp' />
|
||||
<view class="item font-color" :class="state.deliveryType === 2 ? 'on' : 'on2'"
|
||||
@tap="switchDeliveryType(2)" v-if='state.isPickUp' />
|
||||
</view>
|
||||
<!-- 情况一:收货地址的选择 -->
|
||||
<view class='address flex flex-wrap flex-center ss-row-between' @tap='onSelectAddress' v-if='state.deliveryType === 1'
|
||||
:style="state.isPickUp ? '':'border-top-left-radius: 14rpx;border-top-right-radius: 14rpx;'">
|
||||
<view class='addressCon' v-if="state.addressInfo.name">
|
||||
<view class='name'>{{ state.addressInfo.name }}
|
||||
<text class='phone'>{{ state.addressInfo.mobile }}</text>
|
||||
</view>
|
||||
<view class="flex flex-wrap">
|
||||
<text class='default font-color' v-if="state.addressInfo.defaultStatus">[默认]</text>
|
||||
<text class="line2">{{ state.addressInfo.areaName }} {{ state.addressInfo.detailAddress }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class='addressCon' v-else>
|
||||
<view class='setaddress'>设置收货地址</view>
|
||||
</view>
|
||||
<view class='iconfont'>
|
||||
<view class="ss-rest-button">
|
||||
<text class="_icon-forward" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 情况二:门店的选择 -->
|
||||
<view class='address flex flex-wrap flex-center ss-row-between' v-else @tap="onSelectAddress">
|
||||
<view class='addressCon' v-if="state.pickUpInfo.name">
|
||||
<view class='name'>{{ state.pickUpInfo.name }}
|
||||
<text class='phone'>{{ state.pickUpInfo.phone }}</text>
|
||||
</view>
|
||||
<view class="line1"> {{ state.pickUpInfo.areaName }}{{ ', ' + state.pickUpInfo.detailAddress }}
|
||||
</view>
|
||||
</view>
|
||||
<view class='addressCon' v-else>
|
||||
<view class='setaddress'>选择自提门店</view>
|
||||
</view>
|
||||
<view class='iconfont'>
|
||||
<view class="ss-rest-button">
|
||||
<text class="_icon-forward" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class='line'>
|
||||
<image :src="sheep.$url.static('/static/images/line.png', 'local')" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import sheep from '@/sheep';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Object,
|
||||
default() {},
|
||||
}
|
||||
});
|
||||
const emits = defineEmits(['update:modelValue']);
|
||||
|
||||
// computed 解决父子组件双向数据同步
|
||||
const state = computed({
|
||||
get(){
|
||||
return new Proxy(props.modelValue, {
|
||||
set(obj, name, val) {
|
||||
emits('update:modelValue', {
|
||||
...obj,
|
||||
[name]: val,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
})
|
||||
},
|
||||
set(val){
|
||||
emits('update:modelValue', val);
|
||||
}
|
||||
})
|
||||
|
||||
// 选择地址
|
||||
function onSelectAddress() {
|
||||
let emitName = 'SELECT_ADDRESS'
|
||||
let addressPage = '/pages/user/address/list?type=select';
|
||||
if (state.value.deliveryType === 2){
|
||||
emitName = 'SELECT_PICK_UP_INFO'
|
||||
addressPage = '/pages/user/goods_details_store/index'
|
||||
}
|
||||
uni.$once(emitName, (e) => {
|
||||
changeConsignee(e.addressInfo);
|
||||
});
|
||||
sheep.$router.go(addressPage);
|
||||
}
|
||||
|
||||
// 更改收货人地址&计算订单信息
|
||||
async function changeConsignee(addressInfo = {}) {
|
||||
if (!isEmpty(addressInfo)) {
|
||||
if (state.value.deliveryType === 1){
|
||||
state.value.addressInfo = addressInfo;
|
||||
}
|
||||
if (state.value.deliveryType === 2){
|
||||
state.value.pickUpInfo = addressInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 收货方式切换
|
||||
const switchDeliveryType = (type) =>{
|
||||
state.value.deliveryType = type;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.allAddress .font-color{
|
||||
color: #E93323!important
|
||||
}
|
||||
.line2{
|
||||
width: 504rpx;
|
||||
}
|
||||
.textR {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
height: 3rpx;
|
||||
}
|
||||
|
||||
.line image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.address {
|
||||
padding: 28rpx;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.address .addressCon {
|
||||
width: 596rpx;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.address .addressCon .name {
|
||||
font-size: 30rpx;
|
||||
color: #282828;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.address .addressCon .name .phone {
|
||||
margin-left: 50rpx;
|
||||
}
|
||||
|
||||
.address .addressCon .default {
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.address .addressCon .setaddress {
|
||||
color: #333;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.address .iconfont {
|
||||
font-size: 35rpx;
|
||||
color: #707070;
|
||||
}
|
||||
|
||||
.allAddress {
|
||||
width: 100%;
|
||||
background: linear-gradient(to bottom, #e93323 0%, #f5f5f5 100%);
|
||||
// background-image: linear-gradient(to bottom, #e93323 0%, #f5f5f5 100%);
|
||||
// background-image: -webkit-linear-gradient(to bottom, #e93323 0%, #f5f5f5 100%);
|
||||
// background-image: -moz-linear-gradient(to bottom, #e93323 0%, #f5f5f5 100%);
|
||||
//padding: 100rpx 30rpx 0 30rpx;
|
||||
padding-top: 100rpx;
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.allAddress .nav {
|
||||
width: 690rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.allAddress .nav .item {
|
||||
width: 334rpx;
|
||||
}
|
||||
|
||||
.allAddress .nav .item.on {
|
||||
position: relative;
|
||||
width: 230rpx;
|
||||
}
|
||||
|
||||
.allAddress .nav .item.on::before {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
content: "快递配送";
|
||||
font-size: 28rpx;
|
||||
display: block;
|
||||
height: 0;
|
||||
width: 336rpx;
|
||||
border-width: 0 20rpx 80rpx 0;
|
||||
border-style: none solid solid;
|
||||
border-color: transparent transparent #fff;
|
||||
z-index: 2;
|
||||
border-radius: 14rpx 36rpx 0 0;
|
||||
text-align: center;
|
||||
line-height: 80rpx;
|
||||
}
|
||||
|
||||
.allAddress .nav .item:nth-of-type(2).on::before {
|
||||
content: "到店自提";
|
||||
border-width: 0 0 80rpx 20rpx;
|
||||
border-radius: 36rpx 14rpx 0 0;
|
||||
}
|
||||
|
||||
.allAddress .nav .item.on2 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.allAddress .nav .item.on2::before {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
content: "到店自提";
|
||||
font-size: 28rpx;
|
||||
display: block;
|
||||
height: 0;
|
||||
width: 401rpx;
|
||||
border-width: 0 0 60rpx 60rpx;
|
||||
border-style: none solid solid;
|
||||
border-color: transparent transparent #f7c1bd;
|
||||
border-radius: 36rpx 14rpx 0 0;
|
||||
text-align: center;
|
||||
line-height: 60rpx;
|
||||
}
|
||||
|
||||
.allAddress .nav .item:nth-of-type(1).on2::before {
|
||||
content: "快递配送";
|
||||
border-width: 0 60rpx 60rpx 0;
|
||||
border-radius: 14rpx 36rpx 0 0;
|
||||
}
|
||||
|
||||
.allAddress .address {
|
||||
width: 690rpx;
|
||||
max-height: 180rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.allAddress .line {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
@ -1,13 +1,7 @@
|
||||
<template>
|
||||
<s-layout title="确认订单">
|
||||
<!-- TODO:这个判断先删除 v-if="state.orderInfo.need_address === 1" -->
|
||||
<view class="bg-white address-box ss-m-b-14 ss-r-b-10" @tap="onSelectAddress">
|
||||
<s-address-item :item="state.addressInfo" :hasBorderBottom="false">
|
||||
<view class="ss-rest-button">
|
||||
<text class="_icon-forward" />
|
||||
</view>
|
||||
</s-address-item>
|
||||
</view>
|
||||
<!-- 头部地址选择【配送地址】【自提地址】 -->
|
||||
<AddressSelection v-model="addressState" />
|
||||
|
||||
<!-- 商品信息 -->
|
||||
<view class="order-card-box ss-m-b-14">
|
||||
@ -46,26 +40,58 @@
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- TODO 芋艿:接入积分 -->
|
||||
<view
|
||||
class="order-item ss-flex ss-col-center ss-row-between"
|
||||
v-if="state.orderPayload.order_type === 'score'"
|
||||
v-if="state.orderInfo.type === 0"
|
||||
>
|
||||
<view class="item-title">扣除积分</view>
|
||||
<view class="item-title">积分抵扣</view>
|
||||
<view class="ss-flex ss-col-center">
|
||||
{{ state.pointStatus ? '剩余积分' : '当前积分' }}
|
||||
<image
|
||||
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
|
||||
class="score-img"
|
||||
/>
|
||||
<text class="item-value ss-m-r-24">{{ state.orderInfo.score_amount }}</text>
|
||||
<text class="item-value ss-m-r-24">
|
||||
{{ state.pointStatus ? state.orderInfo.totalPoint - state.orderInfo.usePoint : (state.orderInfo.totalPoint || 0) }}
|
||||
</text>
|
||||
<checkbox-group @change="changeIntegral">
|
||||
<checkbox :checked='state.pointStatus' :disabled="!state.orderInfo.totalPoint || state.orderInfo.totalPoint <= 0" />
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
<view class="order-item ss-flex ss-col-center ss-row-between">
|
||||
<!-- 快递配置时,信息的展示 -->
|
||||
<view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 1'>
|
||||
<view class="item-title">运费</view>
|
||||
<view class="ss-flex ss-col-center">
|
||||
<text class="item-value ss-m-r-24">
|
||||
<text class="item-value ss-m-r-24" v-if="state.orderInfo.price.deliveryPrice > 0">
|
||||
+¥{{ fen2yuan(state.orderInfo.price.deliveryPrice) }}
|
||||
</text>
|
||||
<view class='item-value ss-m-r-24' v-else>免运费</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 门店自提时,需要填写姓名和手机号 -->
|
||||
<view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 2'>
|
||||
<view class="item-title">联系人</view>
|
||||
<view class="ss-flex ss-col-center">
|
||||
<uni-easyinput
|
||||
maxlength="20"
|
||||
placeholder="请填写您的联系姓名"
|
||||
v-model="addressState.receiverName"
|
||||
:inputBorder="false"
|
||||
:clearable="false"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 2'>
|
||||
<view class="item-title">联系电话</view>
|
||||
<view class="ss-flex ss-col-center">
|
||||
<uni-easyinput
|
||||
maxlength="20"
|
||||
placeholder="请填写您的联系电话"
|
||||
v-model="addressState.receiverMobile"
|
||||
:inputBorder="false"
|
||||
:clearable="false"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 优惠劵:只有 type = 0 普通订单(非拼团、秒杀、砍价),才可以使用优惠劵 -->
|
||||
@ -120,7 +146,7 @@
|
||||
共{{ state.orderInfo.items.reduce((acc, item) => acc + item.count, 0) }}件
|
||||
</view>
|
||||
<view>合计:</view>
|
||||
<view class="total-num text-red"> ¥{{ fen2yuan(state.orderInfo.price.payPrice) }} </view>
|
||||
<view class="total-num text-red"> ¥{{ fen2yuan(state.orderInfo.price.payPrice) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -159,10 +185,10 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive } from 'vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import AddressSelection from '@/pages/order/addressSelection.vue';
|
||||
import sheep from '@/sheep';
|
||||
import { isEmpty } from 'lodash';
|
||||
import OrderApi from '@/sheep/api/trade/order';
|
||||
import CouponApi from '@/sheep/api/promotion/coupon';
|
||||
import { fen2yuan } from '@/sheep/hooks/useGoods';
|
||||
@ -173,27 +199,30 @@
|
||||
items: [], // 商品项列表
|
||||
price: {}, // 价格信息
|
||||
},
|
||||
addressInfo: {}, // 选择的收货地址
|
||||
showCoupon: false, // 是否展示优惠劵
|
||||
couponInfo: [], // 优惠劵列表
|
||||
showDiscount: false, // 是否展示营销活动
|
||||
// ========== 积分 ==========
|
||||
pointStatus: false, //是否使用积分
|
||||
});
|
||||
|
||||
// 选择地址
|
||||
function onSelectAddress() {
|
||||
uni.$once('SELECT_ADDRESS', (e) => {
|
||||
changeConsignee(e.addressInfo);
|
||||
const addressState = ref({
|
||||
addressInfo: {}, // 选择的收货地址
|
||||
deliveryType: 1, // 收货方式 1 - 快递配送;2 - 门店自提
|
||||
isPickUp: true, // 门店自提是否开启 TODO puhui999: 默认开启,看看后端有开关的话接入
|
||||
pickUpInfo: {}, // 选择的自提门店信息
|
||||
receiverName: '', // 收件人名称
|
||||
receiverMobile: '', // 收件人手机
|
||||
});
|
||||
sheep.$router.go('/pages/user/address/list');
|
||||
}
|
||||
|
||||
// 更改收货人地址&计算订单信息
|
||||
async function changeConsignee(addressInfo = {}) {
|
||||
if (!isEmpty(addressInfo)) {
|
||||
state.addressInfo = addressInfo;
|
||||
}
|
||||
// ========== 积分 ==========
|
||||
/**
|
||||
* 使用积分抵扣
|
||||
*/
|
||||
const changeIntegral = async () => {
|
||||
state.pointStatus = !state.pointStatus;
|
||||
await getOrderInfo();
|
||||
}
|
||||
};
|
||||
|
||||
// 选择优惠券
|
||||
async function onSelectCoupon(couponId) {
|
||||
@ -204,10 +233,28 @@
|
||||
|
||||
// 提交订单
|
||||
function onConfirm() {
|
||||
if (!state.addressInfo.id) {
|
||||
if (addressState.value.deliveryType === 1 && !addressState.value.addressInfo.id) {
|
||||
sheep.$helper.toast('请选择收货地址');
|
||||
return;
|
||||
}
|
||||
if (addressState.value.deliveryType === 2) {
|
||||
if (!addressState.value.pickUpInfo.id) {
|
||||
sheep.$helper.toast('请选择自提门店地址');
|
||||
return;
|
||||
}
|
||||
if (addressState.value.receiverName === '' || addressState.value.receiverMobile === '') {
|
||||
sheep.$helper.toast('请填写联系人或联系人电话');
|
||||
return;
|
||||
}
|
||||
if (!/^[\u4e00-\u9fa5\w]{2,16}$/.test(addressState.value.receiverName)) {
|
||||
sheep.$helper.toast('请填写您的真实姓名');
|
||||
return;
|
||||
}
|
||||
if (!/^1(3|4|5|7|8|9|6)\d{9}$/.test(addressState.value.receiverMobile)) {
|
||||
sheep.$helper.toast('请填写正确的手机号');
|
||||
return;
|
||||
}
|
||||
}
|
||||
submitOrder();
|
||||
}
|
||||
|
||||
@ -216,9 +263,13 @@
|
||||
const { code, data } = await OrderApi.createOrder({
|
||||
items: state.orderPayload.items,
|
||||
couponId: state.orderPayload.couponId,
|
||||
addressId: state.addressInfo.id,
|
||||
deliveryType: 1, // TODO 芋艿:需要支持【门店自提】
|
||||
pointStatus: false, // TODO 芋艿:需要支持【积分选择】
|
||||
remark: state.orderPayload.remark,
|
||||
deliveryType: addressState.value.deliveryType,
|
||||
addressId: addressState.value.addressInfo.id, // 收件地址编号
|
||||
pickUpStoreId: addressState.value.pickUpInfo.id,//自提门店编号
|
||||
receiverName: addressState.value.receiverName,// 选择门店自提时,该字段为联系人名
|
||||
receiverMobile: addressState.value.receiverMobile,// 选择门店自提时,该字段为联系人手机
|
||||
pointStatus: state.pointStatus,
|
||||
combinationActivityId: state.orderPayload.combinationActivityId,
|
||||
combinationHeadId: state.orderPayload.combinationHeadId,
|
||||
seckillActivityId: state.orderPayload.seckillActivityId,
|
||||
@ -230,6 +281,7 @@
|
||||
if (state.orderPayload.items[0].cartId > 0) {
|
||||
sheep.$store('cart').getList();
|
||||
}
|
||||
|
||||
// 跳转到支付页面
|
||||
sheep.$router.redirect('/pages/pay/index', {
|
||||
id: data.payOrderId,
|
||||
@ -242,9 +294,12 @@
|
||||
const { data, code } = await OrderApi.settlementOrder({
|
||||
items: state.orderPayload.items,
|
||||
couponId: state.orderPayload.couponId,
|
||||
addressId: state.addressInfo.id,
|
||||
deliveryType: 1, // TODO 芋艿:需要支持【门店自提】
|
||||
pointStatus: false, // TODO 芋艿:需要支持【积分选择】
|
||||
deliveryType: addressState.value.deliveryType,
|
||||
addressId: addressState.value.addressInfo.id, // 收件地址编号
|
||||
pickUpStoreId: addressState.value.pickUpInfo.id,//自提门店编号
|
||||
receiverName: addressState.value.receiverName,// 选择门店自提时,该字段为联系人名
|
||||
receiverMobile: addressState.value.receiverMobile,// 选择门店自提时,该字段为联系人手机
|
||||
pointStatus: state.pointStatus,
|
||||
combinationActivityId: state.orderPayload.combinationActivityId,
|
||||
combinationHeadId: state.orderPayload.combinationHeadId,
|
||||
seckillActivityId: state.orderPayload.seckillActivityId,
|
||||
@ -255,7 +310,7 @@
|
||||
state.orderInfo = data;
|
||||
// 设置收货地址
|
||||
if (state.orderInfo.address) {
|
||||
state.addressInfo = state.orderInfo.address;
|
||||
addressState.value.addressInfo = state.orderInfo.address;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,9 +45,9 @@
|
||||
</image>
|
||||
<view class="ss-font-30">{{ formatOrderStatus(state.orderInfo) }}</view>
|
||||
</view>
|
||||
<view class="ss-font-26 ss-m-x-20 ss-m-b-70">{{
|
||||
formatOrderStatusDescription(state.orderInfo)
|
||||
}}</view>
|
||||
<view class="ss-font-26 ss-m-x-20 ss-m-b-70">
|
||||
{{ formatOrderStatusDescription(state.orderInfo) }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 收货地址 -->
|
||||
@ -126,6 +126,9 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 自提核销 -->
|
||||
<PickUpVerify :order-info="state.orderInfo" :systemStore="systemStore" ref="pickUpVerifyRef"></PickUpVerify>
|
||||
|
||||
<!-- 订单信息 -->
|
||||
<view class="notice-box">
|
||||
<view class="notice-box__content">
|
||||
@ -172,6 +175,10 @@
|
||||
<text class="title">优惠劵金额</text>
|
||||
<text class="detail">-¥{{ fen2yuan(state.orderInfo.couponPrice) }}</text>
|
||||
</view>
|
||||
<view class="notice-item ss-flex ss-row-between" v-if="state.orderInfo.pointPrice > 0">
|
||||
<text class="title">积分抵扣</text>
|
||||
<text class="detail">-¥{{ fen2yuan(state.orderInfo.pointPrice) }}</text>
|
||||
</view>
|
||||
<view class="notice-item ss-flex ss-row-between" v-if="state.orderInfo.discountPrice > 0">
|
||||
<text class="title">活动优惠</text>
|
||||
<text class="detail">¥{{ fen2yuan(state.orderInfo.discountPrice) }}</text>
|
||||
@ -251,8 +258,8 @@
|
||||
<script setup>
|
||||
import sheep from '@/sheep';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import { reactive } from 'vue';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import {
|
||||
fen2yuan,
|
||||
formatOrderStatus,
|
||||
@ -260,6 +267,8 @@
|
||||
handleOrderButtons,
|
||||
} from '@/sheep/hooks/useGoods';
|
||||
import OrderApi from '@/sheep/api/trade/order';
|
||||
import DeliveryApi from '@/sheep/api/trade/delivery';
|
||||
import PickUpVerify from '@/pages/order/pickUpVerify.vue';
|
||||
|
||||
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
|
||||
const headerBg = sheep.$url.css('/static/img/shop/order/order_bg.png');
|
||||
@ -270,6 +279,9 @@
|
||||
comeinType: '', // 进入订单详情的来源类型
|
||||
});
|
||||
|
||||
// ========== 门店自提(核销) ==========
|
||||
const systemStore = ref({}); // 门店信息
|
||||
|
||||
// 复制
|
||||
const onCopy = () => {
|
||||
sheep.$helper.copyText(state.orderInfo.no);
|
||||
@ -294,7 +306,7 @@
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要取消订单吗?',
|
||||
success: async function (res) {
|
||||
success: async function(res) {
|
||||
if (!res.confirm) {
|
||||
return;
|
||||
}
|
||||
@ -366,6 +378,7 @@
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
// 评价
|
||||
@ -375,6 +388,8 @@
|
||||
});
|
||||
}
|
||||
|
||||
const pickUpVerifyRef = ref();
|
||||
|
||||
async function getOrderDetail(id) {
|
||||
// 对详情数据进行适配
|
||||
let res;
|
||||
@ -389,6 +404,14 @@
|
||||
if (res.code === 0) {
|
||||
state.orderInfo = res.data;
|
||||
handleOrderButtons(state.orderInfo);
|
||||
// 配送方式:门店自提
|
||||
if (res.data.pickUpStoreId) {
|
||||
const { data } = await DeliveryApi.getDeliveryPickUpStore(res.data.pickUpStoreId);
|
||||
systemStore.value = data || {};
|
||||
}
|
||||
if (state.orderInfo.deliveryType === 2 && state.orderInfo.payStatus) {
|
||||
pickUpVerifyRef.value && pickUpVerifyRef.value.markCode(res.data.pickUpVerifyCode);
|
||||
}
|
||||
} else {
|
||||
sheep.$router.back();
|
||||
}
|
||||
|
263
pages/order/pickUpVerify.vue
Normal file
263
pages/order/pickUpVerify.vue
Normal file
@ -0,0 +1,263 @@
|
||||
<template>
|
||||
<view class='order-details'>
|
||||
<!-- 自提商品核销 -->
|
||||
<view v-if="orderInfo.deliveryType === 2 && orderInfo.payStatus" class="writeOff borRadius14">
|
||||
<view class="title">核销信息</view>
|
||||
<view class="grayBg flex-center">
|
||||
<view class="pictrue">
|
||||
<image
|
||||
v-if="!!painterImageUrl"
|
||||
:src="painterImageUrl"
|
||||
:style="{width: `${state.qrcodeSize}px`, height: `${state.qrcodeSize}px`}"
|
||||
:show-menu-by-longpress="true"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="gear">
|
||||
<image :src="sheep.$url.static('/static/images/writeOff.png', 'local')"></image>
|
||||
</view>
|
||||
<view class="num">{{ orderInfo.pickUpVerifyCode }}</view>
|
||||
<view class="rules">
|
||||
<!-- TODO puhui999: 需要后端放回:使用 receiveTime 即可 -->
|
||||
<!-- <view class="item">-->
|
||||
<!-- <view class="rulesTitle flex flex-wrap align-center">-->
|
||||
<!-- 核销时间-->
|
||||
<!-- </view>-->
|
||||
<!-- <view class="info">-->
|
||||
<!-- 每日:-->
|
||||
<!-- <text class="time">2020-2-+52</text>-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
<view class="item">
|
||||
<view class="rulesTitle flex flex-wrap align-center">
|
||||
<text class="iconfont icon-shuoming1"></text>
|
||||
使用说明
|
||||
</view>
|
||||
<view class="info">可将二维码出示给店员扫描或提供数字核销码</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="orderInfo.deliveryType === 2" class="map flex flex-wrap align-center ss-row-between borRadius14">
|
||||
<view>自提地址信息</view>
|
||||
<view class="place cart-color flex flex-wrap flex-center" @tap="showMaoLocation">
|
||||
查看位置
|
||||
</view>
|
||||
</view>
|
||||
<!-- 海报画板:默认隐藏只用来生成海报。生成方式为主动调用 -->
|
||||
<l-painter
|
||||
v-if="showPainter"
|
||||
isCanvasToTempFilePath
|
||||
pathType="url"
|
||||
@success="setPainterImageUrl"
|
||||
hidden
|
||||
ref="painterRef"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import sheep from '@/sheep';
|
||||
import { reactive, ref } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
orderInfo: {
|
||||
type: Object,
|
||||
default() {},
|
||||
},
|
||||
systemStore:{
|
||||
type: Object,
|
||||
default() {},
|
||||
}
|
||||
});
|
||||
const state = reactive({
|
||||
qrcodeSize: 145
|
||||
})
|
||||
|
||||
/**
|
||||
* 打开地图
|
||||
*/
|
||||
const showMaoLocation = () => {
|
||||
console.log(props.systemStore);
|
||||
if (!props.systemStore.latitude || !props.systemStore.longitude) {
|
||||
sheep.$helper.toast('缺少经纬度信息无法查看地图!');
|
||||
return
|
||||
}
|
||||
uni.openLocation({
|
||||
latitude: props.systemStore.latitude,
|
||||
longitude: props.systemStore.longitude,
|
||||
scale: 8,
|
||||
name: props.systemStore.name,
|
||||
address: props.systemStore.areaName + props.systemStore.detailAddress,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 拨打电话
|
||||
*/
|
||||
const makePhone = () => {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: props.systemStore.phone
|
||||
})
|
||||
}
|
||||
|
||||
const painterRef = ref(); // 海报画板
|
||||
const painterImageUrl = ref(); // 海报 url
|
||||
const showPainter = ref(true)
|
||||
// 渲染海报
|
||||
const renderPoster = async (poster) => {
|
||||
await painterRef.value.render(poster);
|
||||
};
|
||||
// 获得生成的图片
|
||||
const setPainterImageUrl = (path) => {
|
||||
console.log(path,'path')
|
||||
painterImageUrl.value = path;
|
||||
showPainter.value = false
|
||||
};
|
||||
/**
|
||||
* 生成核销二维码
|
||||
*/
|
||||
const markCode = (text) => {
|
||||
renderPoster({
|
||||
css: {
|
||||
width: `${state.qrcodeSize}px`,
|
||||
height: `${state.qrcodeSize}px`
|
||||
},
|
||||
views:[
|
||||
{
|
||||
type: 'qrcode',
|
||||
text: text,
|
||||
css: {
|
||||
width: `${state.qrcodeSize}px`,
|
||||
height: `${state.qrcodeSize}px`
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
console.log(text,'text')
|
||||
}
|
||||
defineExpose({
|
||||
markCode
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
// TODO puhui999: 样式需要调整有 bug
|
||||
.borRadius14 {
|
||||
border-radius: 14rpx !important;
|
||||
}
|
||||
.cart-color {
|
||||
color: #E93323 !important;
|
||||
border: 1px solid #E93323 !important
|
||||
}
|
||||
.order-details{
|
||||
border-radius: 10rpx;
|
||||
margin: 0 20rpx 20rpx 20rpx;
|
||||
}
|
||||
.order-details .writeOff {
|
||||
background-color: #fff;
|
||||
margin-top: 15rpx;
|
||||
padding-bottom: 50rpx;
|
||||
}
|
||||
|
||||
.order-details .writeOff .title {
|
||||
font-size: 30rpx;
|
||||
color: #282828;
|
||||
height: 87rpx;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
padding: 0 24rpx;
|
||||
line-height: 87rpx;
|
||||
}
|
||||
|
||||
.order-details .writeOff .grayBg {
|
||||
background-color: #f2f5f7;
|
||||
width: 590rpx;
|
||||
height: 384rpx;
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
margin: 50rpx auto 0 auto;
|
||||
padding-top: 55rpx;
|
||||
}
|
||||
|
||||
.order-details .writeOff .grayBg .pictrue {
|
||||
width: 290rpx;
|
||||
height: 290rpx;
|
||||
}
|
||||
|
||||
.order-details .writeOff .grayBg .pictrue image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.order-details .writeOff .gear {
|
||||
width: 590rpx;
|
||||
height: 30rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.order-details .writeOff .gear image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.order-details .writeOff .num {
|
||||
background-color: #f0c34c;
|
||||
width: 590rpx;
|
||||
height: 84rpx;
|
||||
color: #282828;
|
||||
font-size: 48rpx;
|
||||
margin: 0 auto;
|
||||
border-radius: 0 0 20rpx 20rpx;
|
||||
text-align: center;
|
||||
padding-top: 4rpx;
|
||||
}
|
||||
|
||||
.order-details .writeOff .rules {
|
||||
margin: 46rpx 30rpx 0 30rpx;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
padding-top: 10rpx;
|
||||
}
|
||||
|
||||
.order-details .writeOff .rules .item {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.order-details .writeOff .rules .item .rulesTitle {
|
||||
font-size: 28rpx;
|
||||
color: #282828;
|
||||
}
|
||||
|
||||
.order-details .writeOff .rules .item .rulesTitle .iconfont {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
margin-right: 8rpx;
|
||||
margin-top: 5rpx;
|
||||
}
|
||||
|
||||
.order-details .writeOff .rules .item .info {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
margin-top: 7rpx;
|
||||
}
|
||||
|
||||
.order-details .writeOff .rules .item .info .time {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.order-details .map {
|
||||
height: 86rpx;
|
||||
font-size: 30rpx;
|
||||
color: #282828;
|
||||
line-height: 86rpx;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
margin-top: 15rpx;
|
||||
background-color: #fff;
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.order-details .map .place {
|
||||
font-size: 26rpx;
|
||||
width: 176rpx;
|
||||
height: 50rpx;
|
||||
border-radius: 25rpx;
|
||||
line-height: 50rpx;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
275
pages/user/goods_details_store/index.vue
Normal file
275
pages/user/goods_details_store/index.vue
Normal file
@ -0,0 +1,275 @@
|
||||
<template>
|
||||
<s-layout title="选择自提门店" :bgStyle="{ color: '#FFF' }">
|
||||
<view class="storeBox" ref="container">
|
||||
<view class="storeBox-box" v-for="(item, index) in state.storeList" :key="index" @tap="checked(item)">
|
||||
<view class="store-img">
|
||||
<image :src="item.logo" class="img" />
|
||||
</view>
|
||||
<view class="store-cent-left">
|
||||
<view class="store-name">{{ item.name }}</view>
|
||||
<view class="store-address line1">
|
||||
{{ item.areaName }}{{ ', ' + item.detailAddress }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="row-right ss-flex-col ss-col-center">
|
||||
<view>
|
||||
<!-- #ifdef H5 -->
|
||||
<a class="store-phone" :href="'tel:' + item.phone">
|
||||
<view class="iconfont">
|
||||
<view class="ss-rest-button">
|
||||
<text class="_icon-forward" />
|
||||
</view>
|
||||
</view>
|
||||
</a>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP -->
|
||||
<view class="store-phone" @click="call(item.phone)">
|
||||
<view class="iconfont">
|
||||
<view class="ss-rest-button">
|
||||
<text class="_icon-forward" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<view class="store-distance ss-flex ss-row-center" @tap.stop="showMaoLocation(item)">
|
||||
<text class="addressTxt" v-if="item.distance">距离{{ item.distance.toFixed(2) }}千米</text>
|
||||
<text class="addressTxt" v-else>查看地图</text>
|
||||
<view class="iconfont">
|
||||
<view class="ss-rest-button">
|
||||
<text class="_icon-forward" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</s-layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import DeliveryApi from '@/sheep/api/trade/delivery';
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import sheep from '@/sheep';
|
||||
|
||||
const LONGITUDE = 'user_longitude';
|
||||
const LATITUDE = 'user_latitude';
|
||||
const state = reactive({
|
||||
loaded: false,
|
||||
loading: false,
|
||||
storeList: [],
|
||||
system_store: {},
|
||||
locationShow: false,
|
||||
user_latitude: 0,
|
||||
user_longitude: 0,
|
||||
});
|
||||
|
||||
const call = (phone) => {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: phone,
|
||||
});
|
||||
};
|
||||
const selfLocation = () => {
|
||||
// #ifdef H5
|
||||
const jsWxSdk = sheep.$platform.useProvider('wechat').jsWxSdk;
|
||||
if (jsWxSdk.isWechat()) {
|
||||
jsWxSdk.getLocation((res) => {
|
||||
console.log(res);
|
||||
state.user_latitude = res.latitude;
|
||||
state.user_longitude = res.longitude;
|
||||
uni.setStorageSync(LATITUDE, res.latitude);
|
||||
uni.setStorageSync(LONGITUDE, res.longitude);
|
||||
getList();
|
||||
});
|
||||
} else {
|
||||
// #endif
|
||||
uni.getLocation({
|
||||
type: 'gcj02',
|
||||
success: (res) => {
|
||||
try {
|
||||
state.user_latitude = res.latitude;
|
||||
state.user_longitude = res.longitude;
|
||||
uni.setStorageSync(LATITUDE, res.latitude);
|
||||
uni.setStorageSync(LONGITUDE, res.longitude);
|
||||
} catch {
|
||||
}
|
||||
getList();
|
||||
},
|
||||
complete: () => {
|
||||
getList();
|
||||
},
|
||||
});
|
||||
// #ifdef H5
|
||||
}
|
||||
// #endif
|
||||
};
|
||||
const showMaoLocation = (e) => {
|
||||
// #ifdef H5
|
||||
const jsWxSdk = sheep.$platform.useProvider('wechat').jsWxSdk;
|
||||
if (jsWxSdk.isWechat()) {
|
||||
jsWxSdk.openLocation({
|
||||
latitude: Number(e.latitude),
|
||||
longitude: Number(e.longitude),
|
||||
name: e.name,
|
||||
address: `${e.areaName}-${e.detailAddress}`
|
||||
});
|
||||
} else {
|
||||
// #endif
|
||||
uni.openLocation({
|
||||
latitude: Number(e.latitude),
|
||||
longitude: Number(e.longitude),
|
||||
name: e.name,
|
||||
address: `${e.areaName}-${e.detailAddress}`,
|
||||
success: function() {
|
||||
console.log('success');
|
||||
},
|
||||
});
|
||||
// #ifdef H5
|
||||
}
|
||||
// #endif
|
||||
};
|
||||
|
||||
/**
|
||||
* 选中门店
|
||||
*/
|
||||
const checked = (addressInfo) => {
|
||||
uni.$emit('SELECT_PICK_UP_INFO', {
|
||||
addressInfo,
|
||||
});
|
||||
sheep.$router.back();
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取门店列表数据
|
||||
*/
|
||||
const getList = async () => {
|
||||
if (state.loading || state.loaded) {
|
||||
return;
|
||||
}
|
||||
state.loading = true;
|
||||
const { data, code } = await DeliveryApi.getDeliveryPickUpStoreList({
|
||||
latitude: state.user_latitude,
|
||||
longitude: state.user_longitude,
|
||||
});
|
||||
if (code !== 0) {
|
||||
return;
|
||||
}
|
||||
state.loading = false;
|
||||
state.storeList = data;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (state.user_latitude && state.user_longitude) {
|
||||
getList();
|
||||
} else {
|
||||
selfLocation();
|
||||
getList();
|
||||
}
|
||||
});
|
||||
onLoad(() => {
|
||||
try {
|
||||
state.user_latitude = uni.getStorageSync(LATITUDE);
|
||||
state.user_longitude = uni.getStorageSync(LONGITUDE);
|
||||
} catch (e) {
|
||||
// error
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.line1 {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
.geoPage {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.storeBox {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.storeBox-box {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 23rpx 0;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.store-cent {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.store-cent-left {
|
||||
//width: 45%;
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.store-img {
|
||||
flex: 1;
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 6rpx;
|
||||
margin-right: 22rpx;
|
||||
}
|
||||
|
||||
.store-img .img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.store-name {
|
||||
color: #282828;
|
||||
font-size: 30rpx;
|
||||
margin-bottom: 22rpx;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.store-address {
|
||||
color: #666666;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.store-phone {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
display: block;
|
||||
text-align: center;
|
||||
line-height: 48rpx;
|
||||
background-color: #e83323;
|
||||
margin-bottom: 22rpx;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.store-distance {
|
||||
font-size: 22rpx;
|
||||
color: #e83323;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-size: 20rpx;
|
||||
}
|
||||
|
||||
.row-right {
|
||||
flex: 2;
|
||||
//display: flex;
|
||||
//flex-direction: column;
|
||||
//align-items: flex-end;
|
||||
//width: 33.5%;
|
||||
}
|
||||
</style>
|
@ -4,18 +4,18 @@ export default {
|
||||
// 微信相关
|
||||
wechat: {
|
||||
// 小程序订阅消息
|
||||
subscribeTemplate: (params) =>
|
||||
request({
|
||||
url: 'third/wechat/subscribeTemplate',
|
||||
method: 'GET',
|
||||
params: {
|
||||
platform: 'miniProgram',
|
||||
},
|
||||
custom: {
|
||||
showError: false,
|
||||
showLoading: false,
|
||||
},
|
||||
}),
|
||||
// subscribeTemplate: (params) =>
|
||||
// request({
|
||||
// url: 'third/wechat/subscribeTemplate',
|
||||
// method: 'GET',
|
||||
// params: {
|
||||
// platform: 'miniProgram',
|
||||
// },
|
||||
// custom: {
|
||||
// showError: false,
|
||||
// showLoading: false,
|
||||
// },
|
||||
// }),
|
||||
|
||||
// 获取微信小程序码
|
||||
// TODO @puhui999:这个接口,挪到 /Users/yunai/Java/yudao-mall-uniapp/sheep/api/member/social.js
|
||||
|
@ -1,4 +1,5 @@
|
||||
import request from '@/sheep/request';
|
||||
import { isEmpty } from '@/sheep/helper/utils';
|
||||
|
||||
const OrderApi = {
|
||||
// 计算订单信息
|
||||
@ -13,6 +14,15 @@ const OrderApi = {
|
||||
if (!(data.addressId > 0)) {
|
||||
delete data2.addressId;
|
||||
}
|
||||
if (!(data.pickUpStoreId > 0)) {
|
||||
delete data2.pickUpStoreId;
|
||||
}
|
||||
if (isEmpty(data.receiverName)) {
|
||||
delete data2.receiverName;
|
||||
}
|
||||
if (isEmpty(data.receiverMobile)) {
|
||||
delete data2.receiverMobile;
|
||||
}
|
||||
if (!(data.combinationActivityId > 0)) {
|
||||
delete data2.combinationActivityId;
|
||||
}
|
||||
|
BIN
static/images/writeOff.png
Normal file
BIN
static/images/writeOff.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
Loading…
Reference in New Issue
Block a user