123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- <route lang="json5">
- {
- style: {
- navigationBarTitleText: '购物车',
- navigationBarBackgroundColor: '#fff',
- },
- }
- </route>
- <script setup lang="ts">
- import TiltedButton from '@/components/tilted-button.vue'
- import Product from '../components/product.vue'
- import { shoppingBag } from '@designer-hub/assets/src/assets/svgs/index'
- import InvertedTrapezoidButton from '@/components/inverted-trapezoid-button.vue'
- import TrapeziumButton from '@/components/trapezium-button.vue'
- import {
- createProductItemBuy,
- deleteProductItemBuy,
- getProductItemBuy,
- productPlacing,
- } from '../../../../core/libs/requests'
- import PageHelper from '@/components/page-helper.vue'
- import BottomAppBar from '@/components/bottom-app-bar.vue'
- import { useUserStore } from '../../../../store'
- import { useRouter } from '../../../../core/utils/router'
- import { storeToRefs } from 'pinia'
- import { requestToast } from '../../../../core/utils/common'
- import type { ComponentExposed } from 'vue-component-type-helpers'
- import ButtonEvo from '@/components/button-evo.vue'
- import { usePermissions } from '../../../../composables/permissions'
- const { clickByPermission } = usePermissions()
- const pageHelperRef = ref<ComponentExposed<typeof PageHelper>>()
- const userStore = useUserStore()
- const router = useRouter()
- const { userInfo } = storeToRefs(userStore)
- const selected = ref([])
- const points = computed(() =>
- selected.value.reduce((acc, item) => acc + item.points * item.nums, 0),
- )
- const query = ref({ userId: userInfo.value?.userId })
- const handleSelect = (product) => {
- if (selected.value.map((it) => it.productId).includes(product.productId)) {
- selected.value = selected.value.filter(({ productId }) => productId !== product.productId)
- } else {
- selected.value = [...selected.value, product]
- }
- }
- const handleDelete = async (product: any) => {
- await requestToast(
- () =>
- deleteProductItemBuy({
- doList: [
- {
- productId: product.productId,
- userId: userInfo.value.userId,
- id: product.id,
- deleted: true,
- },
- ],
- }),
- {
- successTitle: '删除成功',
- success: true,
- },
- )
- await pageHelperRef.value?.refresh()
- }
- const handleProductNumsChange = async (nums, product) => {
- const changeNums = nums - product.nums
- if (changeNums > 0) {
- await createProductItemBuy({
- doList: [
- {
- userId: userInfo.value.userId,
- productId: product.productId,
- points: product.points,
- nums: Math.abs(changeNums),
- },
- ],
- })
- if (selected.value.map((it) => it.productId).includes(product.productId)) {
- selected.value = selected.value.map((it) =>
- it.productId === product.productId ? { ...it, nums } : it,
- )
- }
- } else {
- await deleteProductItemBuy({
- doList: [
- {
- productId: product.productId,
- userId: userInfo.value.userId,
- nums: Math.abs(changeNums),
- },
- ],
- })
- if (selected.value.map((it) => it.productId).includes(product.productId)) {
- selected.value = selected.value.map((it) =>
- it.productId === product.productId ? { ...it, nums } : it,
- )
- }
- }
- await pageHelperRef.value?.refresh()
- }
- const handlePlaceOrder = async () => {
- if (!selected.value.length) {
- await uni.showToast({ title: '请选择商品', icon: 'none' })
- return ''
- }
- const { code, data: res } = await requestToast(() =>
- productPlacing({
- isShoppingCart: 1,
- userId: userInfo.value.userId,
- item: 3,
- list: selected.value.map(
- ({ productId, prodcutName, productCoverImgUrl, nums, points, vendorId }) => ({
- productId,
- productName: prodcutName,
- orderImgUrl: productCoverImgUrl,
- nums,
- points,
- vendorId,
- }),
- ),
- couponList: [],
- }),
- )
- if (code === 0) {
- // router.push(`/pages/home/mall/confirm-order`)
- // await deleteProductItemBuy({
- // doList: selected.value.map(({ productId }) => ({
- // productId,
- // deleted: true,
- // userId: userInfo.value.userId,
- // })),
- // })
- pageHelperRef.value?.reload()
- router.push(`/pages/home/mall/confirm-order/index?data=${JSON.stringify(res)}`)
- }
- }
- </script>
- <template>
- <view class="flex-grow flex flex-col gap-14 bg-white px-3.5 py-6">
- <PageHelper
- ref="pageHelperRef"
- :request="getProductItemBuy"
- :query="query"
- class="flex-grow flex flex-col"
- >
- <template #default="{ source }">
- <div class="flex-grow flex flex-col gap-8">
- <!-- {{ selected }} -->
- <template v-for="(it, i) in source.list" :key="i">
- <wd-swipe-action>
- <div class="flex gap-3">
- <div class="flex items-center" @click="handleSelect(it)">
- <div
- class="w-4 h-4 rounded-full border border-black/60 border-solid"
- :class="`${selected.map((it) => it.productId).includes(it.productId) ? 'bg-black' : ''}`"
- ></div>
- </div>
- <div class="w-[110px] h-[110px] bg-[#f6f6f6] rounded-2xl overflow-hidden relative">
- <wd-img width="100%" height="100%" :src="it.productCoverImgUrl"></wd-img>
- <div
- v-if="it.status"
- class="absolute bottom-0 w-full h-5.5 bg-[#D7D7D7] flex items-center justify-center"
- >
- <div
- class="text-black/60 text-xs font-normal font-['PingFang_SC'] leading-normal"
- >
- 已下架
- </div>
- </div>
- <div
- v-if="it.deleted"
- class="absolute bottom-0 w-full h-5.5 bg-[#D7D7D7] flex items-center justify-center"
- >
- <div
- class="text-black/60 text-xs font-normal font-['PingFang_SC'] leading-normal"
- >
- 已失效
- </div>
- </div>
- </div>
- <div class="flex flex-col justify-between flex-1">
- <div
- class="text-black/40 text-base font-normal font-['PingFang_SC'] leading-normal"
- >
- {{ it.prodcutName }}
- </div>
- <div class="flex items-center gap-1.25">
- <div
- class="text-[#ef4343] text-[22px] font-normal font-['D-DIN_Exp'] leading-normal"
- >
- {{ it.points }}
- </div>
- <div
- class="text-black/40 text-sm font-normal font-['PingFang_SC'] leading-[34px]"
- >
- 积分
- </div>
- <div class="flex-1"></div>
- <!-- {{ it.nums }} -->
- <wd-input-number
- :model-value="Number(it.nums)"
- @update:model-value="(e) => handleProductNumsChange(e, it)"
- />
- </div>
- </div>
- </div>
- <template #right>
- <view class="h-full">
- <view
- class="inline-block h-full bg-[#ef4343] text-white flex items-center px-5"
- @click="handleDelete(it)"
- >
- 删除
- </view>
- </view>
- </template>
- </wd-swipe-action>
- </template>
- </div>
- </template>
- </PageHelper>
- <BottomAppBar fixed border>
- <div class="h-[63px] bg-white backdrop-blur-[20px] flex items-center justify-between">
- <div class="flex items-end gap-1.25">
- <div class="text-[#ef4343] text-2xl font-normal font-['D-DIN_Exp'] leading-6">
- {{ points }}
- </div>
- <div class="text-black text-base font-normal font-['PingFang_SC'] leading-5">积分</div>
- </div>
- <div class="" @click="clickByPermission('mallExchange', () => handlePlaceOrder())">
- <ButtonEvo>
- <div
- class="w-[65px] h-[22px] text-white text-base font-normal font-['PingFang_SC'] leading-tight"
- >
- 去结算
- </div>
- </ButtonEvo>
- </div>
- </div>
- </BottomAppBar>
- </view>
- </template>
- <style scoped lang="scss"></style>
|