Browse Source

fix(app): 商城

EvilDragon 4 months ago
parent
commit
2d7dddc78c

+ 4 - 1
packages/app/env/.env.development

@@ -5,7 +5,7 @@ VITE_DELETE_CONSOLE = false
 # 是否开启sourcemap
 VITE_SHOW_SOURCEMAP = true
 
-VITE_SERVER_BASEURL = 'https://www.zhuchaohui.com'
+# VITE_SERVER_BASEURL = 'https://www.zhuchaohui.com'
 # VITE_SERVER_BASEURL = 'http://39.106.91.179:48080'
 # VITE_SERVER_BASEURL = 'http://192.168.2.34:48080'
 # 王超
@@ -15,3 +15,6 @@ VITE_SERVER_BASEURL = 'https://www.zhuchaohui.com'
 # VITE_SERVER_BASEURL = 'http://192.168.2.38:48080'
 # 赵要军
 # VITE_SERVER_BASEURL = 'http://192.168.2.41:48080'
+# 姚逊涛
+VITE_SERVER_BASEURL = 'http://192.168.2.42:48080'
+

+ 54 - 4
packages/app/src/core/libs/requests.ts

@@ -1,4 +1,4 @@
-import { httpGet, httpPost, httpPut } from '../../utils/http'
+import { http, httpGet, httpPost, httpPut } from '../../utils/http'
 import { Schedule } from '../models/schedule'
 import {
   Category,
@@ -345,7 +345,7 @@ export const getProduct = (id: string) =>
   }>('/app-api/member/product/detail', { productId: id })
 export const getProductItemBuy = (query: { userId: number }) =>
   httpPost<{
-    list: {
+    list: Partial<{
       productId: string
       prodcutName: string
       oneCategory: any
@@ -372,7 +372,7 @@ export const getProductItemBuy = (query: { userId: number }) =>
       favourableStatus: number
       count: number
       createTime: any
-    }[]
+    }>[]
     total: number
   }>('/app-api/member/product-item-buy/select', query)
 /**
@@ -388,6 +388,8 @@ export const createProductItemBuy = (data: {
     id?: number
     productId?: string
     userId?: number
+    points: number
+    nums: number
   }[]
 }) => httpPost('/app-api/member/product-item-buy/create', data)
 /**
@@ -416,6 +418,8 @@ export const productPlacing = (data: {
     productId?: string
     points?: number
     nums?: number
+    productName: string
+    orderImgUrl: string
   }[]
   couponList: {
     couponId: number
@@ -446,7 +450,33 @@ export const orderPay = (data: {
   totalsCurrPoints?: number
 }) => httpPost(`/app-api/member/points-order/placingPay`, data)
 export const getPointsOrders = (query) =>
-  httpGet<{ list: []; total: number }>('/app-api/member/points-order/page', query)
+  httpGet<{
+    list: {
+      id: number
+      materialsId: any
+      materialsBrand: any
+      stylistId: number
+      orderMoney: any
+      projectName: string
+      pointsRate: any
+      points: string
+      orderImgUrl?: string
+      orderStatus: string
+      verifyTime: any
+      completeTime?: number
+      turnDownTime: any
+      cancelTime: number
+      cancelReason: any
+      turnDownReason: any
+      remark: any
+      couponId: any
+      orderNo: string
+      createTime: number
+      brokerageRate: any
+      brokerage: any
+    }[]
+    total: number
+  }>('/app-api/member/points-order/page', query)
 export const getActivities = (query) =>
   httpGet<{
     list: Activity[]
@@ -569,6 +599,26 @@ export const getPoints = (query) =>
     }[]
     total: number
   }>(`/app-api/member/points-details/pageAllByYear/${query.year}`, query)
+/**
+ * 获取会员等级列表
+ */
+export const getMemberLevels = () =>
+  httpGet<
+    {
+      id: number
+      memberLevel: number
+      memberLevelName: string
+      upgradeCriteria: number
+      points: number
+      retentionDaysCriteria: number
+      retentionDays?: number
+      memberBgImage: string
+      associatedMemberRights: string
+      associatedMemberRightsName: any
+      status: number
+      createTime: number
+    }[]
+  >('/app-api/basicsetting/set-member-level-config/list')
 export const refreshToken = (refreshToken: string) =>
   httpPost<any>('/app-api/member/auth/refresh-token', {}, { refreshToken })
 export const httpGetMock = <T>(data: T) =>

