Parcourir la source

fix(app): 优化材料商页面展示效果和数据获取

EvilDragon il y a 4 mois
Parent
commit
7bf556ed8f

+ 23 - 0
packages/app/src/components/navbar-evo.vue

@@ -0,0 +1,23 @@
+<script lang="ts" setup>
+import { useRouter } from '../core/utils/router'
+
+defineProps({
+  transparent: {
+    type: Boolean,
+    default: false,
+  },
+})
+const router = useRouter()
+</script>
+<template>
+  <wd-config-provider>
+    <wd-navbar
+      fixed
+      left-arrow
+      safe-area-inset-top
+      :bordered="false"
+      :custom-class="`${transparent ? 'bg-transparent!' : ''}`"
+      @click-left="router.back()"
+    ></wd-navbar>
+  </wd-config-provider>
+</template>

+ 12 - 1
packages/app/src/components/section-heading.vue

@@ -10,6 +10,10 @@ const props = defineProps({
     type: String,
     default: () => '',
   },
+  subtitle: {
+    type: String,
+    default: undefined,
+  },
   path: {
     type: String as PropType<string | undefined>,
     default: () => undefined,
@@ -33,7 +37,11 @@ const handleMore = async () => {
 }
 </script>
 <template>
-  <view class="flex justify-between items-center" :class="[customClass]" @click="handleMore">
+  <view
+    class="flex justify-between items-center gap-2.5"
+    :class="[customClass]"
+    @click="handleMore"
+  >
     <div
       class="font-normal"
       :class="[
@@ -43,6 +51,9 @@ const handleMore = async () => {
     >
       {{ title }}
     </div>
+    <div class="text-black/60 text-xs font-normal font-['PingFang SC'] leading-[10.18px]">
+      {{ subtitle }}
+    </div>
     <div class="overflow-hidden flex-1">
       <slot name="start"></slot>
     </div>

+ 11 - 2
packages/app/src/core/libs/requests.ts

@@ -1,6 +1,13 @@
 import { httpGet, httpPost, httpPut } from '../../utils/http'
 import { Schedule } from '../models/schedule'
-import { Content, DictType, MaterialDealer, MaterialDealerRes, Moment } from '../models/moment'
+import {
+  Content,
+  DictType,
+  MaterialDealer,
+  MaterialDealerDetail,
+  MaterialDealerRes,
+  Moment,
+} from '../models/moment'
 import dayjs from 'dayjs'
 
 export const getUserInfo = () =>
@@ -268,7 +275,9 @@ export const getMaterials = (query = {}) =>
 export const getAppMaterials = () =>
   httpGet<MaterialDealerRes[]>('/app-api/member/materials/appMaterialsList')
 export const getAppMaterial = (id: number) =>
-  httpGet<MaterialDealerRes>('/app-api/member/materials/queryHomePage', { id })
+  httpGet<MaterialDealerDetail>('/app-api/member/materials/queryHomePage', { materialsId: id })
+export const getMaterialDetail = (query: { id: string }) =>
+  httpGet<MaterialDealerDetail>('/app-api/member/materials/getDetail', query)
 export const createMaterialsReferrer = (data) =>
   httpPost('/app-api/member/materials-referrer/create', data)
 export const getContents = (query: { contentType: string; contentCategory?: string }) =>

+ 33 - 0
packages/app/src/core/models/moment.ts

@@ -109,6 +109,31 @@ export interface MaterialDealerRes {
   pointsRate: number
   materialsList: MaterialsList[]
 }
+export interface FodderList {
+  createTime: number
+  updateTime: number
+  creator: string
+  updater: string
+  deleted: boolean
+  id: number
+  materialsId: number
+  fodderUrl: string
+}
+export interface ProductDolist {
+  createTime: number
+  updateTime: number
+  creator: string
+  updater: string
+  deleted: boolean
+  id: number
+  materialsId: number
+  productTitleId: any
+  productTitleName: string
+  productImgUrl: string
+}
+export interface MaterialDealerDetail extends MaterialDealer {
+  shopList: ShopList[]
+}
 export interface Content {
   id: number
   /**
@@ -209,6 +234,14 @@ export enum DictType {
    * 内容分类-线下活动
    */
   offlineActivity = 'offline_activity',
+  /**
+   * 材料商-品牌-类型
+   */
+  memberMaterialsBrandType = 'member_materials_brand_type',
+  /**
+   * 材料商-经营-品牌
+   */
+  materialsManageBrand = 'member_materials_manage_brand',
 }
 export enum CircleType {
   moment = '1',

+ 63 - 31
packages/app/src/pages/material/detail/index.vue

@@ -4,54 +4,82 @@
 <script setup lang="ts">
 import Card from '@/components/card.vue'
 import SectionHeading from '@/components/section-heading.vue'
-import { getAppMaterial } from '../../../core/libs/requests'
+import { getMaterialDetail, getByDictType } from '../../../core/libs/requests'
+import NavbarEvo from '@/components/navbar-evo.vue'
+import { DictType } from '../../../core/models/moment'
 
 const id = ref()
-const { data, run: setData } = useRequest(() => getAppMaterial(id.value))
-const handleBackClick = () => {
-  uni.navigateBack()
-}
+const { data, run: setData } = useRequest(() => getMaterialDetail({ id: id.value }))
+const { data: materialBrandLevels, run: setMaterialBrandLevels } = useRequest(
+  () => getByDictType(DictType.memberMaterialsBrandLevel),
+  { initialData: [] },
+)
+const { data: materialOperationTypes, run: setMaterialOperationTypes } = useRequest(
+  () => getByDictType(DictType.memberMaterialsOperationType),
+  { initialData: [] },
+)
+const { data: materialBrandTypes, run: setMaterialBrandTypes } = useRequest(
+  () => getByDictType(DictType.memberMaterialsBrandType),
+  { initialData: [] },
+)
+const { data: materialsManageBrands, run: setMaterialsManageBrands } = useRequest(
+  () => getByDictType(DictType.materialsManageBrand),
+  { initialData: [] },
+)
 onLoad(async (query: { id: number }) => {
   id.value = query.id
   await setData()
   console.log(data.value)
+  await Promise.all([
+    setMaterialBrandLevels(),
+    setMaterialBrandTypes(),
+    setMaterialOperationTypes(),
+    setMaterialsManageBrands(),
+  ])
 })
 </script>
 <template>
-  <view class="">
+  <view class="flex-grow flex flex-col">
     <div
-      class="w-full aspect-[1.16/1] bg-[url(https://image.zhuchaohui.com/zhucaohui/9da274c73312f5ff828b60457bf4a469e631c001a4bf1c1f355338887b19f035.png)] bg-contain"
+      class="w-full aspect-[1.16/1] bg-[url(https://image.zhuchaohui.com/zhucaohui/9da274c73312f5ff828b60457bf4a469e631c001a4bf1c1f355338887b19f035.png)] bg-[length:100%]"
+      :style="{ backgroundImage: `url(${data?.bannerUrl})` }"
     ></div>
-    <wd-navbar
-      fixed
-      left-arrow
-      safe-area-inset-top
-      custom-class="bg-transparent!"
-      :bordered="false"
-      @click-left="handleBackClick"
-    ></wd-navbar>
+    <NavbarEvo transparent></NavbarEvo>
     <div class="flex flex-col gap-6 relative top--14 px-3.5">
       <Card>
-        <div class="flex">
+        <div class="flex gap-5">
           <wd-img
             round
             width="78"
             height="78"
             custom-class="border border-[#f2f2f2] border-solid"
-            src="https://via.placeholder.com/78x78"
+            :src="data?.logoUrl"
           ></wd-img>
-          <div>
-            <div class="text-black/90 text-lg font-normal font-['PingFang SC'] leading-[10.18px]">
-              IMOLA瓷砖
+          <div class="flex flex-col gap-2.5">
+            <div class="flex gap-2 items-center">
+              <div class="text-black/90 text-lg font-normal font-['PingFang SC'] leading-[10.18px]">
+                <!-- IMOLA瓷砖 -->
+                {{ data?.materialsName }}
+              </div>
+              <div
+                class="w-[52px] h-[17px] px-2 bg-[#ef4343] rounded-[3px] justify-center items-center gap-2.5 inline-flex"
+              >
+                <div class="text-white text-[10px] font-normal font-['PingFang SC'] leading-normal">
+                  <!-- 自营品牌 -->
+                  {{
+                    materialBrandLevels.find(({ value }) => value === String(data.materialsType))
+                      ?.label
+                  }}
+                </div>
+              </div>
             </div>
             <div class="text-black/40 text-xs font-normal font-['PingFang SC'] leading-[10.18px]">
-              进口品牌 | 瓷砖
-            </div>
-            <div class="text-black/60 text-xs font-normal font-['PingFang SC'] leading-normal">
-              自营品牌
-            </div>
-            <div class="text-black/60 text-xs font-normal font-['PingFang SC'] leading-normal">
-              70%积分
+              {{ materialBrandTypes.find(({ value }) => value === String(data?.brandType))?.label }}
+              |
+              {{
+                materialOperationTypes.find(({ value }) => value === String(data?.manageType))
+                  ?.label
+              }}
             </div>
             <div>
               <span
@@ -62,13 +90,17 @@ onLoad(async (query: { id: number }) => {
               <span
                 class="text-black/40 text-xs font-normal font-['PingFang SC'] uppercase leading-[10.18px]"
               >
-                imola / chedit
+                <!-- imola / chedit -->
+                {{
+                  materialsManageBrands.find(({ value }) => value === String(data?.manageBrand))
+                    ?.label
+                }}
               </span>
             </div>
           </div>
         </div>
       </Card>
-      <Card>
+      <!-- <Card>
         <div class="my-6 text-black/90 text-lg font-normal font-['PingFang SC'] leading-[10.18px]">
           品牌介绍
         </div>
@@ -83,9 +115,9 @@ onLoad(async (query: { id: number }) => {
           <br />
           “蜜蜂”是具有代表意大利风格及产品质量并极富艺术创造力的典型品牌,其生产始终沿着两条轨道运行,一是及时掌握体现时代趋势和审美品位的设计理念,二是不断提高产品科技含量和制作工艺。
         </div>
-      </Card>
+      </Card> -->
       <SectionHeading title="产品展示"></SectionHeading>
-      <img class="w-[347px] h-[209px] rounded-2xl" src="https://via.placeholder.com/347x209" />
+      <!-- <img class="w-[347px] h-[209px] rounded-2xl" src="https://via.placeholder.com/347x209" /> -->
       <wd-button custom-class="w-full! rounded-lg!">下载所有素材包</wd-button>
     </div>
   </view>

+ 26 - 15
packages/app/src/pages/material/index.vue

@@ -20,6 +20,10 @@ const { data: materialOperationTypes, run: setMaterialOperationTypes } = useRequ
   () => getByDictType(DictType.memberMaterialsOperationType),
   { initialData: [] },
 )
+const { data: materialBrandTypes, run: setMaterialBrandTypes } = useRequest(
+  () => getByDictType(DictType.memberMaterialsBrandType),
+  { initialData: [] },
+)
 const dealerPanelState = ref(false)
 const currentDeraler = ref<MaterialsList>()
 const pieces = ref([
@@ -61,7 +65,7 @@ const handleCall = (phone: string) => {
 onMounted(async () => {
   await run()
   await setMaterialDealerData()
-  await setMaterialOperationTypes()
+  await Promise.all([setMaterialBrandTypes(), setMaterialOperationTypes()])
   // const reqs = data.value.map((it) =>
   //   getMaterials({ brandLevel: it.value }).then(({ data }) => data),
   // )
@@ -79,15 +83,6 @@ onMounted(async () => {
         height="100%"
         src="https://image.zhuchaohui.com/zhucaohui/f866f4f72392e8f4627d8f5d6628739ad7f0907d3703139e7cdbcb999b803dfe.jpg"
       />
-      <!-- <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"
-      >
-        <view class="mx-7">
-          <wd-button plain custom-class="bg-transparent! border-white! text-white!">
-            02:30
-          </wd-button>
-        </view>
-      </div> -->
     </view>
     <view class="bg-[#f6f6f6] relative bottom-4 rounded-t-2xl py-1">
       <div class="my-6 grid grid-cols-2 grid-gap-3.5 mx-3.5">
@@ -122,11 +117,22 @@ onMounted(async () => {
         </template>
       </div>
 
-      <template v-for="({ brandLevelName, materialsList }, i) in materialDealerData" :key="i">
-        <SectionHeading :title="brandLevelName" custom-class="mx-3.5"></SectionHeading>
-        <div class="my-6 flex px-3.5 gap-3">
+      <template
+        v-for="({ brandLevelName, pointsRate, materialsList }, i) in materialDealerData"
+        :key="i"
+      >
+        <SectionHeading
+          :title="brandLevelName"
+          :subtitle="`积分兑换比例 ${pointsRate}%`"
+          custom-class="mx-3.5"
+        ></SectionHeading>
+        <div class="my-6 px-3.5 overflow-x-auto whitespace-nowrap space-x-3.5">
           <template v-for="(it, index) in materialsList" :key="index">
-            <div :style="{ width: '50%' }" @click="toDetail(it.id)">
+            <div
+              class="inline-block"
+              :style="{ width: 'calc(50% - 14rpx)' }"
+              @click="toDetail(it.id)"
+            >
               <Card>
                 <div class="flex flex-col items-center">
                   <wd-img
@@ -143,7 +149,12 @@ onMounted(async () => {
                   <div
                     class="mb-4 text-black/60 text-sm font-normal font-['PingFang SC'] leading-[10.18px]"
                   >
-                    进口品牌 {{ it.brandType }} |
+                    <!-- 进口品牌 -->
+                    {{
+                      (it.brandType,
+                      materialBrandTypes.find(({ value }) => value === String(it.brandType))?.label)
+                    }}
+                    |
                     {{
                       materialOperationTypes.find(({ value }) => value === String(it.manageType))
                         ?.label