购物车逻辑完善

个人信息存储优化
团购支付
This commit is contained in:
2024-03-31 17:22:14 +08:00
parent 1fc0aa432b
commit b502385272
19 changed files with 859 additions and 141 deletions

View File

@@ -16,8 +16,8 @@
超级\n秒杀
</view>
<view class='price c-flex-column' style='flex: 1'>
<text>{{ detailBean?.payPrice || 0 }}</text>
<text>{{ detailBean?.goodsPrice || 0 }}</text>
<text>{{ groupBuyBean?.payPrice || 0 }}</text>
<text>{{ groupBuyBean?.price || 0 }}</text>
</view>
<view class='countdown-time c-flex-column'>
<view class='c-flex-row'>{{ countdownTime?.days || 0 }}
@@ -33,12 +33,12 @@
<view class='goods-info-view c-flex-column'>
<view class='c-flex-row'>
<text class='goods-price accent-text-color'>{{ detailBean?.payPrice || 0 }}</text>
<text>销量{{ detailBean?.totalNum || 0 }}</text>
<text class='goods-price accent-text-color'>{{ groupBuyBean?.payPrice || 0 }}</text>
<text>销量{{ groupBuyBean?.totalNum || 0 }}</text>
</view>
<view class='c-flex-row'>
<text style='flex: 1'>{{ detailBean?.name }}</text>
<text style='flex: 1'>{{ groupBuyBean?.name }}</text>
<view class='share-button c-flex-column'>
<image :src='assetsUrl("ic_share.png")'></image>
<button class='btn' plain open-type='share'>分享</button>
@@ -51,7 +51,7 @@
<text>选择</text>
<text>规格 颜色/尺码</text>
<image :src='assetsUrl("ic_arrow_right_gray.png")' />
<text>1种颜色可选</text>
<text>{{ getStockColorCount }}种颜色可选</text>
</view>
</view>
@@ -70,27 +70,27 @@
</view>
<!-- 商品详情图片 -->
<view class='card-view image-container' v-if='detailBean?.content'>
<view class='card-view image-container' v-if='groupBuyBean?.content'>
<text class='card-view-title'>商品详情</text>
<image
v-for='(item,index) in JSON.parse(detailBean?.content).filter((a: any) => a.type === 2).map((b: any) => b.images)'
v-for='(item,index) in JSON.parse(groupBuyBean?.content).filter((a: any) => a.type === 2).map((b: any) => b.images)'
:src='item' mode='aspectFill' :key='index' />
</view>
<!-- 商品详情 -->
<view class='card-view goods-container'>
<view class='c-flex-row'>
<image :src='detailBean?.goods?.images' />
<image :src='groupBuyBean?.goods?.images' />
<view class='c-flex-column'>
<text class='goods-name'>{{ detailBean?.goods?.name }}</text>
<text class='goods-name'>{{ groupBuyBean?.goods?.name }}</text>
<text style='color: #a6a6a6'>精选</text>
<view class='tag-view c-flex-row'>
<text>团长推荐</text>
<text>今日必买</text>
</view>
<text style='color: #a6a6a6'>不参与会员折扣</text>
<text style='color: #F32B2B'>¥{{ detailBean?.goods?.payPrice }}</text>
<text class='bought_count'>已团{{ detailBean?.sendNum }}</text>
<text style='color: #F32B2B'>¥{{ groupBuyBean?.goods?.payPrice }}</text>
<text class='bought_count'>已团{{ groupBuyBean?.sendNum }}</text>
</view>
</view>
</view>
@@ -99,7 +99,7 @@
<view class='card-view coupon-container'>
<text class='card-view-title'>赠送优惠券</text>
<view class='c-flex-column'>
<coupon-item v-for='(item,index) in detailBean?.couponsList' :key='index' :item='item' />
<coupon-item v-for='(item,index) in groupBuyBean?.couponsList' :key='index' :item='item' />
</view>
</view>
@@ -125,13 +125,13 @@
<view class='place-order-button' @click.stop='placeOrder'>跟团购买</view>
</view>
</view>
<sku-dialog ref='skuDialogRef' :bean='detailBean?.goods' @confirm='confirmGoodsSku' />
<sku-dialog ref='skuDialogRef' :flash-price='groupBuyBean?.payPrice || 0' />
</template>
<script lang='ts' setup>
import { assetsUrl } from '@/utils/assets';
import dayjs from 'dayjs';
import { goPath } from '@/utils';
import { formatTimeWithZeroPad, goPath } from '@/utils';
import SkuDialog from '@/components/sku-dialog.vue';
import CouponItem from './components/coupon-item.vue';
@@ -139,33 +139,33 @@ import { getGroupBuyDetail, getGroupBuyRecordList, preOrder } from '@/api/groupb
import { getGoodsList } from '@/api/goods';
import { GoodsBean } from '@/api/goods/types';
import { useUserStore } from '@/store';
import { GroupBuyBean, RecordBean } from '@/api/groupbuy/types';
const userStore = useUserStore();
const { userInfo } = storeToRefs(userStore);
const skuDialogRef = ref();
const detailBean = ref();
const groupBuyBean = ref<GroupBuyBean>();
const recommendList = ref<GoodsBean[]>();
const skuBean = ref();
const bannerList = ref([]);
const swiperIndex = ref(0);
let interval: number;
const countdownTime = ref<{
days: number,
hours: number,
minutes: number,
seconds: number
days: string,
hours: string,
minutes: string,
seconds: string
}>();
const recordList = ref([]);
const recordList = ref<RecordBean[]>([]);
const currentPageNum = ref(1);
onLoad(async (e: any) => {
detailBean.value = await getGroupBuyDetail(e.id);
detailBean.value.goods.price = detailBean.value.price;
bannerList.value = JSON.parse(detailBean.value.content).filter((item: any) => item.type === 2).map((item: any) => item.images);
groupBuyBean.value = await getGroupBuyDetail(e.id);
groupBuyBean.value.goods.price = groupBuyBean.value.price;
bannerList.value = JSON.parse(groupBuyBean.value.content).filter((item: any) => item.type === 2).map((item: any) => item.images);
countdown();
await fetchRecommendList();
await fetchBuyRecordList();
@@ -177,6 +177,12 @@ onUnload(() => {
}
});
const getStockColorCount = computed(() => {
const list = Array.from(new Set(groupBuyBean.value?.goods?.stocks?.map(item => item.colorName)))
.map(colorName => groupBuyBean.value?.goods?.stocks?.find(item => item.colorName === colorName)!);
return list.length;
});
const fetchRecommendList = async () => {
const { rows } = await getGoodsList({
page: {
@@ -195,7 +201,7 @@ const fetchBuyRecordList = async (refresh: boolean = true) => {
if(!refresh) {
currentPageNum.value += 1;
}
const { list } = await getGroupBuyRecordList(detailBean.value.id, currentPageNum.value, 20);
const { list } = await getGroupBuyRecordList(groupBuyBean?.value?.id || '', currentPageNum.value, 20);
recordList.value = recordList.value.concat(list);
};
@@ -209,16 +215,16 @@ const swiperChange = (e: any) => {
const countdown = () => {
interval = setInterval(() => {
if(detailBean.value?.endDate) {
if(groupBuyBean.value?.endDate) {
let now = new Date();
let end = dayjs(detailBean.value?.endDate).toDate().getTime();
let end = dayjs(groupBuyBean.value?.endDate).toDate().getTime();
let remaining = Math.floor((end - now.getTime()) / 1000);
if(remaining > 0) {
countdownTime.value = {
days: Math.floor(remaining / 60 / 60 / 24),
hours: Math.floor(remaining / 60 / 60 % 24),
minutes: Math.floor(remaining / 60 % 60),
seconds: Math.floor(remaining % 60)
days: formatTimeWithZeroPad(Math.floor(remaining / 60 / 60 / 24)),
hours: formatTimeWithZeroPad(Math.floor(remaining / 60 / 60 % 24)),
minutes: formatTimeWithZeroPad(Math.floor(remaining / 60 % 60)),
seconds: formatTimeWithZeroPad(Math.floor(remaining % 60))
};
} else {
clearInterval(interval);
@@ -228,31 +234,27 @@ const countdown = () => {
};
const showSkuDialog = (fn: Function) => {
skuDialogRef.value.show(fn);
};
const confirmGoodsSku = (e: any) => {
skuBean.value = e;
skuDialogRef.value.show(groupBuyBean?.value?.goods?.goodsId, fn);
};
const placeOrder = async () => {
async function create() {
async function create(bean: GoodsBean) {
const params = {
'colorId': '1725029269178814466',
'sizeId': '0',
'goodsId': detailBean.value.goods.goodsId,
'groupId': detailBean.value.id,
'colorId': bean.checkedStock.colorId,
'sizeId': bean.checkedStock.sizeId,
'goodsId': groupBuyBean?.value?.goods.goodsId,
'groupId': groupBuyBean?.value?.id,
'memberId': userInfo.value.id,
'shareId': '123456'
};
const result = await preOrder(params);
goPath('/pages/common/groupbuy/order');
goPath(`/pages/common/groupbuy/order?orderBean=${encodeURIComponent(JSON.stringify(result))}`);
}
showSkuDialog(() => {
create();
showSkuDialog((e: GoodsBean) => {
create(e);
});
};
</script>
@@ -360,7 +362,7 @@ const placeOrder = async () => {
margin-left: 12rpx;
margin-right: 12rpx;
background: #FFFFFF;
border-radius: 7rpx 7rpx 7rpx 7rpx;
border-radius: 7rpx;
color: #F32B2B;
}
@@ -467,7 +469,7 @@ const placeOrder = async () => {
font-size: 24rpx;
color: #999999;
position: absolute;
top: 40rpx;
top: 50rpx;
left: 100rpx;
}
}
@@ -527,7 +529,7 @@ const placeOrder = async () => {
.bottom-view {
background: #FFFFFF;
padding: 20rpx 30rpx 78rpx 33rpx;
padding: 20rpx 30rpx 78rpx 30rpx;
position: fixed;
left: 0;
right: 0;

View File

@@ -2,21 +2,27 @@
<view class='content'>
<view class='card-view'>
<image class='goods-image' :src='assetsUrl("test_bg.png")' />
<view class='c-flex-column' style='flex: 1'>
<text class='goods-name'>商品名称</text>
<text class='goods-sku'>颜色尺码</text>
</view>
<template v-for='(item,index) in orderBean?.orderGoods' :key='index'>
<image class='goods-image' :src='item?.images' />
<view class='c-flex-column' style='flex: 1'>
<text class='goods-name'>{{ item?.goodsName }}</text>
<text class='goods-sku'>{{ item?.stockStock?.colorName }} {{ item?.stockStock?.sizeName }}</text>
</view>
<view class='c-flex-column'>
<text class='goods-num'>x1</text>
<text class='goods-price'>¥100</text>
</view>
<view class='c-flex-column'>
<text class='goods-num'>x{{ item?.goodsNum }}</text>
<view class='c-flex-row'>
<text class='goods-price' style='margin-right: 10rpx;text-decoration: line-through'>¥{{ item?.originPrice }}
</text>
<text class='goods-price'>¥{{ item?.consumePrice }}</text>
</view>
</view>
</template>
</view>
<view class='card-view'>
<text style='flex: 1'>实付</text>
<text style='color: #F32B2B'>¥100</text>
<text style='color: #F32B2B'>¥{{ orderBean?.totalPrice || 0 }}</text>
</view>
<view class='bottom-view c-flex-row'>
@@ -27,12 +33,57 @@
</template>
<script lang='ts' setup>
import { pay, progress } from '@/api/groupbuy';
import { OrderBean } from '@/api/groupbuy/types';
import { parseParameter, sortASCII } from '@/utils';
import { hexMD5 } from '@/utils/common/md5';
import { useUserStore } from '@/store';
import { assetsUrl } from '@/utils/assets';
const userState = useUserStore();
const { terminalInfo } = storeToRefs(userState);
const orderBean = ref<OrderBean>();
onLoad((e: any) => {
orderBean.value = JSON.parse(decodeURIComponent(e?.orderBean));
});
const payment = () => {
let signParams = {
return_url: 'return_url',
total_amount: orderBean.value?.totalPrice,
client_sn: orderBean.value?.id,
terminal_sn: terminalInfo.value.terminalSn,
subject: 'subject',
subject_img: 'subject_img',
merchant_name: 'merchant_name',
notify_url: 'https://www.baidu.com'
};
// signParams = util.sortASCII(signParams, true);
sortASCII(signParams, true);
//参数拼接
// const signStr = util.pars(signParams) + '&key=' + terminalInfo.value.terminalKey;
const signStr = parseParameter(signParams) + '&key=' + terminalInfo.value.terminalKey;
console.log('签名字符串', signStr);
// const sign = utilMd5.hexMD5(signStr).toUpperCase();
const sign = hexMD5(signStr);
console.log('签名结果', sign);
const params = {
'id': orderBean.value?.id,
'orderSn': signParams.client_sn,
'terminal_key': terminalInfo.value.terminalKey,
'terminal_sn': terminalInfo.value.terminalSn
};
progress(params);
pay({
'orderId': orderBean.value?.id,
'result': JSON.stringify('{payResult:xxx}')
});
};
</script>
<style lang='scss' scoped>