+ 26 - 10
packages/app/src/pages/home/activity/detail/index.vue

@@ -11,6 +11,7 @@ import {
   activitySignup,
   getActivity,
   getActivitySignups,
+  getMemberLevels,
   getStudyTour,
   getStudyTourSignups,
   studyTourSignup,
@@ -30,7 +31,7 @@ import { NetImages } from '../../../../core/libs/net-images'
 import signupListDialogBg from '@designer-hub/assets/src/libs/assets/signupListDialogBg'
 import { getActivityStatusText, getCountsArr } from '../../../../core/utils/common'
 import { extractColorsFromImageData } from 'extract-colors/lib/extract-colors.mjs'
-import { sort } from 'radash'
+import { group, sort } from 'radash'
 import { Activity, StudyTour } from '../../../../core/models/moment'
 
 const themeVars = ref<ConfigProviderThemeVars>({
@@ -49,6 +50,7 @@ const { data: signups, run: setSignups } = useRequest(
   () => getActivitySignups({ activityId: id.value }),
   { initialData: { list: [], total: 0 } },
 )
+const { data: levels, run: setLevels } = useRequest(() => getMemberLevels(), { initialData: [] })
 const show = ref(false)
 const successShow = ref(false)
 const listShow = ref(false)
@@ -56,6 +58,18 @@ const dominantColor = ref()
 const palette = ref()
 const isActivity = computed(() => type.value === 'activity')
 const isStudyTour = computed(() => type.value === 'studyTour')
+const levelsById = computed(() =>
+  levels.value.reduce((acc, item) => {
+    acc[item.id] = item
+    return acc
+  }, {}),
+)
+const levelsByMemberLevel = computed(() =>
+  levels.value.reduce((acc, item) => {
+    acc[item.memberLevel] = item
+    return acc
+  }, {}),
+)
 const infos = computed(() => [
   {
     icon: clock,
@@ -71,14 +85,10 @@ const infos = computed(() => [
     title: `${activityTypes.value[type.value]}时间`,
     content: [
       dayjs(
-        'activityStartTime' in data.value
-          ? data.value.activityStartTime
-          : data.value.studyStartTime || data.value.planStudyStartTime,
+        data.value.activityStartTime || data.value.studyStartTime || data.value.planStudyStartTime,
       ).format('YYYY.MM.DD'),
       dayjs(
-        'activityEndTime' in data.value
-          ? data.value.activityEndTime
-          : data.value.studyEndTime || data.value.planStudyEndTime,
+        data.value.activityEndTime || data.value.studyEndTime || data.value.planStudyEndTime,
       ).format('YYYY.MM.DD'),
     ],
     visable: true,
@@ -86,7 +96,7 @@ const infos = computed(() => [
   {
     icon: location,
     title: `${activityTypes.value[type.value]}地点`,
-    content: ['activityAddr' in data.value ? data.value.activityAddr : ''],
+    content: [data.value.activityAddr || ''],
     visable: isActivity.value,
   },
   {
@@ -98,7 +108,11 @@ const infos = computed(() => [
   {
     icon: funnel,
     title: `等级限制`,
-    content: [data.value.memberLevel?.join('、')],
+    content: [
+      data.value.memberLevel
+        ?.map((it) => levelsByMemberLevel.value[String(it)]?.memberLevelName)
+        .join(',') || '',
+    ],
     visable: true,
   },
 ])
@@ -159,6 +173,7 @@ onLoad(async (query: { id: string; type: 'activity' | 'studyTour' }) => {
     })
     .exec()
   await setSignups()
+  await setLevels()
 })
 </script>
 <template>
@@ -222,8 +237,9 @@ onLoad(async (query: { id: string; type: 'activity' | 'studyTour' }) => {
     <div
       class="px-4 py-6 bg-[#010102]/30 backdrop-blur-[20px] rounded-2xl my-8 flex flex-col gap-3"
     >
+      <!-- {{ levelsById }} -->
       <template v-for="(it, i) in infos" :key="i">
-        <div v-if="it.show" class="flex items-center gap-1.5">
+        <div v-if="it.visable" class="flex items-center gap-1.5">
           <wd-img width="16" height="16" :src="it.icon"></wd-img>
           <div
             class="w-[70px] text-[#c1c1c1] text-base font-normal font-['PingFang_SC'] leading-normal"

+ 13 - 9
packages/app/src/pages/home/mall/components/product.vue

@@ -19,15 +19,19 @@ const { userInfo } = storeToRefs(userStore)
 
 const router = useRouter()
 const handleAddToCart = async () => {
-  await requestToast(() =>
-    createProductItemBuy({
-      doList: [
-        {
-          userId: userInfo.value.userId,
-          productId: props.options?.productId || '',
-        },
-      ],
-    }),
+  await requestToast(
+    () =>
+      createProductItemBuy({
+        doList: [
+          {
+            userId: userInfo.value.userId,
+            productId: props.options?.productId || '',
+            points: props.options?.points,
+            nums: 1,
+          },
+        ],
+      }),
+    { success: true, successTitle: '加入购物车成功' },
   )
 }
 </script>

+ 21 - 15
packages/app/src/pages/home/mall/confirm-order/index.vue

@@ -16,11 +16,11 @@ import TrapeziumButton from '@/components/trapezium-button.vue'
 import Card from '@/components/card.vue'
 import SectionHeading from '@/components/section-heading.vue'
 import BottomAppBar from '@/components/bottom-app-bar.vue'
-import { requestToast } from '@/core/utils/common'
-import { orderPay } from '@/core/libs/requests'
-import { useUserStore } from '@/store'
+import { requestToast } from '../../../../core/utils/common'
+import { orderPay } from '../../../../core/libs/requests'
+import { useUserStore } from '../../../../store'
 import { storeToRefs } from 'pinia'
-import { useRouter } from '@/core/utils/router'
+import { useRouter } from '../../../../core/utils/router'
 
 const router = useRouter()
 const userStore = useUserStore()
@@ -50,20 +50,22 @@ onLoad(async (query: { data: string }) => {
   <view class="flex-grow flex flex-col px-3.5 py-5.5 gap-6">
     <Card>
       <div class="flex flex-col gap-6">
-        <template v-for="(it, i) in products" :key="i">
+        <template v-for="(it, i) in data.list" :key="i">
           <div class="flex gap-3">
-            <div class="w-16 h-16 bg-[#f6f6f6] rounded-lg"></div>
+            <div class="w-16 h-16 bg-[#f6f6f6] rounded-lg">
+              <wd-img width="100%" height="100%" :src="it.orderImgUrl"></wd-img>
+            </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.productName }}
               </div>
               <div class="text-black/40 text-xs font-normal font-['PingFang_SC'] leading-normal">
-                1000积分
+                {{ it.points }}积分
               </div>
             </div>
             <div>
               <div class="text-black/90 text-sm font-normal font-['PingFang_SC'] leading-[10.18px]">
-                ×1
+                ×{{ it.nums }}
               </div>
             </div>
           </div>
@@ -72,24 +74,28 @@ onLoad(async (query: { data: string }) => {
     </Card>
     <Card>
       <div class="flex flex-col gap-8">
-        <SectionHeading title="总积分" end-text="1360" size="sm"></SectionHeading>
-        <div @click="show = true">
+        <SectionHeading title="总积分" :end-text="data.totalsPoints" size="sm"></SectionHeading>
+        <!-- <div @click="show = true">
           <SectionHeading title="优惠券" end-text="已选2张" end-arrow size="sm"></SectionHeading>
-        </div>
-        <SectionHeading title="实付积分" end-text="1360" size="sm"></SectionHeading>
+        </div> -->
+        <SectionHeading
+          title="实付积分"
+          :end-text="data.totalsCurrPoints"
+          size="sm"
+        ></SectionHeading>
       </div>
     </Card>
     <BottomAppBar fixed placeholder>
       <div class="h-[63px] bg-white backdrop-blur-[20px] flex px-3.5 items-center justify-between">
         <div class="flex">
           <div class="text-[#ef4343] text-2xl font-normal font-['D-DIN Exp'] leading-normal">
-            1280
+            {{ data.totalsCurrPoints }}
           </div>
           <div class="text-black/40 text-base font-normal font-['PingFang_SC'] leading-[34px]">
             积分
           </div>
         </div>
-        <div class="" @click="show = true">
+        <div class="">
           <TrapeziumButton size="large">
             <div
               class="w-[49px] h-[22px] text-white text-base font-normal font-['PingFang_SC'] leading-tight"

+ 14 - 7
packages/app/src/pages/home/mall/detail/index.vue

@@ -32,14 +32,23 @@ const { data, run: setData } = useRequest(() => getProduct(id.value))
 
 const handleConfirm = async () => {
   if (type.value === 'orderNow') {
-    const { data: res } = await requestToast(() =>
+    const { data: res, code } = await requestToast(() =>
       productPlacing({
         isShoppingCart: 0,
         userId: userInfo.value.userId,
-        list: [{ productId: id.value, points: data.value.needPoints, nums: 1 }],
+        list: [
+          {
+            productId: id.value,
+            points: data.value.points,
+            nums: 1,
+            productName: data.value.prodcutName,
+            orderImgUrl: data.value.productCoverImgUrl,
+          },
+        ],
         couponList: [],
       }),
     )
+    if (code !== 0) return
     router.push(`/pages/home/mall/confirm-order/index?data=${JSON.stringify(res)}`)
   }
 }
@@ -77,9 +86,7 @@ onLoad(async (query: { id: string }) => {
           已售{{ data?.exchangeCount || 0 }}件
         </div>
       </div>
-      <div
-        class="w-[90px] h-4 text-black text-xl font-normal font-['PingFang_SC'] leading-[10.18px]"
-      >
+      <div class="h-4 text-black text-xl font-normal font-['PingFang_SC'] leading-[10.18px]">
         <!-- 阿芙佳朵 -->
         {{ data?.prodcutName }}
       </div>
@@ -146,13 +153,13 @@ onLoad(async (query: { id: string }) => {
             </div>
             <div class="flex items-center">
               <div class="text-[#ef4343] text-[22px] font-normal font-['D-DIN Exp'] leading-normal">
-                {{ data?.needPoints }}
+                {{ data?.points }}
               </div>
               <div class="text-black/40 text-sm font-normal font-['PingFang_SC'] leading-[34px]">
                 积分
               </div>
               <div class="flex-1"></div>
-              <wd-input-number v-model="a" />
+              <!-- <wd-input-number v-model="a" /> -->
             </div>
           </div>
         </div>

+ 16 - 23
packages/app/src/pages/home/mall/index.vue

@@ -12,14 +12,22 @@ import TiltedButton from '@/components/tilted-button.vue'
 import Product from './components/product.vue'
 import { shoppingBag } from '@designer-hub/assets/src/assets/svgs/index'
 import { useRouter } from '../../../core/utils/router'
-import { getBanners, getProductCategories, getProducts } from '../../../core/libs/requests'
+import {
+  getBanners,
+  getProductCategories,
+  getProductItemBuy,
+  getProducts,
+} from '../../../core/libs/requests'
 import PageHelper from '@/components/page-helper.vue'
 import { BannerMode } from '../../../core/models/moment'
 import Banner from '../components/banner.vue'
 import BottomAppBar from '@/components/bottom-app-bar.vue'
+import { useUserStore } from '@/store'
+import { storeToRefs } from 'pinia'
 
 const router = useRouter()
-
+const userStore = useUserStore()
+const { userInfo } = storeToRefs(userStore)
 const { data: productCategories, run: setProductCategories } = useRequest(
   () => getProductCategories(),
   { initialData: [] },
@@ -27,39 +35,24 @@ const { data: productCategories, run: setProductCategories } = useRequest(
 const { data: banners, run: setBanners } = useRequest(() => getBanners({ mode: BannerMode.Mall }), {
   initialData: [],
 })
+const { data: carts, run: setCarts } = useRequest(
+  () => getProductItemBuy({ userId: userInfo.value.userId }),
+  { initialData: { list: [], total: 0 } },
+)
 const current = ref<number>(0)
 const swiperList = computed(() => banners.value.map((it) => it.bannerImgUrl))
 const categories = computed(() => productCategories.value.find(({ id }) => id === 1)?.children)
 const category = ref()
-function handleClick(e) {
-  console.log(e)
-}
-function onChange(e) {
-  console.log(e)
-}
 onMounted(async () => {
   await setProductCategories()
   await setBanners()
+  await setCarts()
   category.value = categories.value[0]
 })
 </script>
 
 <template>
   <view class="bg-white flex-grow flex flex-col px-3.5 py-5.5 gap-5.5">
-    <!-- <wd-swiper
-      custom-class="rounded-2xl overflow-hidden aspect-[2.71/1]"
-      width="100%"
-      height="100%"
-      :list="swiperList"
-      autoplay
-      v-model:current="current"
-      :indicator="{ type: 'dots-bar' } as any"
-      @click="handleClick"
-      @change="onChange"
-    ></wd-swiper> -->
-    <!-- <div class="bg-black rounded-2xl pt-11">
-      <div class="bg-white rounded-2xl shadow p-3.5"></div>
-    </div> -->
     <Banner :mode="BannerMode.Mall"></Banner>
     <div class="w-full inline-flex gap-2">
       <!-- <div><wd-button type="primary" size="small">GELATO专区</wd-button></div> -->
@@ -112,7 +105,7 @@ onMounted(async () => {
               购物车
             </span>
             <span class="h-[22px] text-white text-sm font-normal font-['PingFang_SC']">
-              (已选2件)
+              <template v-if="carts.total">(已选{{ carts.total }}件)</template>
             </span>
           </TiltedButton>
         </div>

+ 6 - 14
packages/app/src/pages/home/mall/shopping-cart/index.vue

@@ -19,21 +19,11 @@ import BottomAppBar from '@/components/bottom-app-bar.vue'
 import { useUserStore } from '../../../../store'
 import { storeToRefs } from 'pinia'
 import { requestToast } from '../../../../core/utils/common'
-import Test from '../components/test.vue'
 import type { ComponentExposed } from 'vue-component-type-helpers'
 
-import { Activity } from '@/core/models/moment'
-
-// typeof PageHelper<string, {list: string[]}>
-// const pageHelperRef =
-//   ref<InstanceType<ReturnType<typeof PageHelper<string, typeof { list: string[] }>>>()
-// const a2 = ref<InstanceType<ReturnType<typeof PageHelper<any, {an}>>>>()
-// const testRef = ref<ComponentExposed<typeof Test<{ aaa: string }>> | undefined>()
 const pageHelperRef = ref<ComponentExposed<typeof PageHelper>>()
-// testRef1.value?
 const userStore = useUserStore()
 const { userInfo } = storeToRefs(userStore)
-const data = ref([{}, {}, {}])
 const a = ref(1)
 const handleDelete = async (product: any) => {
   await requestToast(
@@ -73,7 +63,9 @@ const handleDelete = async (product: any) => {
                 <div class="flex items-center">
                   <div class="w-4 h-4 rounded-full border border-black/60 border-solid"></div>
                 </div>
-                <div class="w-[110px] h-[110px] bg-[#f6f6f6] rounded-2xl"></div>
+                <div class="w-[110px] h-[110px] bg-[#f6f6f6] rounded-2xl">
+                  <wd-img width="100%" height="100%" :src="it.productCoverImgUrl"></wd-img>
+                </div>
                 <div class="flex flex-col justify-between flex-1">
                   <div
                     class="text-black/40 text-base font-normal font-['PingFang_SC'] leading-normal"
@@ -84,7 +76,7 @@ const handleDelete = async (product: any) => {
                     <div
                       class="text-[#ef4343] text-[22px] font-normal font-['D-DIN Exp'] leading-normal"
                     >
-                      1000
+                      {{ it.points }}
                     </div>
                     <div
                       class="text-black/40 text-sm font-normal font-['PingFang_SC'] leading-[34px]"
@@ -92,7 +84,7 @@ const handleDelete = async (product: any) => {
                       积分
                     </div>
                     <div class="flex-1"></div>
-                    <wd-input-number v-model="it.count" />
+                    <wd-input-number v-model="it.nums" />
                   </div>
                 </div>
               </div>
@@ -114,7 +106,7 @@ const handleDelete = async (product: any) => {
     <BottomAppBar fixed border>
       <div class="h-[63px] bg-white backdrop-blur-[20px] flex px-3.5 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">1360</div>
+          <div class="text-[#ef4343] text-2xl font-normal font-['D-DIN_Exp'] leading-6">0</div>
           <div class="text-black text-base font-normal font-['PingFang_SC'] leading-5">积分</div>
         </div>
         <div class="">

+ 7 - 4
packages/app/src/pages/mine/orders/index.vue

@@ -10,6 +10,8 @@ import { storeToRefs } from 'pinia'
 
 const userStore = useUserStore()
 const { userInfo } = storeToRefs(userStore)
+
+const status = ref({ '0': '待交付', '1': '已完成', '2': '已驳回', '3': '已撤销' })
 const handleClick = () => {
   uni.navigateTo({ url: '/pages/mine/orders/detail/index' })
 }
@@ -27,7 +29,7 @@ const handleClick = () => {
                     width="94"
                     height="94"
                     custom-class="rounded-2xl overflow-hidden"
-                    src="https://via.placeholder.com/94x94"
+                    :src="it.orderImgUrl"
                   />
                   <div class="flex flex-col flex-1">
                     <div
@@ -38,20 +40,21 @@ const handleClick = () => {
                     <div
                       class="text-start text-black/40 text-sm font-normal font-['PingFang_SC'] leading-normal"
                     >
-                      x1
+                      x{{ it.nums || 1 }}
                     </div>
                     <div class="flex-1"></div>
                     <div
                       class="text-start text-black/60 text-sm font-normal font-['PingFang_SC'] leading-normal"
                     >
-                      1600积分
+                      {{ it.points }}积分
                     </div>
                   </div>
                   <div>
                     <div
                       class="text-black/40 text-sm font-normal font-['PingFang_SC'] leading-normal"
                     >
-                      已完成
+                      <!-- 已完成 -->
+                      {{ status[it.orderStatus] }}
                     </div>
                   </div>
                 </div>

+ 2 - 2
packages/app/src/pages/mine/points/index.vue

@@ -75,10 +75,10 @@ const { userInfo } = storeToRefs(userStore)
                   <div>
                     <div
                       class="text-lg font-normal font-['D-DIN_Exp'] leading-relaxed"
-                      :class="`${it.points > 0 ? 'text-[#ef4343]' : 'text-black'}`"
+                      :class="`${it.pointsType === '1' ? 'text-[#ef4343]' : 'text-black'}`"
                     >
                       <!-- 8200 -->
-                      {{ it.points > 0 ? '+' : '-' }}
+                      {{ { '1': '+', '2': '-' }[it.pointsType] }}
                       {{ it.points }}
                     </div>
                   </div>