功能完善

This commit is contained in:
2024-04-13 17:20:09 +08:00
parent be328f9243
commit 23af4c25e3
15 changed files with 253 additions and 90 deletions

View File

@@ -4,6 +4,7 @@ export interface OrderBean {
allowIntegral: boolean; allowIntegral: boolean;
bizId: string; bizId: string;
classify: number; classify: number;
address: any,
companyId: string; companyId: string;
consignTime: string; consignTime: string;
consumerId: string; consumerId: string;
@@ -71,4 +72,7 @@ export interface OrderBean {
updated: boolean; updated: boolean;
useGold: number; useGold: number;
wholePrice: number; wholePrice: number;
//extra field
countdown: number;
} }

View File

@@ -12,7 +12,8 @@
<view class='sku-view c-flex-column'> <view class='sku-view c-flex-column'>
<view class='sku-title'>颜色</view> <view class='sku-title'>颜色</view>
<view class='sku-color-list c-flex-row'> <view class='sku-color-list c-flex-row'>
<view class='sku-item' :class='{"sku-item-active":currentColorIndex==index}' <view class='sku-item'
:class='{"sku-item-active":currentColorIndex==index}'
v-for='(item, index) in skuColorList' :key='index' v-for='(item, index) in skuColorList' :key='index'
@click='colorChange(index)'> @click='colorChange(index)'>
<text>{{ item }}</text> <text>{{ item }}</text>
@@ -22,11 +23,13 @@
<view class='sku-title' style='margin-top: 43rpx'>尺码</view> <view class='sku-title' style='margin-top: 43rpx'>尺码</view>
<view class='sku-color-list c-flex-row'> <view class='sku-color-list c-flex-row'>
<view class='sku-item' <view class='sku-item'
:class='{"sku-item-active":currentSizeIndex==index,"sku-item-disabled":item.existingNumber<=-1}' v-if='(skuSizeList?.length||0)>0'
:class='{"sku-item-active":currentSizeIndex==index,"sku-item-disabled":item.existingNumber<=0}'
v-for='(item, index) in skuSizeList' :key='index' v-for='(item, index) in skuSizeList' :key='index'
@click='sizeChange(index)'> @click='sizeChange(index)'>
<text>{{ item.sizeName }}</text> <text>{{ item.sizeName }}</text>
</view> </view>
<text v-else style='color: #999999;font-size: 30rpx'>暂无库存</text>
</view> </view>
<view class='c-flex-row' style='margin-top: 52rpx'> <view class='c-flex-row' style='margin-top: 52rpx'>
@@ -41,7 +44,9 @@
</view> </view>
</view> </view>
</view> </view>
<button class='primary-button' @click='confirm'>确定</button> <button class='primary-button' :plain='currentSizeIndex<=0' :disabled='currentSizeIndex<=0' @click='confirm'>
确定
</button>
</view> </view>
</view> </view>
</uni-popup> </uni-popup>
@@ -65,7 +70,7 @@ const popupRef = ref();
const goodsDetailBean = ref<GoodsBean>(); const goodsDetailBean = ref<GoodsBean>();
const skuColorList = ref<string[]>([]); const skuColorList = ref<string[]>([]);
const currentColorIndex = ref(0); const currentColorIndex = ref(0);
const currentSizeIndex = ref(0); const currentSizeIndex = ref(-1);
const goodsCount = ref(1); const goodsCount = ref(1);
let callback: Function; let callback: Function;
@@ -96,25 +101,31 @@ const show = async (goodsId: string, fn: Function) => {
sizeChange(sizeIndex || 0); sizeChange(sizeIndex || 0);
goodsCount.value = props.exists?.count; goodsCount.value = props.exists?.count;
} }
if(skuSizeList) {
// skuSizeList.value![2].existingNumber = 2;
}
}; };
const skuSizeList = computed(() => { const skuSizeList = computed(() => {
const currentColorName = skuColorList.value[currentColorIndex.value]; const currentColorName = skuColorList.value[currentColorIndex.value];
return goodsDetailBean.value?.stocks?.filter((res: { colorName: string }) => { let sizeList = goodsDetailBean.value?.stocks?.filter((res: { colorName: string }) => {
return res.colorName === currentColorName; return res.colorName === currentColorName;
}); });
currentSizeIndex.value = sizeList?.findIndex(res => res.existingNumber > 0) || 0;
return sizeList;
}); });
const close = () => {
popupRef.value.close();
};
const colorChange = (index: number) => { const colorChange = (index: number) => {
currentColorIndex.value = index; currentColorIndex.value = index;
}; };
const sizeChange = (index: number) => { const sizeChange = (index: number) => {
currentSizeIndex.value = index; if((skuSizeList.value![index].existingNumber || 0) <= 0) {
showToast('库存不足');
} else {
currentSizeIndex.value = index;
}
}; };
const countChange = (isPlus: boolean) => { const countChange = (isPlus: boolean) => {
@@ -140,6 +151,10 @@ const confirm = () => {
popupRef.value.close(); popupRef.value.close();
}; };
const close = () => {
popupRef.value.close();
};
defineExpose({ defineExpose({
show show
}); });
@@ -262,6 +277,7 @@ defineExpose({
.primary-button { .primary-button {
width: 100%; width: 100%;
margin-top: 50rpx; margin-top: 50rpx;
border: none;
} }
} }
} }

