Prechádzať zdrojové kódy

Merge branch 'main' of https://github.com/omnia96/designer-hub

Jake 3 mesiacov pred
rodič
commit
443b2d0d83

+ 50 - 0
packages/app/src/core/libs/models.ts

@@ -347,6 +347,56 @@ export interface StudyTour {
     clockExplainUrl: string
   }[]
 }
+export interface MyStudyTour {
+  id: number
+  name: string
+  studyType: string
+  planApplyStartTime: number
+  planApplyEndTime?: number
+  planStudyStartTime: number
+  planStudyEndTime?: number
+  planStudyAllowType?: string
+  planStudyAllowCount?: number
+  studyYear: string
+  memberLevel: number[]
+  needPointsType: string
+  needPointsCount?: number
+  badgeId?: number
+  applyStartTime: number
+  applyEndTime: number
+  applyStatus?: number
+  studyStartTime: number
+  studyEndTime: number
+  studyAllowType: string
+  studyAllowCount: number
+  bannerUrl: string
+  thumbnailUrl: string
+  backgroundUrl: string
+  studyDesc: string
+  isTravelPlan: number
+  showStatus: number
+  headRecommend: number
+  signUpCount: any
+  viewCount: number
+  createTime: number
+  ifSingnUp: boolean
+  studyTravelDOList: {
+    createTime: any
+    updateTime: any
+    creator: any
+    updater: any
+    deleted: any
+    id: any
+    studyId: number
+    travelDate: any
+    travelTime: number
+    title: string
+    travelDesc: string
+    clockExplainDesc: string
+    clockExplainUrl: string
+  }[]
+}
+
 export interface Banner {
   id: number
   name: string

+ 6 - 0
packages/app/src/core/libs/requests.ts

@@ -18,6 +18,7 @@ import {
   ResPageData,
   Message,
   Coupon,
+  MyStudyTour,
 } from './models'
 import dayjs from 'dayjs'
 import { pointsCancel } from '../../../../merchant/node_modules/@designer-hub/app/src/core/libs/requests'
@@ -865,6 +866,11 @@ export const getProductCoupons = (query) =>
  */
 export const getPointsCoupons = (query) =>
   httpGet<Coupon[]>('/app-api/member/coupon-user/coupon-user-by-point-ids-page', query)
+/**
+ * 获取已报名的游学
+ */
+export const getMyStudyTours = (query = {}) =>
+  httpGet<MyStudyTour[]>('/app-api/member/app-study-abroad/getSignUpStudyAbroad', query)
 export const refreshToken = (refreshToken: string) =>
   httpPost<any>('/app-api/member/auth/refresh-token', {}, { refreshToken })
 export const httpGetMock = <T>(data: T) =>

+ 88 - 0
packages/app/src/pages/common/components/coupons-selector.vue

@@ -0,0 +1,88 @@
+<script setup lang="ts">
+import { getPointsCoupons, getProductCoupons } from '../../../core/libs/requests'
+import { Coupon } from '../../../core/libs/models'
+import { useUserStore } from '../../../store'
+import { storeToRefs } from 'pinia'
+import CouponCard from './coupon-card.vue'
+
+const props = withDefaults(
+  defineProps<{
+    type: 'points' | 'product'
+    products?: any[]
+    businessId?: number
+    show?: boolean
+  }>(),
+  { show: false },
+)
+const modelValue = defineModel({ default: () => [], type: Array as PropType<Coupon[]> })
+const emits = defineEmits<{ close: [] }>()
+const userStore = useUserStore()
+const { userInfo } = storeToRefs(userStore)
+// const show = ref(false)
+const tab = ref(0)
+const request = ref()
+const { data: coupons, run: setCoupons } = useRequest(() => request.value(), { initialData: [] })
+const handleSelect = (coupon: Coupon) => {
+  if (modelValue.value.map(({ id }) => id).includes(coupon.id)) {
+    modelValue.value = modelValue.value.filter(({ id }) => id !== coupon.id)
+  } else {
+    modelValue.value = [...modelValue.value, coupon]
+  }
+  emits('close')
+}
+watch(
+  () => props.show,
+  async (val) => {
+    console.log(val)
+
+    if (val) {
+      console.log(111111)
+
+      await setCoupons()
+    }
+  },
+)
+onMounted(async () => {
+  if (props.type === 'product') {
+    request.value = () =>
+      getProductCoupons({
+        userId: userInfo.value.userId,
+        productIds: props.products.map((it) => it.productId).join(','),
+        isUse: 0,
+      })
+  }
+  if (props.type === 'points') {
+    request.value = () =>
+      getPointsCoupons({
+        userId: userInfo.value.userId,
+        //   productIds: props.products.map((it) => it.productId).join(','),
+        businessId: props.businessId,
+        isUse: 0,
+      })
+  }
+  //   await setCoupons()
+})
+</script>
+<template>
+  <wd-action-sheet title="优惠券" :modelValue="show" @close="emits('close')">
+    <view class="">
+      <wd-tabs v-model="tab">
+        <wd-tab title="可用优惠券"></wd-tab>
+        <!-- <wd-tab title="不可用优惠券"></wd-tab> -->
+      </wd-tabs>
+      <div class="h-100 overflow-y-scroll">
+        <div class="bg-[#f6f6f6] py-3.5 flex flex-col gap-4 min-h-full">
+          <template v-for="(it, i) in coupons" :key="i">
+            <CouponCard
+              :options="{ couponType: 2, ...it }"
+              canSelect
+              :selected="modelValue?.map(({ id }) => id).includes(it.id)"
+              @select="handleSelect"
+            ></CouponCard>
+          </template>
+        </div>
+      </div>
+      <!-- <wd-button block :round="false">确认</wd-button> -->
+    </view>
+  </wd-action-sheet>
+</template>

+ 27 - 23
packages/app/src/pages/home/components/schedule-card.vue

@@ -1,29 +1,26 @@
 <script setup lang="ts">
 import SectionHeading from '@/components/section-heading.vue'
-import { scheduleCardBg } from '@/core/libs/pngs'
+import { scheduleCardBg } from '../../../core/libs/pngs'
+import { MyStudyTour, StudyTour } from '../../../core/libs/models'
+import { group } from 'radash'
+import dayjs from 'dayjs'
 
-const props = defineProps({
-  customClass: {
-    type: String,
-    default: () => '',
-  },
-  options: {
-    type: Object,
-    default: () => ({
-      items: [
-        { date: '9:00', title: '早稻田大学课程', desc: '学习灯光设计师课程' },
-        { date: '11:00', title: '早稻田大学博物馆参观', desc: '了解博物馆历史' },
-        { date: '15:00', title: '早稻田大学设计交流会', desc: '交流学习设计心得' },
-      ],
-    }),
-  },
+const props = withDefaults(defineProps<{ customClass?: string; items?: MyStudyTour[] }>(), {
+  items: () => [],
 })
 const data = ref()
+const dates = computed(() => {
+  const a = props.items.at(0)?.studyTravelDOList
+  // 使用radash将studyTravelDOList 中的travelTime字段按天分组
+  const b = group(a, (it) => dayjs(it.travelTime).format('YYYY-MM-DD'))
+  console.log(b)
+  return b
+})
 const pull = () => {
-  data.value = props.options.items.slice(0, 3)
+  data.value = props.items.at(0)?.studyTravelDOList.slice(0, 3)
 }
 const push = () => {
-  data.value = props.options.items.slice(0, 2)
+  data.value = props.items.at(0)?.studyTravelDOList.slice(0, 2)
 }
 const handleClick = async () => {
   uni.navigateTo({ url: '/pages/home/schedule/index' })
@@ -38,12 +35,16 @@ onMounted(() => {
     <div
       class="w-full my-3.5 text-[#acacac] text-sm font-normal font-['PingFang_SC'] leading-normal"
     >
-      6月26日 第二天
+      <!-- 6月26日 第二天 -->
+      <!-- {{ dates }} -->
+      <!-- {{ items?.at(0)?.studyTravelDOList?.at(0)?.travelTime }} -->
+      {{ Object.keys(dates).at(0) }}
+      第{{ 1 }}天
     </div>
     <div
       class="w-80 bg-gradient-to-r from-[#141414] to-[#4b4949] rounded-tl-2xl rounded-tr-2xl p-6 box-border"
     >
-      <template v-for="(it, index) in data" :key="index">
+      <template v-for="(it, index) in Object.values(dates)" :key="index">
         <view class="relative mb-4">
           <view class="flex items-center">
             <div class="w-2 h-2 left-0 top-0 rounded-full border-2 border-solid border-white"></div>
@@ -51,14 +52,17 @@ onMounted(() => {
             <div
               class="w-12 ml-3.5 text-white text-base font-normal font-['PingFang_SC'] leading-normal"
             >
-              9:00
+              <!-- 9:00 -->
+              {{ dayjs(it.at(0)?.travelTime).format('HH:mm') }}
             </div>
             <div class="text-white text-base font-normal font-['PingFang_SC'] leading-normal">
-              早稻田大学课程
+              <!-- 早稻田大学课程 -->
+              {{ it.at(0)?.title }}
             </div>
           </view>
           <div class="ml-6.5 text-white/40 text-sm font-normal font-['PingFang_SC'] leading-normal">
-            学习灯光设计师课程
+            <!-- 学习灯光设计师课程 -->
+            {{ it.at(0)?.travelDesc }}
           </div>
           <div
             v-if="index !== data?.length - 1"

+ 14 - 2
packages/app/src/pages/home/index.vue

@@ -16,7 +16,12 @@ import MomentItem from '@/components/moment-item.vue'
 import HomeBanner from './components/home-banner.vue'
 import useRequest from '../../hooks/useRequest'
 import Menus from './components/menus.vue'
-import { getCircles, getSetIndexConfigs, shareCircle } from '../../core/libs/requests'
+import {
+  getCircles,
+  getMyStudyTours,
+  getSetIndexConfigs,
+  shareCircle,
+} from '../../core/libs/requests'
 import { logo } from '../../core/libs/svgs'
 import PageHelper from '@/components/page-helper.vue'
 import { ComponentExposed } from 'vue-component-type-helpers'
@@ -25,6 +30,7 @@ import { storeToRefs } from 'pinia'
 import { messages } from '../../core/libs/messages'
 import { handleUpvoteClick, handleShareClick } from '../../core/libs/actions'
 import { useUserStore } from '../../store'
+import ScheduleCard from './components/schedule-card.vue'
 
 defineOptions({
   name: 'Home',
@@ -37,6 +43,9 @@ const { data: indexConfigsData, run: setIndexConfigsData } = useRequest(
   () => getSetIndexConfigs(),
   { initialData: { list: [] } },
 )
+const { data: studyTours, run: setStudyTours } = useRequest(() => getMyStudyTours(), {
+  initialData: [],
+})
 const swiperData = ref<{ data: any }[]>()
 const swiperCurrent = ref(0)
 
@@ -45,6 +54,7 @@ onShow(async () => {
 })
 onLoad(async () => {
   await setIndexConfigsData()
+  await setStudyTours()
   swiperData.value = indexConfigsData.value.list.map((it) => ({
     data: it,
   }))
@@ -124,7 +134,9 @@ onShareAppMessage(async ({ from, target }) => {
       </swiper>
     </view>
     <view class="bg-[#f6f6f6] relative bottom-4 rounded-t-2xl py-1">
-      <!-- <ScheduleCard custom-class="my-6 mx-3.5"></ScheduleCard> -->
+      <template v-if="studyTours?.length">
+        <ScheduleCard custom-class="my-6 mx-3.5" :items="studyTours"></ScheduleCard>
+      </template>
       <menus></menus>
       <!-- <view class="my-6 mx-3.5">
         <HotActivity></HotActivity>

+ 69 - 8
packages/app/src/pages/home/mall/confirm-order/index.vue

@@ -24,7 +24,9 @@ import { useRouter } from '../../../../core/utils/router'
 import dayjs from 'dayjs'
 import { Coupon } from '../../../../core/libs/models'
 import CouponCard from '@/pages/common/components/coupon-card.vue'
-import { select } from 'radash'
+import { select, sort } from 'radash'
+import CouponsSelector from '@/pages/common/components/coupons-selector.vue'
+import { right } from '../../../../core/libs/svgs'
 
 const router = useRouter()
 const userStore = useUserStore()
@@ -40,7 +42,27 @@ const { data: coupons, run: setCoupons } = useRequest(() =>
     isUse: 0,
   }),
 )
-const paidPoints = computed(() => (data.value?.totalsPoints || 0).toString())
+const offerPoints = computed(() => {
+  const products = sort(data.value?.list, (it: any) => it.points).reverse()
+  let sumBrandPoints = 0
+  products.forEach((product: any) => {
+    if (selectedCoupons.value) {
+      selectedCoupons.value.forEach((coupon) => {
+        if (
+          coupon.buinessId === product.vendorId &&
+          coupon.productIds.split(',').includes(product.productId)
+        ) {
+          sumBrandPoints += product.points
+        }
+      })
+    }
+  })
+  console.log(sumBrandPoints)
+  return Number(sumBrandPoints)
+})
+const paidPoints = computed(() => {
+  return (data.value?.totalsPoints - offerPoints.value || 0).toString()
+})
 const handlePay = async () => {
   console.log(111)
 
@@ -63,7 +85,7 @@ const handlePay = async () => {
   }
 }
 const handleQ = async () => {
-  await setCoupons()
+  // await setCoupons()
   show.value = true
 }
 const handleSelect = (coupon: Coupon) => {
@@ -114,7 +136,39 @@ onLoad(async (query: { data: string }) => {
             :end-text="`已选${selectedCoupons?.length || 0}张`"
             end-arrow
             size="sm"
-          ></SectionHeading>
+          >
+            <template #start>
+              <div
+                v-if="selectedCoupons?.length"
+                class="px-1 py-.75 rounded border border-solid border-[#ef4343] justify-center items-center gap-2.5 inline-flex"
+              >
+                <div
+                  class="text-[#ef4343] text-[9px] font-normal font-['PingFang_SC'] leading-[10.18px]"
+                >
+                  已选{{ selectedCoupons?.length }}张
+                </div>
+              </div>
+            </template>
+            <template #append>
+              <div class="flex items-center gap-1">
+                <template v-if="!selectedCoupons?.length">
+                  <div
+                    class="text-black/40 text-sm font-normal font-['PingFang SC'] leading-[10.18px]"
+                  >
+                    选择优惠券
+                  </div>
+                </template>
+                <template v-else>
+                  <div
+                    class="text-[#ef4343] text-sm font-normal font-['PingFang SC'] leading-[10.18px]"
+                  >
+                    -{{ offerPoints }}
+                  </div>
+                </template>
+                <wd-img :src="right" width="12" height="12"></wd-img>
+              </div>
+            </template>
+          </SectionHeading>
         </div>
         <SectionHeading title="实付积分" :end-text="paidPoints" size="sm"></SectionHeading>
       </div>
@@ -123,7 +177,7 @@ onLoad(async (query: { data: string }) => {
       <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">
-            {{ data?.totalsCurrPoints || data?.totalsPoints - data?.totalsCouponPoints }}
+            {{ paidPoints }}
           </div>
           <div class="text-black/40 text-base font-normal font-['PingFang_SC'] leading-[34px]">
             积分
@@ -143,7 +197,15 @@ onLoad(async (query: { data: string }) => {
         </div>
       </div>
     </BottomAppBar>
-    <wd-action-sheet title="优惠券" v-model="show">
+    <CouponsSelector
+      v-model="selectedCoupons"
+      type="product"
+      :show="show"
+      :products="data?.list"
+      @close="show = false"
+    ></CouponsSelector>
+    <!-- <CouponsSelector></CouponsSelector> -->
+    <!-- <wd-action-sheet title="优惠券" v-model="show">
       <view class="">
         <wd-tabs>
           <wd-tab title="可用优惠券"></wd-tab>
@@ -159,9 +221,8 @@ onLoad(async (query: { data: string }) => {
             ></CouponCard>
           </template>
         </div>
-        <!-- <wd-button block :round="false">确认</wd-button> -->
       </view>
-    </wd-action-sheet>
+    </wd-action-sheet> -->
   </view>
 </template>
 

+ 34 - 0
packages/app/src/pages/home/mall/confirm-order/test.java

@@ -0,0 +1,34 @@
+// // 订单按照积分从大到小排序
+//             orderVOList.sort(Comparator.comparingInt(OrderVO::getPoints).reversed());
+//             for (OrderVO orderVO : orderVOList) {
+//                 Integer sumBrandPoints = 0;
+//                 // TODO 优惠券使用
+//                 if (CollUtil.isNotEmpty(orderCouponVOList)){
+//                     for (OrderCouponVO orderCouponVO : orderCouponVOList) {
+//                         //判断商品ID在优化卷ID中包含
+//                         if (orderCouponVO.getBuinessId().equals(orderVO.getVendorId())
+//                                 && orderCouponVO.getProjectIds().contains(orderVO.getProductId())){
+//                             sumBrandPoints += orderVO.getPoints();
+//                             orderCouponVO.setBrandPoints(orderVO.getPoints());
+
+//                             CouponUserDO couponUserDO = new CouponUserDO();
+//                             couponUserDO.setId(orderCouponVO.getCouponId());
+//                             couponUserDO.setIsUse(1);
+//                             couponUserDO.setUserId(pointsOrderSaveReqListVO.getUserId());
+//                             couponUserDO.setBrandPoints(orderCouponVO.getBrandPoints());
+//                             couponUserDO.setUseTime(LocalDateTime.now());
+//                             couponUserDO.setBuinessId(orderVO.getVendorId());
+//                             couponUserDO.setOrderNo(orderVO.getOrderNo());
+//                             couponUserService.goUpdateCouponUser(couponUserDO, false);
+//                         }
+//                     }
+
+
+//                     //优惠总积分
+//                     Integer sumBrandTotalsPoints = orderCouponVOList.stream()
+//                             .map(orderCouponVO -> ObjUtil.defaultIfNull(orderCouponVO.getBrandPoints(),0))
+//                             .mapToInt(Integer::intValue)
+//                             .sum();
+
+//                     pointsOrderSaveReqListVO.setTotalsCouponPoints(sumBrandTotalsPoints);
+//                 }

+ 96 - 66
packages/app/src/pages/home/schedule/index.vue

@@ -5,21 +5,27 @@ style:
 </route>
 <script setup lang="ts">
 import TiltedButton from '@/components/tilted-button.vue'
-import { getSchedule, getUserInfo } from '@/core/libs/requests'
-import { camera, map } from '@/core/libs/svgs'
+import { getMyStudyTours, getSchedule, getUserInfo } from '../../../core/libs/requests'
+import { camera, map } from '../../../core/libs/svgs'
+import { useUserStore } from '../../../store'
+import { storeToRefs } from 'pinia'
+import { group } from 'radash'
+import dayjs from 'dayjs'
+import NavbarEvo from '@/components/navbar-evo.vue'
 
-const { data, run } = useRequest(getSchedule)
-const { data: userInfo, run: runUserInfo } = useRequest(getUserInfo)
+const userStore = useUserStore()
+const { userInfo } = storeToRefs(userStore)
+const { data, run } = useRequest(() => getMyStudyTours(), { initialData: [] })
 
 onMounted(() => {
   run()
-  runUserInfo()
 })
 </script>
 <template>
   <view class="">
+    <NavbarEvo transparent dark></NavbarEvo>
     <view class="bg-black w-full pos-relative aspect-[1.26/1]">
-      <wd-img width="100%" height="100%" :src="data?.cover" />
+      <!-- <wd-img width="100%" height="100%" :src="data?.cover" /> -->
       <div
         class="w-[375px] h-[90px] bg-gradient-to-t from-black to-black/0 absolute left-0 bottom-0 w-full flex items-center"
       >
@@ -31,73 +37,97 @@ onMounted(() => {
       </div>
     </view>
     <view class="bg-white relative bottom-4 rounded-t-2xl p-6.5">
-      <view class="border-b border-black/10 border-b-solid pb-5">
-        <div class="text-black/90 text-2xl font-normal font-['PingFang_SC'] leading-normal">
-          {{ data?.name }}
-        </div>
-        <view class="flex mt-5">
-          <wd-img
-            custom-class="rounded-full overflow-hidden mr-1"
-            width="22"
-            height="22"
-            :src="userInfo?.avatar"
-          />
-          <div class="text-black/40 text-base font-normal font-['PingFang_SC'] leading-normal">
-            {{ userInfo?.nickname }}
+      <template v-for="(it, i) in data" :key="i">
+        <view class="border-b border-black/10 border-b-solid pb-5">
+          <div class="text-black/90 text-2xl font-normal font-['PingFang_SC'] leading-normal">
+            {{ it.name }}
           </div>
-          <div class="flex text-black/40 text-base font-normal font-['PingFang_SC'] leading-normal">
-            <view class="mx-3.5">|</view>
-            6月26日 第二天
-          </div>
-        </view>
-      </view>
-      <template v-for="(it, index) in data.items" :key="index">
-        <view class="grid grid-gap-2 mt-8">
-          <view class="col-start-1 row-start-1 flex items-center justify-center">
-            <view
-              class="w-[27px] h-[27px] bg-[#f6f6f6] rounded-full flex justify-center items-center"
-            >
-              <wd-img width="16" height="16" :src="map"></wd-img>
-            </view>
-          </view>
-          <view class="col-start-2 row-start-1 flex">
-            <div
-              class="text-black/90 text-base font-normal font-['PingFang_SC'] leading-normal mr-5"
-            >
-              {{ it.time }}
-            </div>
-            <div class="text-black/90 text-base font-normal font-['PingFang_SC'] leading-normal">
-              {{ it.title }}
-            </div>
-          </view>
-          <view class="col-start-2 row-start-2 border-b border-black/10 border-b-solid pb-5">
-            <div class="">
-              <span class="text-black/60 text-sm font-normal font-['PingFang_SC'] leading-[23px]">
-                行程介绍:
-              </span>
-              <span class="text-black/40 text-sm font-normal font-['PingFang_SC'] leading-[23px]">
-                {{ it.content }}
-              </span>
-            </div>
-            <view class="flex items-center my-4">
-              <wd-img width="16" height="16" :src="camera"></wd-img>
+          <template
+            v-for="(date, index) in group(it.studyTravelDOList, (it) =>
+              dayjs(it.travelTime).format('YYYY-MM-DD'),
+            )"
+            :key="index"
+          >
+            <view class="flex mt-5">
+              <wd-img
+                custom-class="rounded-full overflow-hidden mr-1"
+                width="22"
+                height="22"
+                :src="userInfo?.avatar"
+              />
+              <div class="text-black/40 text-base font-normal font-['PingFang_SC'] leading-normal">
+                {{ userInfo?.nickname }}
+              </div>
               <div
-                class="ml-1 text-black/90 text-xs font-normal font-['PingFang_SC'] leading-normal"
+                class="flex text-black/40 text-base font-normal font-['PingFang_SC'] leading-normal"
               >
-                打卡示例
+                <view class="mx-3.5">|</view>
+                <!-- 6月26日 第二天 -->
+                {{
+                  // Object.keys(
+                  //   group(it.studyTravelDOList, (it) => dayjs(it.travelTime).format('YYYY-MM-DD')),
+                  // )
+                  dayjs(date.at(i).travelTime).format('MM月DD日')
+                }}
               </div>
             </view>
-            <img class="w-[285px] h-[157px] rounded-lg" :src="it.momentExample" />
-            <div
-              class="mt-2.5 text-black/40 text-xs font-normal font-['PingFang_SC'] leading-normal"
-            >
-              {{ it.monentHint }}
-            </div>
-          </view>
+            <template v-for="(item, itemIndex) in date" :key="itemIndex">
+              <view class="grid grid-gap-2 mt-8">
+                <view class="col-start-1 row-start-1 flex items-center justify-center">
+                  <view
+                    class="w-[27px] h-[27px] bg-[#f6f6f6] rounded-full flex justify-center items-center"
+                  >
+                    <wd-img width="16" height="16" :src="map"></wd-img>
+                  </view>
+                </view>
+                <view class="col-start-2 row-start-1 flex">
+                  <div
+                    class="text-black/90 text-base font-normal font-['PingFang_SC'] leading-normal mr-5"
+                  >
+                    {{ dayjs(item.travelTime).format('HH:mm') }}
+                  </div>
+                  <div
+                    class="text-black/90 text-base font-normal font-['PingFang_SC'] leading-normal"
+                  >
+                    {{ item.title }}
+                  </div>
+                </view>
+                <view class="col-start-2 row-start-2 border-b border-black/10 border-b-solid pb-5">
+                  <div class="">
+                    <span
+                      class="text-black/60 text-sm font-normal font-['PingFang_SC'] leading-[23px]"
+                    >
+                      行程介绍:
+                    </span>
+                    <span
+                      class="text-black/40 text-sm font-normal font-['PingFang_SC'] leading-[23px]"
+                      v-html="item.travelDesc"
+                    ></span>
+                  </div>
+                  <view class="flex items-center my-4">
+                    <wd-img width="16" height="16" :src="camera"></wd-img>
+                    <div
+                      class="ml-1 text-black/90 text-xs font-normal font-['PingFang_SC'] leading-normal"
+                    >
+                      打卡示例
+                    </div>
+                  </view>
+                  <img class="w-[285px] h-[157px] rounded-lg" :src="item.clockExplainUrl" />
+                  <div
+                    class="mt-2.5 text-black/40 text-xs font-normal font-['PingFang_SC'] leading-normal"
+                  >
+                    {{ item.clockExplainDesc }}
+                  </div>
+                </view>
+              </view>
+            </template>
+            <!-- <template v-for="(it, index) in data.items" :key="index">
+            </template> -->
+          </template>
         </view>
       </template>
     </view>
-    <div
+    <!-- <div
       class="mx-3.5 p-3.5 bg-white/90 rounded-2xl backdrop-blur-[20px] fixed bottom-4 left-0 right-0 flex items-center justify-between"
     >
       <div class="text-black/40 text-sm font-normal font-['PingFang_SC'] leading-[34px]">
@@ -113,6 +143,6 @@ onMounted(() => {
           <view class="px-3">发圈子</view>
         </TiltedButton>
       </view>
-    </div>
+    </div> -->
   </view>
 </template>

+ 2 - 2
packages/app/src/pages/messages/components/message-card.vue

@@ -11,7 +11,7 @@ const props = withDefaults(defineProps<{ options?: Message }>(), {})
 const emits = defineEmits<{
   submit: [message: Message]
   cancel: [message: Message]
-  selectCoupon: [coupons: any[]]
+  selectCoupon: [message: Message, coupons: any[]]
 }>()
 const { data: coupons, run: setCoupons } = useRequest(
   () =>
@@ -74,7 +74,7 @@ onMounted(async () => {
               </div>
               <div
                 class="flex items-center"
-                @click="coupons.length && emits('selectCoupon', coupons)"
+                @click="coupons.length && emits('selectCoupon', options, coupons)"
               >
                 <div
                   class="text-sm font-normal font-['PingFang_SC']"

+ 15 - 36
packages/app/src/pages/messages/index.vue

@@ -18,7 +18,6 @@ import {
   orderPointsSubmit,
   updateMessage,
 } from '../../core/libs/requests'
-import dayjs from 'dayjs'
 import { MessageType } from '../../core/libs/enums'
 import { ComponentExposed } from 'vue-component-type-helpers'
 import { Coupon, Message } from '../../core/libs/models'
@@ -26,9 +25,8 @@ import { requestToast } from '../../core/utils/common'
 import { useUserStore } from '../../store'
 import { storeToRefs } from 'pinia'
 import MessageCard from './components/message-card.vue'
-import CouponCard from '../common/components/coupon-card.vue'
-import { select } from 'radash'
 import { useMessage } from 'wot-design-uni'
+import CouponsSelector from '../common/components/coupons-selector.vue'
 
 const pageHelperRef = ref<ComponentExposed<typeof PageHelper>>()
 const userStore = useUserStore()
@@ -40,9 +38,10 @@ const tabs = ref([
   { label: '系统消息', value: MessageType.System },
   { label: '互动消息', value: MessageType.Interact },
 ])
-const selectedCoupon = ref()
+const selectedCoupons = ref<Coupon[]>([])
 const coupons = ref<Coupon[]>([])
 const cancelReason = ref('')
+const currentMessage = ref<Message>()
 const { confirm } = useMessage('wd-message-box-slot')
 
 const query = computed(() => ({ messageType: tabs.value[tab.value]?.value }))
@@ -77,7 +76,7 @@ const handleSubmit = async (message: Message) => {
       orderPointsSubmit({
         id: message.businessId,
         userId: message.designerId,
-        couponUserId: selectedCoupon.value?.id,
+        couponUserId: selectedCoupons.value[0]?.id,
       }),
     {
       success: true,
@@ -87,24 +86,16 @@ const handleSubmit = async (message: Message) => {
   // await deleteMessage(message.id.toString())
   await updateMessage({ id: message.id, isRead: '1' })
   await pageHelperRef.value?.refresh()
-  selectedCoupon.value = undefined
+  selectedCoupons.value = []
 }
-const handleQ = async (res) => {
-  // const { data } = await getPointsCoupons({
-  //   userId: message.designerId,
-  //   businessId: message.businessId,
-  // })
-  // console.log(data)
+const handleQ = async (msg, res) => {
+  currentMessage.value = msg
   coupons.value = res
   show.value = true
 }
-const handleSelect = (coupon: Coupon) => {
-  selectedCoupon.value = coupon
-  show.value = false
-}
 onShow(async () => {
   nextTick(() => {
-    pageHelperRef.value?.refresh()
+    pageHelperRef.value?.reload()
   })
 })
 </script>
@@ -148,25 +139,13 @@ onShow(async () => {
         />
       </wd-config-provider>
     </wd-message-box>
-    <wd-action-sheet title="优惠券" v-model="show">
-      <view class="">
-        <wd-tabs>
-          <wd-tab title="可用优惠券"></wd-tab>
-          <wd-tab title="不可用优惠券"></wd-tab>
-        </wd-tabs>
-        <div class="bg-[#f6f6f6] py-3.5 flex flex-col gap-4">
-          <template v-for="(it, i) in coupons" :key="i">
-            <CouponCard
-              :options="it"
-              can-select
-              :selected="selectedCoupon?.id === it.id"
-              @select="handleSelect"
-            ></CouponCard>
-          </template>
-        </div>
-        <!-- <wd-button block :round="false">确认</wd-button> -->
-      </view>
-    </wd-action-sheet>
+    <CouponsSelector
+      v-model="selectedCoupons"
+      type="points"
+      :show="show"
+      :business-id="currentMessage?.businessId"
+      @close="show = false"
+    ></CouponsSelector>
   </view>
 </template>
 

+ 1 - 1
packages/app/src/pages/mine/index.vue

@@ -360,7 +360,7 @@ onPageScroll(({ scrollTop }: { scrollTop: number }) => {
           <div class="flex items-center">
             <div class="flex-1"></div>
             <div
-              class="h-[22px] bg-gradient-to-r from-[#333333] to-[#20201e] rounded-tl-[20px] rounded-bl-[20px] mr--3.5 px-2 mt-3"
+              class="bg-gradient-to-r from-[#333333] to-[#20201e] rounded-tl-[20px] rounded-bl-[20px] mr--3.5 px-2 mt-3"
               @click="router.push('/pages/mine/levels/index')"
             >
               <div class="text-xs font-normal font-['PingFang_SC'] leading-relaxed color-[#f3f3f3]">

+ 4 - 1
packages/app/src/pages/mine/levels/index.vue

@@ -79,7 +79,10 @@ onMounted(async () => {
         </swiper>
       </div>
     </div>
-    <template v-for="(it, index) in levelConfigs[current].setMemberRights" :key="index">
+    <template
+      v-for="(it, index) in sort(levelConfigs, (it) => it.memberLevel)[current].setMemberRights"
+      :key="index"
+    >
       <div
         class="bg-[#201d28] rounded-2xl shadow border border-[#504951] border-solid flex gap-4 px-2.5 py-5.5"
       >

+ 11 - 1
packages/app/src/pages/mine/orders/index.vue

@@ -9,19 +9,29 @@ import { useUserStore } from '../../../store'
 import { storeToRefs } from 'pinia'
 import { PointsOrder } from '../../../core/libs/models'
 import { useRouter } from '../../../core/utils/router'
+import { ComponentExposed } from 'vue-component-type-helpers'
 
 const userStore = useUserStore()
 const { userInfo } = storeToRefs(userStore)
 const router = useRouter()
 
 const status = ref({ '0': '待交付', '1': '已完成', '2': '已驳回', '3': '已撤销' })
+const pageHelperRef = ref<ComponentExposed<typeof PageHelper>>()
 const handleClick = (order: PointsOrder) => {
   router.push(`/pages/mine/orders/detail/index?id=${order.id}`)
 }
+onShow(async () => {
+  await pageHelperRef.value?.refresh()
+})
 </script>
 <template>
   <div class="flex-grow flex flex-col gap-4 px-3.5 py-5">
-    <PageHelper :request="getPointsOrders" :query="{}" class="flex-grow flex flex-col">
+    <PageHelper
+      ref="pageHelperRef"
+      :request="getPointsOrders"
+      :query="{}"
+      class="flex-grow flex flex-col"
+    >
       <template #default="{ source }">
         <div class="flex-grow flex flex-col gap-4">
           <template v-for="(it, i) in source.list" :key="i">