新增营销系统、分销系统、会员功能、门店、提现功能
This commit is contained in:
@ -1,8 +1,7 @@
|
||||
<script setup>
|
||||
import UvNavbar from "@/uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue";
|
||||
import { useRouter } from "@/hooks/useRouter";
|
||||
import { onLoad, onPageScroll, onShow } from "@dcloudio/uni-app";
|
||||
import { ref, unref } from "vue";
|
||||
import {onLoad, onPageScroll, onShow} from "@dcloudio/uni-app";
|
||||
import { nextTick, onBeforeUnmount, ref, unref } from "vue";
|
||||
import { useMainStore } from '@/store/store';
|
||||
import { storeToRefs } from "pinia";
|
||||
import { orderConfirm, orderCreate } from "@/api/order";
|
||||
@ -15,42 +14,71 @@ import { doPayment, PayType } from "@/utils/paymentUtils";
|
||||
import CouponSelect from "@/pages/submitOrder/components/coupon-select.vue";
|
||||
import Header from "@/components/Header/index.vue"
|
||||
import { useScroll } from "@/hooks/useScroll";
|
||||
import { nextIcon } from "@/utils/images";
|
||||
|
||||
import { nextIcon, shopIcon } from "@/utils/images";
|
||||
import { emitter } from "@/utils/emitter";
|
||||
import {h5InWeChat} from "@/utils";
|
||||
import Login from "@/pages/login/login.vue";
|
||||
// ==================================== hooks =====================================
|
||||
const {scrollTop} = useScroll()
|
||||
onPageScroll(()=>{})
|
||||
const {getParams, push, goBack} = useRouter()
|
||||
const {toast, loading, hideLoading} = useInterface();
|
||||
const mainStore = useMainStore();
|
||||
const {selectAddress, defaultAddress, address} = storeToRefs(mainStore);
|
||||
const routerParams = ref({})
|
||||
const selectCouponRef = ref(false)
|
||||
const couponList = ref([])
|
||||
const selectCoupon = ref({})
|
||||
const currentCouponId = ref(0)
|
||||
const cartIds = ref('')
|
||||
const flag = ref(false)
|
||||
|
||||
const selectCouponFn = async (coupon) => {
|
||||
currentCouponId.value = coupon.couponId
|
||||
const campaignType = ref(0)
|
||||
const zeroPrice = ref(false) // 本单支付金额是否为0
|
||||
/**
|
||||
* 重新计算价格
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
async function calculateOrder() {
|
||||
orderDetail.value = await orderConfirm({
|
||||
cartId: unref(routerParams).cartId,
|
||||
orderType: unref(routerParams).orderType,
|
||||
addressId: unref(selectAddress)?.id || undefined,
|
||||
shippingType: addressTabSelect.value, // 默认快递 1快递2门店
|
||||
storeId: shopSelect.value?.id,
|
||||
useIntegral: useIntegral.value.length > 0,
|
||||
couponId: currentCouponId.value
|
||||
})
|
||||
console.log(orderDetail.value)
|
||||
// 余额为0 自动走余额支付
|
||||
if (orderDetail.value.priceGroup.totalPrice <= 0) {
|
||||
payType.value = PayType["1"]
|
||||
zeroPrice.value = true
|
||||
toast({title: '支付金额为0.00,自动选择余额支付', icon: 'none', duration: 3000})
|
||||
} else {
|
||||
zeroPrice.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// ==================================== 优惠券相关 ===========================================
|
||||
const selectCouponRef = ref(false)
|
||||
const currentCouponId = ref(undefined)
|
||||
const selectCouponFn = async (coupon) => {
|
||||
currentCouponId.value = coupon.couponId
|
||||
await calculateOrder()
|
||||
selectCouponRef.value.close()
|
||||
}
|
||||
|
||||
const addressTabSelect = ref(0) // 提货方式
|
||||
|
||||
const showCouponSelect = (index) => {
|
||||
if (index === 0) {
|
||||
selectCouponRef.value.open()
|
||||
}
|
||||
}
|
||||
|
||||
// =================================== 配送方式相关 ================================================
|
||||
const addressTabSelect = ref(1) // 提货方式
|
||||
|
||||
/**
|
||||
* 选择提货方式
|
||||
* @param tab
|
||||
*/
|
||||
function changeAddressTab(tab) {
|
||||
if (tab.value === 1) {
|
||||
toast({title: '敬请期待'})
|
||||
} else {
|
||||
addressTabSelect.value = tab.value
|
||||
}
|
||||
addressTabSelect.value = tab.value
|
||||
shopSelect.value = undefined
|
||||
doGetInitConfirmOrder()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,7 +90,6 @@ function gotoSelectAddress() {
|
||||
|
||||
/**
|
||||
* 获取默认选择的地址
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function doGetSelectAddress() {
|
||||
// store内部没有地址,就先去获取地址
|
||||
@ -76,58 +103,104 @@ async function doGetSelectAddress() {
|
||||
// 没有默认地址设置默认地址
|
||||
if (!selectAddress.value || !selectAddress.value?.id) {
|
||||
defaultAddress.value && defaultAddress.value.id ? mainStore.setSelectAddress(defaultAddress.value.id) : mainStore.setSelectAddress(unref(address)[0].id)
|
||||
doGetInitConfirmOrder()
|
||||
}
|
||||
}
|
||||
|
||||
const shopSelect = ref(null) // 当前选择的店铺
|
||||
|
||||
// 注册事件监听
|
||||
emitter.on('selectShop', (res) => {
|
||||
// 处理门店选择逻辑
|
||||
shopSelect.value = res
|
||||
doGetInitConfirmOrder()
|
||||
})
|
||||
emitter.on('selectAddress', async () => {
|
||||
// 处理门店选择逻辑
|
||||
await doGetSelectAddress()
|
||||
await doGetInitConfirmOrder()
|
||||
})
|
||||
|
||||
/**
|
||||
* 选择店铺
|
||||
*/
|
||||
function selectShop() {
|
||||
push({url: '/pages/submitOrder/shopSelect'}, {data: {shopSelect: shopSelect.value}})
|
||||
}
|
||||
|
||||
// =============================== 订单信息相关 ======================================================
|
||||
const flag = ref(false)
|
||||
|
||||
const payType = ref(PayType["0"]) // 支付方式
|
||||
|
||||
// 初始订单信息
|
||||
const useIntegral = ref([1]) // 是否使用积分 length>0使用积分
|
||||
|
||||
// 订单信息
|
||||
const orderDetail = ref({
|
||||
cartInfo: [],
|
||||
priceGroup: {
|
||||
costPrice: 0, payIntegral: 0, storeFreePostage: 0, storePostage: 0, totalPrice: 0, vipPrice: 0
|
||||
costPrice: 0,
|
||||
payIntegral: 0,
|
||||
storeFreePostage: 0,
|
||||
storePostage: 0,
|
||||
totalPrice: 0,
|
||||
vipPrice: 0
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 获取初始订单信息
|
||||
* todo 如果没有地址,选择地址后需要重新调用
|
||||
* @returns {Promise<void>}
|
||||
* 调用此方法可以重新生成订单信息(包括价格信息)
|
||||
*/
|
||||
async function doGetInitConfirmOrder() {
|
||||
orderDetail.value = await orderConfirm({
|
||||
cartId: unref(routerParams).cartId,
|
||||
addressId: unref(selectAddress)?.id || undefined
|
||||
})
|
||||
await calculateOrder()
|
||||
cartIds.value = unref(routerParams).cartId
|
||||
currentCouponId.value = orderDetail.value.priceGroup.couponId
|
||||
flag.value = true
|
||||
}
|
||||
|
||||
const subLoading = ref(false) // 加载中
|
||||
const showCouponSelect = (index) => {
|
||||
if (index === 0) {
|
||||
selectCouponRef.value.open()
|
||||
}
|
||||
/**
|
||||
* 改变是否使用积分
|
||||
*/
|
||||
function handleUseIntegralChange() {
|
||||
nextTick(() => {
|
||||
doGetInitConfirmOrder()
|
||||
})
|
||||
}
|
||||
|
||||
const subLoading = ref(false) // 加载中
|
||||
|
||||
/**
|
||||
* 提交订单
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
async function handleConfirm() {
|
||||
if (!unref(selectAddress) || !unref(selectAddress).id) {
|
||||
if (addressTabSelect.value === 1 && (!unref(selectAddress) || !unref(selectAddress).id)) {
|
||||
toast({title: '请先选择地址'})
|
||||
return
|
||||
}
|
||||
if (addressTabSelect.value === 2 && !shopSelect.value) {
|
||||
toast({title: '请先选择门店'})
|
||||
return
|
||||
}
|
||||
subLoading.value = true
|
||||
try {
|
||||
const payInfo = await doCreateServiceOrder()
|
||||
// 去拉取支付
|
||||
await doPayment({type: payType.value, payInfo})
|
||||
await doPayment({type: payType.value, payInfo,isGroup:routerParams.value.campaignType===1})
|
||||
// #ifndef H5
|
||||
push({url: '/pages/payStatus/index'}, {type: 'redirectTo'})
|
||||
push({url: '/pages/payStatus/index'}, { data: {campaignType: campaignType.value},type: 'redirectTo'})
|
||||
// #endif
|
||||
// 处理微信内h5
|
||||
// #ifdef H5
|
||||
if(h5InWeChat()){
|
||||
push({url: '/pages/payStatus/index'}, { data: {campaignType: campaignType.value},type: 'redirectTo'})
|
||||
}
|
||||
// #endif
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
toast({title: '支付失败'})
|
||||
push({url: '/pages/payStatus/index'}, {type: 'redirectTo'})
|
||||
push({url: '/pages/payStatus/index'}, {data: {campaignType: campaignType.value} , type: 'redirectTo'})
|
||||
} finally {
|
||||
subLoading.value = false
|
||||
mainStore.cartId = null
|
||||
@ -140,9 +213,10 @@ async function handleConfirm() {
|
||||
async function doCreateServiceOrder() {
|
||||
try {
|
||||
loading({title: '订单创建中...'})
|
||||
const res = await orderCreate({
|
||||
const data = {
|
||||
key: unref(orderDetail).orderKey,
|
||||
addressId: unref(selectAddress).id,
|
||||
addressId: unref(selectAddress) && unref(selectAddress).id,
|
||||
storeId: unref(shopSelect) && unref(shopSelect).id,
|
||||
bargainId: 0,
|
||||
combinationId: 0,
|
||||
couponId: currentCouponId.value,
|
||||
@ -151,16 +225,41 @@ async function doCreateServiceOrder() {
|
||||
pinkId: 0,
|
||||
seckillId: 0,
|
||||
shippingType: addressTabSelect.value,
|
||||
useIntegral: 0,
|
||||
isChannel: 1,
|
||||
});
|
||||
distributorId: unref(routerParams)?.distributorId, // 分销商ID
|
||||
useIntegral: useIntegral.value.length > 0,
|
||||
orderType: unref(routerParams)?.orderType,
|
||||
}
|
||||
setActivityData(data)
|
||||
const res = await orderCreate(data);
|
||||
return res.result
|
||||
} finally {
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
const {scrollTop} = useScroll()
|
||||
/**
|
||||
* 设置活动参数
|
||||
* @param data
|
||||
*/
|
||||
function setActivityData(data) {
|
||||
// 处理活动数据 路由参数 orderType 1普通下单 2活动下单
|
||||
if (routerParams.value.orderType !== 2) return
|
||||
// 活动商品
|
||||
data.campaignType = routerParams.value.campaignType // 1拼团 2秒杀 3砍价
|
||||
campaignType.value = routerParams.value.campaignType
|
||||
data.campaignDetailId = routerParams.value.campaignDetailId // 活动营销ID
|
||||
// 拼团 路由参数 campaignType 1拼团活动
|
||||
if (routerParams.value.campaignType !== 1) return;
|
||||
data.teamworkType = routerParams.value.teamworkType // 1发起拼团 2加入
|
||||
data.teamworkType === 2 ? data.teamworkId = routerParams.value.teamworkId : void (0) // 加入拼团的id
|
||||
}
|
||||
|
||||
|
||||
// =============================== 生命周期 ========================================
|
||||
const routerParams = ref({})
|
||||
const cartIds = ref('')
|
||||
|
||||
|
||||
/**
|
||||
* 检查路由参数
|
||||
@ -173,16 +272,22 @@ function checkRouterParam(params) {
|
||||
routerParams.value = params
|
||||
}
|
||||
|
||||
|
||||
onLoad(async options => {
|
||||
try {
|
||||
const params = getParams(options)
|
||||
await checkRouterParam(params)
|
||||
await doGetInitConfirmOrder()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
onShow(async ()=>{
|
||||
onBeforeUnmount(() => {
|
||||
emitter.clear('selectShop')
|
||||
emitter.clear('selectAddress')
|
||||
})
|
||||
|
||||
onShow(async () => {
|
||||
await doGetInitConfirmOrder()
|
||||
await doGetSelectAddress()
|
||||
})
|
||||
</script>
|
||||
@ -195,10 +300,7 @@ onShow(async ()=>{
|
||||
</Header>
|
||||
<!-- 地址 -->
|
||||
<view class="address-box">
|
||||
<view
|
||||
class="address-box__inner"
|
||||
|
||||
>
|
||||
<view class="address-box__inner">
|
||||
<view class="tab-box">
|
||||
<!-- tab top -->
|
||||
<view class="title-row flex flex-ai__center flex-jc__sb">
|
||||
@ -213,47 +315,69 @@ onShow(async ()=>{
|
||||
</view>
|
||||
</view>
|
||||
<!-- address info -->
|
||||
<view
|
||||
class="address-row flex flex-ai__center flex-jc__sb"
|
||||
v-if="address.length>0"
|
||||
@click="gotoSelectAddress"
|
||||
>
|
||||
<template v-if="addressTabSelect === 1">
|
||||
<view
|
||||
class="flex flex-ai__center"
|
||||
v-if="selectAddress"
|
||||
class="address-row flex flex-ai__center flex-jc__sb"
|
||||
v-if="address.length>0"
|
||||
@click="gotoSelectAddress"
|
||||
>
|
||||
<uv-icon
|
||||
name="map"
|
||||
size="22"
|
||||
/>
|
||||
<view class="info">
|
||||
<view>
|
||||
{{ selectAddress.realName }} {{ selectAddress.phone }}
|
||||
</view>
|
||||
<view class="address-info">
|
||||
{{ selectAddress.province }} - {{ selectAddress.city }}- {{ selectAddress.district }} -
|
||||
{{ selectAddress.detail }}
|
||||
<view
|
||||
class="flex flex-ai__center"
|
||||
v-if="selectAddress"
|
||||
>
|
||||
<uv-icon
|
||||
name="map"
|
||||
size="22"
|
||||
/>
|
||||
<view class="info">
|
||||
<view>
|
||||
{{ selectAddress.realName }} {{ selectAddress.phone }}
|
||||
</view>
|
||||
<view class="address-info">
|
||||
{{ selectAddress.province }} - {{ selectAddress.city }}- {{ selectAddress.district }} -
|
||||
{{ selectAddress.detail }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<image
|
||||
class="arrow-icon"
|
||||
:src="nextIcon"
|
||||
alt=""
|
||||
/>
|
||||
</view>
|
||||
<image
|
||||
class="arrow-icon"
|
||||
:src="nextIcon"
|
||||
alt=""
|
||||
/>
|
||||
</view>
|
||||
<view
|
||||
class="address-row flex flex-ai__center flex-jc__sb"
|
||||
v-else
|
||||
@click="gotoSelectAddress"
|
||||
>
|
||||
点击添加地址
|
||||
<image
|
||||
class="arrow-icon"
|
||||
:src="nextIcon"
|
||||
alt=""
|
||||
/>
|
||||
</view>
|
||||
<view
|
||||
class="address-row flex flex-ai__center flex-jc__sb"
|
||||
v-else
|
||||
@click="gotoSelectAddress"
|
||||
>
|
||||
点击添加地址
|
||||
<image
|
||||
class="arrow-icon"
|
||||
:src="nextIcon"
|
||||
alt=""
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
<!-- 门店INFO -->
|
||||
<template v-else>
|
||||
<view
|
||||
class="shop-select"
|
||||
@click="selectShop">
|
||||
<image :src="shopIcon" />
|
||||
<view class="right flex flex-jc__sb flex-ai__center">
|
||||
<view
|
||||
v-if="shopSelect">
|
||||
<view>{{ shopSelect.storeIntro }}</view>
|
||||
<view style="font-size: 23rpx;font-weight: normal">{{ shopSelect.address }}</view>
|
||||
</view>
|
||||
<view
|
||||
v-else>
|
||||
点击选择门店
|
||||
</view>
|
||||
<u-icon name="arrow-right" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -278,11 +402,11 @@ onShow(async ()=>{
|
||||
imgWidth="200rpx"
|
||||
>
|
||||
<template #options="{goods}">
|
||||
<view class="goods-detail">
|
||||
<view class="goods-detail" style="width: 100%">
|
||||
<view class="sku-row">
|
||||
{{ goods.attrInfo.sku }}
|
||||
</view>
|
||||
<view class="price-row flex flex-ai__center flex-jc__sb">
|
||||
<view class="price-row flex flex-ai__center flex-jc__sb" style="width:100%;">
|
||||
<view class="price flex flex-ai__end">
|
||||
¥{{ sku.truePrice }}
|
||||
<span class="old-price">
|
||||
@ -314,7 +438,7 @@ onShow(async ()=>{
|
||||
<view class="label">{{ row.label }}</view>
|
||||
<view class="value">
|
||||
{{ row.prefix }}
|
||||
{{ orderDetail["priceGroup"][row.field]?.toFixed(2) }}
|
||||
{{ orderDetail["priceGroup"][row.field]?.toFixed(2) || '0.00' }}
|
||||
<image
|
||||
v-if="row.field=== 'couponPrice'"
|
||||
class="arrow-icon"
|
||||
@ -350,7 +474,8 @@ onShow(async ()=>{
|
||||
<view class="pay-item">
|
||||
<uv-radio
|
||||
:name="payItem.type"
|
||||
:disabled="payItem.disabled"
|
||||
:disabled="
|
||||
payItem.disabled || (payItem.type===PayType['0']&&zeroPrice) || (mainStore.user.nowMoney===0 &&!zeroPrice&&payItem.type===PayType['1'])"
|
||||
>
|
||||
<view class="flex flex-ai__center flex-jc__sb">
|
||||
<view
|
||||
@ -362,8 +487,11 @@ onShow(async ()=>{
|
||||
/>
|
||||
</view>
|
||||
<view class="text">
|
||||
<view>
|
||||
<view class="flex flex-nowrap flex-ai__end" style="white-space: nowrap">
|
||||
{{ payItem.label }}
|
||||
<span v-if="payItem.type===PayType['1']" style="font-size: 16rpx;white-space: nowrap;">
|
||||
({{mainStore.user.nowMoney}}元)
|
||||
</span>
|
||||
</view>
|
||||
<view class="e-text">
|
||||
{{ payItem.eLabel }}
|
||||
@ -386,10 +514,42 @@ onShow(async ()=>{
|
||||
<view class="label">{{ row.label }}</view>
|
||||
<view class="value">
|
||||
{{ row.prefix }}
|
||||
{{ orderDetail["priceGroup"][row.field]?.toFixed(2) }}
|
||||
{{ orderDetail["priceGroup"][row.field]?.toFixed(2) || '0.00' }}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<!--会员 -->
|
||||
<view
|
||||
class="row flex flex-ai__center flex-jc__sb"
|
||||
v-if="orderDetail.priceGroup.isVip">
|
||||
<view class="label">会员优惠</view>
|
||||
<view class="value">
|
||||
-¥{{ orderDetail.priceGroup.vipDeductionAmount.toFixed(2) }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="row flex flex-ai__center flex-jc__sb"
|
||||
v-if="orderDetail.priceGroup.enableIntegral">
|
||||
<view class="label">积分抵扣</view>
|
||||
<view class="value flex flex-ai__center">
|
||||
当前积分:
|
||||
<text class="primary-color">{{ orderDetail.priceGroup.integral }}</text>
|
||||
<u-checkbox-group
|
||||
style="margin-left: 10rpx;margin-top: 3rpx;"
|
||||
shape="circle"
|
||||
activeColor="#ee6d46"
|
||||
v-model="useIntegral"
|
||||
@change="handleUseIntegralChange">
|
||||
<u-checkbox
|
||||
label=" "
|
||||
:name="1" />
|
||||
</u-checkbox-group>
|
||||
<template v-if="useIntegral.length>0">
|
||||
-¥{{ orderDetail.priceGroup.deductionPrice.toFixed(2) }}
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部操作条 -->
|
||||
@ -477,13 +637,26 @@ $bottomHeight: 100rpx;
|
||||
.address-info {
|
||||
color: #333333;
|
||||
margin: 10rpx 0;
|
||||
//max-width: 60vw;
|
||||
//overflow: hidden;
|
||||
//white-space: nowrap;
|
||||
//text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.shop-select {
|
||||
@include usePadding(42, 42);
|
||||
@include useFlex(flex-start, center);
|
||||
|
||||
.right {
|
||||
flex-grow: 1;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
image {
|
||||
margin-right: 20rpx;
|
||||
width: 35rpx;
|
||||
height: 35rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -554,6 +727,7 @@ $bottomHeight: 100rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.pay-box {
|
||||
|
||||
:deep(.uv-radio-group ) {
|
||||
@ -590,7 +764,7 @@ $bottomHeight: 100rpx;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: $bottomHeight;
|
||||
bottom: 0;
|
||||
bottom: env(safe-area-inset-bottom);
|
||||
left: 0;
|
||||
background: $white-color;
|
||||
|
||||
@ -617,4 +791,5 @@ $bottomHeight: 100rpx;
|
||||
max-height: 1000rpx;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user