View File

@@ -14,12 +14,17 @@
</template> </template>
<script lang='ts' setup> <script lang='ts' setup>
defineProps({ const props = defineProps({
titles: { titles: {
type: Object as PropType<string[]>, type: Object as PropType<string[]>,
default: '' default: ''
}, },
index: {
type: Number,
default: 0
},
fixed: { fixed: {
type: Boolean, type: Boolean,
default: true default: true
@@ -42,6 +47,10 @@ defineProps({
const emits = defineEmits(['change']); const emits = defineEmits(['change']);
const currentIndex = ref<number>(0); const currentIndex = ref<number>(0);
watch(() => props.index, (newVal) => {
currentIndex.value = newVal;
});
const onChange = (index: number) => { const onChange = (index: number) => {
currentIndex.value = index; currentIndex.value = index;
emits('change', index); emits('change', index);

View File

@@ -26,7 +26,7 @@
</view> </view>
<view class='bottom-view c-flex-row'> <view class='bottom-view c-flex-row'>
<sqb-pay @bindnavigateTo='navigateTo' <sqb-pay @navigateTo='navigateTo'
:return_url='buildSqbParams.return_url' :return_url='buildSqbParams.return_url'
:total_amount='buildSqbParams.total_amount' :total_amount='buildSqbParams.total_amount'
:terminal_sn='buildSqbParams.terminal_sn' :terminal_sn='buildSqbParams.terminal_sn'
@@ -49,6 +49,7 @@ import { OrderBean } from '@/api/order/types';
import { parseParameter, sortASCII } from '@/utils'; import { parseParameter, sortASCII } from '@/utils';
import { hexMD5 } from '@/utils/common/md5'; import { hexMD5 } from '@/utils/common/md5';
import { useUserStore } from '@/store'; import { useUserStore } from '@/store';
import { handlePayResult } from '@/utils/order';
const userState = useUserStore(); const userState = useUserStore();
const { terminalInfo } = storeToRefs(userState); const { terminalInfo } = storeToRefs(userState);
@@ -78,11 +79,12 @@ const buildSqbParams = computed(() => {
}); });
const navigateTo = (e: any) => { const navigateTo = (e: any) => {
uni.redirectTo({ console.log('----------->>>>>navigateTo ', e);
url: e.detail.url, handlePayResult(orderBean.value?.id, e, {
fail(e) { onSuccess: () => {
uni.showToast({ pay({
title: '支付失败' 'orderId': orderBean.value?.id,
'result': 'xxx'
}); });
} }
}); });
@@ -95,14 +97,8 @@ const payment = () => {
'terminal_key': terminalInfo.value.terminalKey, 'terminal_key': terminalInfo.value.terminalKey,
'terminal_sn': terminalInfo.value.terminalSn 'terminal_sn': terminalInfo.value.terminalSn
}; };
progress(params); progress(params);
pay({
'orderId': orderBean.value?.id,
'result': '{payResult:xxx}'
});
}; };
</script> </script>
<style lang='scss' scoped> <style lang='scss' scoped>

View File

@@ -140,7 +140,7 @@ const swiperChange = (e: any) => {
image { image {
width: 100%; width: 100%;
height: 100%; height: 520rpx;
} }
} }
@@ -154,8 +154,11 @@ const swiperChange = (e: any) => {
.indicator-view { .indicator-view {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
position: relative; position: absolute;
justify-content: center; justify-content: center;
left: 0;
right: 0;
top: -20rpx;
.normal { .normal {
width: 16rpx; width: 16rpx;
@@ -235,7 +238,7 @@ const swiperChange = (e: any) => {
} }
.divider { .divider {
margin: 0 40rpx; margin: 0 30rpx;
width: 0.5rpx; width: 0.5rpx;
height: 100%; height: 100%;
background: #C7C7C7; background: #C7C7C7;

View File

@@ -16,7 +16,7 @@
</view> </view>
</scroll-view> </scroll-view>
<scroll-view class='goods-list' :scroll-y='true' type='custom'> <scroll-view class='goods-list' :scroll-y='true' type='custom' @scrolltolower='loadMore'>
<grid-view type='masonry' :cross-axis-count='2'> <grid-view type='masonry' :cross-axis-count='2'>
<view v-for='(item, index) in goodsList' :key='index' class='goods-item' <view v-for='(item, index) in goodsList' :key='index' class='goods-item'
@click.stop='goPath(`/pages/mall/subs/goods/detail?goodsId=${item.goodsId}`)'> @click.stop='goPath(`/pages/mall/subs/goods/detail?goodsId=${item.goodsId}`)'>
@@ -43,7 +43,7 @@
<script setup lang='ts'> <script setup lang='ts'>
import SkuDialog from '@/components/sku-dialog.vue'; import SkuDialog from '@/components/sku-dialog.vue';
import { assetsUrl } from '@/utils/assets'; import { assetsUrl } from '@/utils/assets';
import { goLogin, goPath, isLogin } from '@/utils'; import { goLogin, goPath, isLogin, showToast } from '@/utils';
import { getCategoryList, getGoodsList } from '@/api/goods'; import { getCategoryList, getGoodsList } from '@/api/goods';
import { CategoryBean, GoodsBean } from '@/api/goods/types'; import { CategoryBean, GoodsBean } from '@/api/goods/types';
import useShoppingCartStore from '@/store/modules/shoppingcart'; import useShoppingCartStore from '@/store/modules/shoppingcart';
@@ -58,6 +58,7 @@ const skuDialogRef = ref();
const categoryList = ref<CategoryBean[]>([]); const categoryList = ref<CategoryBean[]>([]);
const categorySelectedIndex = ref<number>(0); const categorySelectedIndex = ref<number>(0);
const goodsList = ref<GoodsBean[]>([]); const goodsList = ref<GoodsBean[]>([]);
const currentPageNum = ref<number>(1);
onLoad(() => { onLoad(() => {
if(!isLogin()) { if(!isLogin()) {
@@ -87,18 +88,27 @@ const changeCategory = async (index: number) => {
await fetchGoodsList(); await fetchGoodsList();
}; };
const fetchGoodsList = async () => { const fetchGoodsList = async (refresh: boolean = true) => {
currentPageNum.value = refresh ? 1 : currentPageNum.value + 1;
const { rows } = await getGoodsList({ const { rows } = await getGoodsList({
page: { page: {
pageNum: 1, pageNum: currentPageNum.value,
pageSize: 100, pageSize: 30,
bean: { bean: {
keyword: '', keyword: '',
typeIds: [categoryList.value[categorySelectedIndex.value].typeId] typeIds: [categoryList.value[categorySelectedIndex.value].typeId]
} }
} }
}); });
goodsList.value = rows; if(refresh) {
goodsList.value = rows;
} else {
goodsList.value = goodsList.value.concat(rows);
}
};
const loadMore = () => {
fetchGoodsList(false);
}; };
const randomImageHeight = () => { const randomImageHeight = () => {
@@ -114,6 +124,7 @@ const getRandomFloatInRange = (a: number, b: number) => {
const addShoppingCart = (goodsBean: GoodsBean) => { const addShoppingCart = (goodsBean: GoodsBean) => {
skuDialogRef.value.show(goodsBean.goodsId, (e: GoodsBean) => { skuDialogRef.value.show(goodsBean.goodsId, (e: GoodsBean) => {
shoppingCartStore.save(e); shoppingCartStore.save(e);
showToast('添加购物车成功');
}); });
}; };
</script> </script>

View File

@@ -94,14 +94,14 @@
<view class='payment-way c-flex-row' @click.stop='changePayment'> <view class='payment-way c-flex-row' @click.stop='changePayment'>
<text>支付方式</text> <text>支付方式</text>
<view>{{ paymentType === 0 ? '微信支付' : '余额' }} <view>{{ paymentType === 0 ? '微信支付' : '余额' }}
<image :src='assetsUrl("ic_arrow_right_gray.png")' /> <image style='display: none' :src='assetsUrl("ic_arrow_right_gray.png")' />
</view> </view>
</view> </view>
<view class='bottom-view c-flex-row'> <view class='bottom-view c-flex-row'>
<text>合计</text> <text>合计</text>
<text>{{ orderBean?.totalPrice || 0 }}</text> <text>{{ orderBean?.totalPrice || 0 }}</text>
<sqb-pay @bindnavigateTo='navigateTo' <sqb-pay @navigateTo='navigateTo'
:return_url='buildSqbParams.return_url' :return_url='buildSqbParams.return_url'
:total_amount='buildSqbParams.total_amount' :total_amount='buildSqbParams.total_amount'
:terminal_sn='buildSqbParams.terminal_sn' :terminal_sn='buildSqbParams.terminal_sn'
@@ -130,6 +130,7 @@ import { getPaymentList, orderCreate, overPayment } from '@/api/order';
import { CouponBean } from '@/api/user/types'; import { CouponBean } from '@/api/user/types';
import { OrderBean } from '@/api/order/types'; import { OrderBean } from '@/api/order/types';
import { useUserStore } from '@/store'; import { useUserStore } from '@/store';
import { handlePayResult } from '@/utils/order';
const userStore = useUserStore(); const userStore = useUserStore();
const { terminalInfo, deliveryAddress } = storeToRefs(userStore); const { terminalInfo, deliveryAddress } = storeToRefs(userStore);
@@ -176,15 +177,14 @@ const showCouponDialog = () => {
const confirmCoupon = (item: CouponBean) => { const confirmCoupon = (item: CouponBean) => {
checkedCoupon.value = item; checkedCoupon.value = item;
}; };
const navigateTo = (e: any) => { const navigateTo = (e: any) => {
console.log('----------->>>>>navigateTo ', e); console.log('--------------_>>>>>>navigateTo ', e);
uni.redirectTo({ handlePayResult(orderBean.value?.id, e, {
url: e.detail.url, onSuccess: () => {
fail(e) { // pay({
uni.showToast({ // 'orderId': orderBean.value?.order.id,
title: '支付失败' // 'result': 'xxx'
}); // });
} }
}); });
}; };
@@ -237,7 +237,6 @@ const payment = async () => {
}] }]
}; };
await overPayment(paymentParams); await overPayment(paymentParams);
uni.navigateBack();
uni.hideLoading(); uni.hideLoading();
}; };

View File

@@ -73,17 +73,17 @@ import { useUserStore } from '@/store';
const officialAccountDialogRef = ref(); const officialAccountDialogRef = ref();
const orderActionList = ref([{ const orderActionList = ref([{
title: '进行中', title: '未支付',
icon: assetsUrl('ic_order_progressing.png'), icon: assetsUrl('ic_order_progressing.png'),
path: '/pages/mine/subs/order/index'
}, {
title: '已结束',
icon: assetsUrl('ic_order_finish.png'),
path: '/pages/mine/subs/order/index?index=1' path: '/pages/mine/subs/order/index?index=1'
}, {
title: '已支付',
icon: assetsUrl('ic_order_finish.png'),
path: '/pages/mine/subs/order/index?index=2'
}, { }, {
title: '全部订单', title: '全部订单',
icon: assetsUrl('ic_order_all.png'), icon: assetsUrl('ic_order_all.png'),
path: '/pages/mine/subs/order/index?index=2' path: '/pages/mine/subs/order/index?index=0'
}]); }]);
const serviceList = [ const serviceList = [

View File

@@ -6,7 +6,9 @@
<view class='c-flex-row'> <view class='c-flex-row'>
<text class='goods-name'>{{ item?.orderGoods[0].goodsName }}</text> <text class='goods-name'>{{ item?.orderGoods[0].goodsName }}</text>
<text class='status'> <text class='status'>
{{ item?.payStatus == 2 ? '已支付' : '未支付' }} <text v-if='item?.payStatus == 2'>已支付</text>
<text v-else-if='isPending(item)'>待支付</text>
<text v-else style='color: #999999'>已过期</text>
</text> </text>
</view> </view>
<view class='bottom-view c-flex-row'> <view class='bottom-view c-flex-row'>
@@ -21,17 +23,17 @@
</view> </view>
</view> </view>
<view class='action-view c-flex-row'> <view class='action-view c-flex-row'>
<view class='countdown c-flex-row' v-if='item?.payStatus==1'> <view class='countdown c-flex-row' v-if='isPending(item)'>
<image :src='assetsUrl("ic_time.png")' /> <image :src='assetsUrl("ic_time.png")' />
<text class='primary-text-color'>支付剩余时间 <text class='primary-text-color'>支付剩余时间
<text class='accent-text-color'>05:23</text> <text class='accent-text-color'>{{ dayjs.unix(item?.countdown || 0).format('mm:ss') || '00:00' }}</text>
</text> </text>
</view> </view>
<view v-else style='flex: 1' /> <view v-else style='flex: 1' />
<view class='c-flex-row'> <view class='c-flex-row'>
<text class='add-shoppingcart secondary-text-color' @click.stop='add(item?.orderGoods[0])'>加入购物车</text> <text class='add-shoppingcart secondary-text-color' @click.stop='add(item?.orderGoods[0])'>加入购物车</text>
<text class='payment accent-text-color' v-if='item?.payStatus==1' @click.stop='pay(item?.id)'>立即支付 <text class='payment accent-text-color' v-if='isPending(item)' @click.stop='pay(item?.id)'>立即支付
</text> </text>
</view> </view>
</view> </view>
@@ -42,8 +44,10 @@
import { PropType } from 'vue'; import { PropType } from 'vue';
import { assetsUrl } from '@/utils/assets'; import { assetsUrl } from '@/utils/assets';
import { goPath } from '@/utils'; import { goPath } from '@/utils';
import { isPending } from '@/utils/order';
import { OrderBean } from '@/api/order/types'; import { OrderBean } from '@/api/order/types';
import { GoodsBean } from '@/api/goods/types'; import { GoodsBean } from '@/api/goods/types';
import dayjs from 'dayjs';
const emits = defineEmits(['addShoppingCart', 'payment']); const emits = defineEmits(['addShoppingCart', 'payment']);
@@ -55,7 +59,7 @@ const add = (item: GoodsBean | undefined) => {
emits('addShoppingCart', item); emits('addShoppingCart', item);
}; };
const pay = (orderId: string) => { const pay = (orderId: string | undefined) => {
emits('payment', orderId); emits('payment', orderId);
}; };
</script> </script>

View File

@@ -1,7 +1,7 @@
<template> <template>
<scroll-view scroll-y> <scroll-view scroll-y>
<view class='content'> <view class='content'>
<view class='countdown c-flex-row' v-if='orderBean?.order.payStatus==1'> <view class='countdown c-flex-row' v-if='isPending(orderBean?.order)'>
<image :src='assetsUrl("ic_order.png")' /> <image :src='assetsUrl("ic_order.png")' />
<view class='c-flex-column'> <view class='c-flex-column'>
<text> <text>
@@ -10,23 +10,23 @@
<view class='c-flex-row'> <view class='c-flex-row'>
<image :src='assetsUrl("ic_time.png")' /> <image :src='assetsUrl("ic_time.png")' />
<text>支付剩余时间 <text>支付剩余时间
<text style='color: #F32B2B'>05:23</text> <text style='color: #F32B2B'>{{ dayjs.unix(orderBean?.order?.countdown || 0).format('mm:ss') }}</text>
</text> </text>
</view> </view>
</view> </view>
</view> </view>
<view class='address-view c-flex-column'> <view class='address-view c-flex-column' v-if='orderBean?.order?.address'>
<view class='user-info c-flex-row'> <view class='user-info c-flex-row'>
<text>默认</text> <text v-if='orderBean.order.address.defaultstatus==1'>默认</text>
<text>黄先生</text> <text>{{ orderBean?.order?.address.name }}</text>
<text>155****6532</text> <text>{{ orderBean?.order?.address.mobile }}</text>
<view style='flex: 1' /> <view style='flex: 1' />
<text style='color: #5B96FB'>复制</text> <text style='color: #5B96FB'>复制</text>
</view> </view>
<view class='addr c-flex-row'> <view class='addr c-flex-row'>
<image :src='assetsUrl("ic_location.png")' /> <image :src='assetsUrl("ic_location.png")' />
<text>湖南省 长沙市 详细地址详细地址详细地址</text> <text>{{ orderBean?.order?.address.addr }}</text>
</view> </view>
<image class='dashed-line' :src='assetsUrl("ic_address_dashed_line.png")' /> <image class='dashed-line' :src='assetsUrl("ic_address_dashed_line.png")' />
</view> </view>
@@ -93,9 +93,9 @@
<text>下单时间{{ orderBean?.order?.createTime }}</text> <text>下单时间{{ orderBean?.order?.createTime }}</text>
</view> </view>
<view class='bottom-action-view c-flex-row' v-if='orderBean?.order.payStatus==1'> <view class='bottom-action-view c-flex-row' v-if='isPending(orderBean?.order)'>
<text @click.stop='cancel' style='display: none'>取消订单</text> <text @click.stop='cancel' style='display: none'>取消订单</text>
<sqb-pay @bindnavigateTo='navigateTo' <sqb-pay @navigateTo='navigateTo'
:return_url='buildSqbParams.return_url' :return_url='buildSqbParams.return_url'
:total_amount='buildSqbParams.total_amount' :total_amount='buildSqbParams.total_amount'
:terminal_sn='buildSqbParams.terminal_sn' :terminal_sn='buildSqbParams.terminal_sn'
@@ -118,6 +118,9 @@ import { OrderBean } from '@/api/order/types';
import { parseParameter, sortASCII } from '@/utils'; import { parseParameter, sortASCII } from '@/utils';
import { hexMD5 } from '@/utils/common/md5'; import { hexMD5 } from '@/utils/common/md5';
import { useUserStore } from '@/store'; import { useUserStore } from '@/store';
import { handlePayResult, isPending } from '@/utils/order';
import dayjs from 'dayjs';
import { pay } from '@/api/groupbuy';
const userState = useUserStore(); const userState = useUserStore();
const { terminalInfo } = storeToRefs(userState); const { terminalInfo } = storeToRefs(userState);
@@ -128,12 +131,19 @@ const orderBean = ref<{
paymentList: [] paymentList: []
}>(); }>();
let currentInterval = 0;
onLoad(async (e: any) => { onLoad(async (e: any) => {
await uni.showLoading(); await uni.showLoading();
orderBean.value = await getOrderDetail(e.orderId); orderBean.value = await getOrderDetail(e.orderId);
handleCountdown();
uni.hideLoading(); uni.hideLoading();
}); });
onUnload(() => {
clearInterval(currentInterval);
});
const buildSqbParams = computed(() => { const buildSqbParams = computed(() => {
const params = sortASCII({ const params = sortASCII({
client_sn: orderBean.value?.order?.id || '', client_sn: orderBean.value?.order?.id || '',
@@ -152,16 +162,32 @@ const buildSqbParams = computed(() => {
const navigateTo = (e: any) => { const navigateTo = (e: any) => {
console.log('--------------_>>>>>>navigateTo ', e); console.log('--------------_>>>>>>navigateTo ', e);
uni.redirectTo({ handlePayResult(orderBean.value?.order.id, e, {
url: e.detail.url, onSuccess: () => {
fail(e) { // pay({
uni.showToast({ // 'orderId': orderBean.value?.order.id,
title: '支付失败' // 'result': 'xxx'
}); // });
} }
}); });
}; };
const handleCountdown = () => {
clearInterval(currentInterval);
let second = 30 * 60;
currentInterval = setInterval(() => {
if(isPending(orderBean.value?.order)) {
orderBean.value!.order!.countdown = second;
if(orderBean.value!.order!.countdown <= 0) {
orderBean.value!.order!.countdown = 0;
} else {
uni.navigateBack();
}
second--;
}
}, 1000);
};
const cancel = () => { const cancel = () => {
}; };
const payment = () => { const payment = () => {

View File

@@ -1,5 +1,5 @@
<template> <template>
<tabbar :titles="['全部', '进行中', '已结束']" @change='tabChange' /> <tabbar :titles="['全部', '未支付', '已支付']" :index='payStatus' @change='tabChange' />
<u-list :list='orderList' :border='false' @scrolltolower='loadMore'> <u-list :list='orderList' :border='false' @scrolltolower='loadMore'>
<u-list-item v-for='(item,index) in orderList' :key='index'> <u-list-item v-for='(item,index) in orderList' :key='index'>
<order-item :item='item' @addShoppingCart='addShoppingCart' @pay='payment' /> <order-item :item='item' @addShoppingCart='addShoppingCart' @pay='payment' />
@@ -13,12 +13,13 @@
<script lang='ts' setup> <script lang='ts' setup>
import { ref } from 'vue'; import { ref } from 'vue';
import { showToast } from '@/utils';
import { isPending } from '@/utils/order';
import { getOrderList } from '@/api/order'; import { getOrderList } from '@/api/order';
import OrderItem from '@/pages/mine/subs/order/components/order-item.vue'; import OrderItem from '@/pages/mine/subs/order/components/order-item.vue';
import { OrderBean } from '@/api/order/types'; import { OrderBean } from '@/api/order/types';
import SkuDialog from '@/components/sku-dialog.vue'; import SkuDialog from '@/components/sku-dialog.vue';
import { GoodsBean, StockBean } from '@/api/goods/types'; import { GoodsBean, StockBean } from '@/api/goods/types';
import { showToast } from '@/utils';
import useShoppingCartStore from '@/store/modules/shoppingcart'; import useShoppingCartStore from '@/store/modules/shoppingcart';
const shoppingCartStore = useShoppingCartStore(); const shoppingCartStore = useShoppingCartStore();
@@ -28,8 +29,15 @@ const orderList = ref<OrderBean[]>([]);
const currentPageNum = ref(1); const currentPageNum = ref(1);
const payStatus = ref(0); const payStatus = ref(0);
onLoad((e) => { let currentInterval = 0;
fetchData();
onLoad((e: any) => {
const index = Number(e.index) || 0;
tabChange(index);
});
onUnload(() => {
clearInterval(currentInterval);
}); });
const tabChange = (index: number) => { const tabChange = (index: number) => {
@@ -51,8 +59,26 @@ const fetchData = async (refresh: boolean = true) => {
} else { } else {
orderList.value = orderList.value.concat(list); orderList.value = orderList.value.concat(list);
} }
handleCountdown(orderList.value.filter(item => item.payStatus == 1));
}; };
const handleCountdown = (items: OrderBean[]) => {
clearInterval(currentInterval);
let second = 30 * 60;
currentInterval = setInterval(() => {
items.forEach(item => {
if(isPending(item)) {
item.countdown = second;
if(item.countdown <= 0) {
item.countdown = 0;
}
second--;
}
});
}, 1000);
};
const loadMore = () => { const loadMore = () => {
fetchData(false); fetchData(false);
}; };

View File

@@ -28,7 +28,7 @@
<view class='bottom-button-view'> <view class='bottom-button-view'>
<!-- <payment-button style='flex: 1' :payParams='buildSignParams'>--> <!-- <payment-button style='flex: 1' :payParams='buildSignParams'>-->
<sqb-pay style='width: 100%;' @bindnavigateTo='navigateTo' <sqb-pay style='width: 100%;' @navigateTo='navigateTo'
:return_url='buildSqbParams.return_url' :return_url='buildSqbParams.return_url'
:total_amount='buildSqbParams.total_amount' :total_amount='buildSqbParams.total_amount'
:terminal_sn='buildSqbParams.terminal_sn' :terminal_sn='buildSqbParams.terminal_sn'
@@ -50,6 +50,7 @@ import { useUserStore } from '@/store';
import { getRechargeList, preRecharge, recharge, rechargeVerify } from '@/api/user'; import { getRechargeList, preRecharge, recharge, rechargeVerify } from '@/api/user';
import { parseParameter, sortASCII } from '@/utils'; import { parseParameter, sortASCII } from '@/utils';
import { hexMD5 } from '@/utils/common/md5'; import { hexMD5 } from '@/utils/common/md5';
import { handlePayResult } from '@/utils/order';
const userState = useUserStore(); const userState = useUserStore();
const { userInfo, terminalInfo } = storeToRefs(userState); const { userInfo, terminalInfo } = storeToRefs(userState);
@@ -96,12 +97,9 @@ const buildSqbParams = computed(() => {
const navigateTo = (e: any) => { const navigateTo = (e: any) => {
console.log('--------------_>>>>>>navigateTo ', e); console.log('--------------_>>>>>>navigateTo ', e);
uni.redirectTo({ handlePayResult(preRechargeOrderId.value, e, {
url: e.detail.url, onSuccess: () => {
fail(e) { console.log('---------->>> recharge success ');
uni.showToast({
title: '支付失败'
});
} }
}); });
}; };

View File

@@ -52,9 +52,9 @@ const useUserStore = defineStore('user', {
// 设置用户的信息 // 设置用户的信息
async setUserInfo(partial: Partial<UserBean>) { async setUserInfo(partial: Partial<UserBean>) {
this.userInfo = partial as UserBean; this.userInfo = partial as UserBean;
setCompanyId(this.userInfo.companyId); await setCompanyId(this.userInfo.companyId);
await this.fetchCompanyInfo();
await this.fetchTerminal(); await this.fetchTerminal();
await this.fetchCompanyInfo();
}, },
setDeliveryAddress(partial: Partial<any>) { setDeliveryAddress(partial: Partial<any>) {
@@ -129,14 +129,12 @@ const useUserStore = defineStore('user', {
creatorId: res.user.creatorId, creatorId: res.user.creatorId,
gender: res.user.gender gender: res.user.gender
}; };
setToken(res.token);
const registerResult = await this.userRegister(registerForm); const registerResult = await this.userRegister(registerForm);
await this.setUserInfo(registerResult as LoginResult); await this.setUserInfo(registerResult as LoginResult);
setToken(res.token);
setCompanyId(res.user.companyId);
} else { } else {
await this.setUserInfo(res.user);
setToken(res.token); setToken(res.token);
setCompanyId(res.user.companyId); await this.setUserInfo(res.user);
} }
resolve(res); resolve(res);
} else { } else {

View File

@@ -1,4 +1,5 @@
// 小程序更新检测 // 小程序更新检测
export function mpUpdate() { export function mpUpdate() {
const updateManager = uni.getUpdateManager(); const updateManager = uni.getUpdateManager();
updateManager.onCheckForUpdate((res) => { updateManager.onCheckForUpdate((res) => {
@@ -27,11 +28,25 @@ export function mpUpdate() {
}); });
} }
export function showToast(title: string, icon: 'none' | 'success' | 'loading' | 'error' | 'fail' | 'exception' | undefined = 'none', duration: number = 2000) { interface ToastOption {
icon?: 'none' | 'success' | 'loading' | 'error' | 'fail' | 'exception' | undefined,
duration?: number,
complete?: Function
}
export function showToast(title: string, { icon, duration, complete }: ToastOption = {}) {
const defaultDuration = 1500;
uni.showToast({ uni.showToast({
title, title: title,
icon, icon: icon || 'none',
duration duration: duration || defaultDuration,
complete(result) {
setTimeout(() => {
if(complete != undefined) {
complete();
}
}, duration || defaultDuration);
}
}); });
} }

58
src/utils/order/index.ts Normal file
View File

@@ -0,0 +1,58 @@
import { OrderBean } from '@/api/order/types';
import dayjs from 'dayjs';
import { showToast } from '@/utils';
/**
* 获取订单支付过期时间
* @param order
*/
export function getOrderDeadline(order: OrderBean) {
// return dayjs(order?.createTime).add(30, 'minute').toDate().getTime();
return dayjs(order?.createTime).add(10, 'day').toDate().getTime();
}
/**
* 订单已过期
* @param item
*/
export const isExpired = (item: OrderBean) => {
return item?.payStatus == 1 && getOrderDeadline(item) < Date.now();
};
/**
* 订单待支付
* @param item
*/
export const isPending = (item: OrderBean | undefined) => {
return item?.payStatus == 1 && getOrderDeadline(item) > Date.now();
};
export const handlePayResult = (orderId: string | undefined, e: any, { onSuccess, onFailure }: any) => {
const payDetail = e.detail;
let url = payDetail.url;
const str = url.split('?')[1];
const resultObj = JSON.parse(str.replaceAll('result=', ''));
if(resultObj?.is_success === true) {
if(onSuccess) {
onSuccess();
} else {
showToast('支付成功', {
icon: 'success',
complete: () => {
uni.navigateBack();
}
});
}
} else {
if(onFailure) {
onFailure();
}
const msg = resultObj?.error_message || '支付失败';
showToast(msg, {
complete: () => {
uni.navigateBack();
}
});
}
};