Files
jdt-user/src/pages/cart/index.vue
YuanHuakk 896acaef9e
All checks were successful
continuous-integration/drone/push Build is passing
feat(custom): 地图apiKey更换,订单核销详情新增支付方式
2025-05-29 15:45:16 +08:00

366 lines
8.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<view v-if="list.length > 0">
<nut-cell-group v-for="(itm, idx) in list" :key="idx">
<nut-cell>
<nut-checkbox
v-model="itm.state.checkbox"
:indeterminate="itm.state.indeterminate"
@change="(val: boolean) => changeBoxAll(val, idx)"
>{{ itm.StoreName }}
</nut-checkbox>
</nut-cell>
<nut-checkbox-group
v-model="itm.state.checkboxgroup"
:ref="el => getGroup(el, idx)"
@change="label => changeBox(label, itm)">
<nut-cell v-for="(item, idx1) in itm.Goods" :key="idx1">
<nut-checkbox :label="item.gid" style="width: 10%"></nut-checkbox>
<view class="box">
<view class="box-left">
<img class="cover" :src="item.cover" alt="" />
<view class="center">
<view class="line-clamp-2 text-[25px]">{{ item.name }}</view>
<view class="price">
<view
>{{ item.price }}
<text v-if="item.discount_integral > 0"
>+{{ item.discount_integral }}积分</text
>
</view>
</view>
</view>
</view>
<nut-input-number
v-model="item.number"
readonly
:min="-1"
@add.stop="() => onAdd(item)"
@reduce.stop="() => onReduce(item)" />
</view>
</nut-cell>
</nut-checkbox-group>
</nut-cell-group>
</view>
<nut-empty v-else description="购物车暂无数据"></nut-empty>
<view>
<view style="height: 100px"></view>
</view>
<view class="bottom-box" v-if="list.length > 0">
<view class="left">
<!-- <nut-checkbox v-model="selectAllVal" @change="selectAll"
>全选
</nut-checkbox> -->
<view>
<view class="text-box">
总金额
<nut-price
v-model:price="localCount.price"
size="normal"
:need-symbol="false" />
</view>
<view class="text-box">
总积分
<nut-price
v-model:price="localCount.exchange"
size="normal"
:need-symbol="false" />
</view>
</view>
</view>
<nut-button type="primary" @click="sub">去结算</nut-button>
</view>
<!-- 支付 -->
<Pay
:is-show-pay="isShowPay"
:interval="true"
v-model:jfInfo="orderData"
@closePay="closePay" />
</view>
</template>
<script lang="ts" setup>
import { nextTick, ref } from 'vue';
import Taro from '@tarojs/taro';
import { addCart, getAllCart } from '@/api/cart';
import { createActiveOrder } from '@/api/goods';
import Pay from '@/components/Pay.vue';
interface CardList {
name: string;
cover: string;
bid: string;
gid: string;
number: string;
price: number;
exchange: number;
pay_price: number;
discount_integral: number;
}
// const selectAllVal = ref(false);
interface List {
StoreName: string;
Goods: CardList[];
state: {
checkbox: boolean;
indeterminate: boolean;
checkboxgroup: string[];
};
}
const list = ref<List[]>([]);
const groupList = ref(new Map());
const localCount = ref({
price: 0,
exchange: 0,
});
const getGroup = (el: any, idx: number) => {
return groupList.value.set(idx, el);
};
const changeBoxAll = async (value: boolean, idx: number) => {
await nextTick(() => {
groupList.value.get(idx).toggleAll(value);
});
};
const changeBox = (label: string[], item: any) => {
localCount.value = {
price: 0,
exchange: 0,
};
item['Count'] = {
priceCount: 0,
exchangeCount: 0,
};
if (label.length > 0) {
label.forEach((id: string) => {
item.Goods.forEach((itm: any) => {
if (itm.gid === id) {
item['Count'].priceCount += itm.price;
item['Count'].exchangeCount += itm.discount_integral;
}
});
});
}
list.value.forEach((item: any) => {
localCount.value.price += item.Count.priceCount;
localCount.value.exchange += item.Count.exchangeCount;
});
if (label.length === item.Goods.length) {
item.state.checkbox = true;
item.state.indeterminate = false;
} else if (label.length && label.length < item.Goods.length) {
item.state.indeterminate = true;
} else {
item.state.indeterminate = false;
item.state.checkbox = false;
}
};
Taro.useDidShow(() => {
getList();
});
// const selectAll = () => {
// localCount.value = {
// price: 0,
// exchange: 0,
// };
// groupList.value.forEach((item: any) => {
// item.toggleAll(selectAllVal.value);
// });
// list.value.forEach((item: any) => {
// if (item.state.checkboxgroup.length > 0) {
// item.Goods.forEach((itm: any) => {
// localCount.value.price += itm.price;
// localCount.value.exchange += itm.exchange;
// });
// }
// });
// };
const isShowPay = ref(false);
const orderData = ref<any>([]);
const sub = async () => {
try {
console.log('sub');
const arr: any = list.value.filter(
(item: any) => item.state.checkboxgroup.length > 0,
);
console.log(arr);
if (arr.length === 0) {
Taro.showToast({
title: '请选择商品',
icon: 'none',
});
return;
}
const { data: res } = await createActiveOrder({
Bid: arr.map((item: any) => item.StoreBid),
});
if (res.oid) {
// orderData.value = res?.oid;
// isShowPay.value = true;
// console.log(arr)
Taro.navigateTo({
url: `/pages/goods/pay/index?oid=${res.oid}&bid=${arr[0].StoreBid}&OrderType=1`,
});
}
} catch (e) {
Taro.showToast({
title: e.msg || '订单创建失败',
icon: 'none',
});
}
};
const closePay = async (val: boolean) => {
isShowPay.value = val;
orderData.value = [];
await getList();
Taro.navigateTo({
url: '/pages/users/order_list/index?type=0',
});
};
const getList = async () => {
localCount.value = {
price: 0,
exchange: 0,
};
const res = await getAllCart();
list.value = res.data.data || [];
if (list.value.length > 0) {
list.value = list.value.map((item: any) => ({
...item,
Goods: item.Goods.sort(
(a: CardList, b: CardList) => Number(a.gid) - Number(b.gid),
),
state: {
indeterminate: false,
checkbox: false,
checkboxgroup: [],
},
Count: {
priceCount: 0,
exchangeCount: 0,
},
}));
}
};
// const toPage = () => {
// Taro.switchTab({
// url: "/pages/index/index",
// });
// };
const onAdd = async (item: CardList) => {
await add_cart(item, Number(item.number) + 1);
};
const onReduce = async (item: CardList) => {
await add_cart(item, Number(item.number) - 1);
};
const add_cart = async (item: CardList, num: number = 1) => {
try {
const res = await addCart({
Bid: item.bid,
Gid: item.gid,
Number: Number(num),
});
Taro.showToast({
title: res.msg,
icon: 'none',
});
await getList();
} catch (e) {
Taro.showToast({
title: e.msg,
icon: 'none',
});
}
};
</script>
<style lang="scss">
.index {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
}
.box {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.box-left {
display: flex;
align-items: center;
.cover {
width: 130px;
height: 130px;
min-width: 130px;
min-height: 130px;
margin-right: 15px;
border-radius: 20px;
}
.center {
display: flex;
flex-direction: column;
justify-content: space-between;
.price {
display: flex;
flex-direction: column;
color: red;
}
}
}
}
.bottom-box {
box-sizing: border-box;
background-color: #fff;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 100px;
z-index: 9999;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
box-shadow: 100px 104px 288px rgba(0, 0, 0, 0.01);
border-top: 1px solid #f5f5f5;
.left {
display: flex;
align-items: center;
.text-box {
margin-left: 10px;
}
}
}
</style>