Browse Source

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

Jake 5 months ago
parent
commit
286e6da695

+ 2 - 0
packages/app/src/components/card.vue

@@ -5,11 +5,13 @@ defineProps({
     default: () => '',
   },
 })
+const emits = defineEmits(['click'])
 </script>
 <template>
   <view
     class="rounded-2xl bg-white shadow-[0_16rpx_20rpx_-10rpx_rgba(0,0,0,0.05)] p-3.5 overflow-hidden box-border"
     :class="customClass"
+    @click="emits('click')"
   >
     <slot></slot>
   </view>

+ 12 - 1
packages/app/src/core/libs/requests.ts

@@ -1,7 +1,8 @@
 import { http, httpGet, httpPost } from '../../utils/http'
 import { Schedule } from '../models/schedule'
-import { DictType, Moment } from '../models/moment'
+import { DictType, MaterialDealer, materialDealer, Moment } from '../models/moment'
 import dayjs from 'dayjs'
+import { getMaterialDealers } from './requests'
 
 export const getUserInfo = () =>
   httpGetMock<any>({
@@ -288,6 +289,16 @@ export const getSetIndexConfigs = (query = {}) =>
       createTime: string
     }[]
   }>('/app-api/basicsetting/set-index-config/page', query)
+
+/**
+ * 获取材料商列表
+ * @param query {{brandLevel: '1'|'2'}}
+ * @returns {Promise<*>}
+ */
+export const getMaterials = (query = {}) =>
+  httpGet<{
+    list: MaterialDealer[]
+  }>('/app-api/member/materials/page', query)
 export const refreshToken = (refreshToken: string) =>
   httpPost<any>('/app-api/member/auth/refresh-token', {}, { refreshToken })
 export const httpGetMock = <T>(data: T) =>

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

@@ -51,6 +51,31 @@ export interface Task {
   sort: number
   status: number
 }
+export interface MaterialDealer {
+  id: number
+  logoUrl: string
+  materialsName: string
+  materialsType: number
+  brandLevel: number
+  manageType: number
+  manageBrand: number
+  brandType: number
+  storeAddress: string
+  storeName: string
+  contactPerson: string
+  contactPhone: string
+  invoiceTitle: string
+  taxpayerNumber: string
+  invoiceAddr: string
+  bankDeposit: string
+  agreementFileUrl: string
+  virtualArrival: number
+  status: string
+  createTime: string
+  points: number
+  clockPoints: string
+  orderCount: number
+}
 export enum DictType {
   /**
    *  擅长空间类型
@@ -64,6 +89,14 @@ export enum DictType {
    * 圈子标签
    */
   circleTag = 'basic_set_label_type',
+  /**
+   * 材料商品牌等级
+   */
+  memberMaterialsBrandLevel = 'member_materials_brand_level',
+  /**
+   * 材料商运营类型
+   */
+  memberMaterialsOperationType = 'member_materials_operation_type',
 }
 export enum CircleType {
   moment = '1',

+ 8 - 0
packages/app/src/pages.json

@@ -222,6 +222,14 @@
       }
     },
     {
+      "path": "pages/material/mini-class/index",
+      "type": "page",
+      "style": {
+        "navigationStyle": "custom",
+        "navigationBarTitleText": "材料小课堂"
+      }
+    },
+    {
       "path": "pages/material/recommend/index",
       "type": "page",
       "style": {

+ 1 - 1
packages/app/src/pages/home/classmates/index.vue

@@ -4,7 +4,7 @@ style:
   navigationBarBackgroundColor: '#fff'
 </route>
 <script setup lang="ts">
-import { getClassmates } from '@/core/libs/requests'
+import { getClassmates } from '../../../core/libs/requests'
 import ClassItem from '../components/class-item.vue'
 
 const { data, run } = useRequest(getClassmates)

+ 98 - 71
packages/app/src/pages/material/index.vue

@@ -5,38 +5,49 @@
 <script setup lang="ts">
 import Card from '@/components/card.vue'
 import SectionHeading from '@/components/section-heading.vue'
-import { abc, calculator, treaty } from '@/core/libs/pngs'
-import { getMaterialDealers } from '@/core/libs/requests'
-import { materialDealers, close, phone } from '@/core/libs/svgs'
+import { abc, calculator } from '../../core/libs/pngs'
+import { getByDictType, getMaterials } from '../../core/libs/requests'
+import { materialDealers, close, phone } from '../../core/libs/svgs'
+import { DictType, MaterialDealer } from '../../core/models/moment'
 
-const { data, run } = useRequest(getMaterialDealers)
+const { data, run } = useRequest(() => getByDictType(DictType.memberMaterialsBrandLevel))
+const { data: materialOperationTypes, run: setMaterialOperationTypes } = useRequest(() =>
+  getByDictType(DictType.memberMaterialsOperationType),
+)
+const { data: selfOperateds, run: setSelfOperateds } = useRequest(
+  () => getMaterials({ brandLevel: 1 }),
+  { initialData: { list: [] } },
+)
+const { data: jointVenture, run: setJointVenture } = useRequest(
+  () => getMaterials({ brandLevel: 2 }),
+  { initialData: { list: [] } },
+)
 const dealerPanelState = ref(false)
 const pieces = ref([
   {
     title: '材料小课堂',
     desc: '全方位了解',
     icon: abc,
-    class: 'col-start-1 row-start-1',
-    // iconSize: 102,
+    gridItemClass: 'col-start-1 row-start-1',
+    path: '/pages/material/mini-class/index',
   },
   {
     title: '积分计算机',
     desc: '积分小帮手',
     icon: calculator,
-    class: 'col-start-2 row-start-1',
+    gridItemClass: 'col-start-2 row-start-1',
     path: '/pages/material/calculator/index',
-    // iconSize: 68,
   },
   {
     title: '推荐材料商',
     desc: '我们将优先洽谈大家推荐的材料商',
     icon: materialDealers,
-    class: 'col-start-1 row-start-2 col-end-3',
-    // iconSize: 44,
+    gridItemClass: 'col-start-1 col-end-3 row-start-2',
     isMore: true,
     path: '/pages/material/recommend/index',
   },
 ])
+const materialsByBrandLevel = ref<{ list: MaterialDealer[] }[]>([])
 const handleMenuItemClick = ({ path }: any) => {
   uni.navigateTo({ url: path })
 }
@@ -45,8 +56,15 @@ const toDetail = () => {
     url: '/pages/material/detail/index',
   })
 }
-onMounted(() => {
-  run()
+onMounted(async () => {
+  await run()
+  console.log(data.value)
+  await setMaterialOperationTypes()
+  const reqs = data.value.map((it) =>
+    getMaterials({ brandLevel: it.value }).then(({ data }) => data),
+  )
+  materialsByBrandLevel.value = await Promise.all(reqs)
+  console.log(materialsByBrandLevel.value)
 })
 </script>
 <template>
@@ -63,71 +81,80 @@ onMounted(() => {
         </view>
       </div> -->
     </view>
-
     <view class="bg-[#f6f6f6] relative bottom-4 rounded-t-2xl py-1">
-      <div class="my-6 grid grid-gap-2.5 mx-3.5">
+      <div class="my-6 grid grid-cols-2 grid-gap-2.5 mx-3.5">
         <template v-for="it of pieces" :key="it.title">
-          <card
-            :custom-class="[it.class, 'flex justify-between items-center'].join(' ')"
-            @click="handleMenuItemClick(it)"
-          >
-            <view class="flex items-end justify-end">
-              <wd-img :src="it.icon" :width="42" :height="42"></wd-img>
-            </view>
-            <div class="flex-1 flex flex-col justify-around h-full">
-              <div
-                class="text-black/80 text-base font-normal font-['PingFang SC'] leading-[10.18px]"
-              >
-                {{ it.title }}
+          <div :class="it.gridItemClass" @click="handleMenuItemClick(it)">
+            <card custom-class="flex justify-between items-center">
+              <view class="flex items-end justify-end">
+                <wd-img :src="it.icon" :width="42" :height="42"></wd-img>
+              </view>
+              <div class="flex-1 flex flex-col justify-around h-full">
+                <div
+                  class="text-black/80 text-base font-normal font-['PingFang SC'] leading-[10.18px]"
+                >
+                  {{ it.title }}
+                </div>
+                <div
+                  class="mt-1 text-black/40 text-xs font-normal font-['PingFang SC'] leading-normal"
+                >
+                  {{ it.desc }}
+                </div>
               </div>
-              <div
-                class="mt-1 text-black/40 text-xs font-normal font-['PingFang SC'] leading-normal"
-              >
-                {{ it.desc }}
+              <div v-if="it.isMore" class="mr--4">
+                <wd-button
+                  custom-class="text-black/40!"
+                  type="icon"
+                  icon="arrow-right"
+                  icon-color=""
+                ></wd-button>
               </div>
-            </div>
-            <div v-if="it.isMore" class="mr--4">
-              <wd-button
-                custom-class="text-black/40!"
-                type="icon"
-                icon="arrow-right"
-                icon-color=""
-              ></wd-button>
-            </div>
-          </card>
+            </card>
+          </div>
         </template>
       </div>
-      <SectionHeading title="自营品牌" custom-class="mx-3.5"></SectionHeading>
-      <div class="my-6 flex px-1.75">
-        <template v-for="(it, i) in data" :key="i">
-          <Card custom-class="mx-1.75" :style="{ width: 'calc(50vw - 96rpx)' }" @click="toDetail">
-            <div class="flex flex-col items-center">
-              <wd-img
-                width="78"
-                height="78"
-                custom-class="border border-[#f2f2f2] rounded-full overflow-hidden"
-                :src="it.icon"
-              ></wd-img>
-              <div
-                class="my-4 text-black/90 text-base font-normal font-['PingFang SC'] leading-[10.18px]"
-              >
-                IMOLA瓷砖
-              </div>
-              <div
-                class="mb-4 text-black/60 text-sm font-normal font-['PingFang SC'] leading-[10.18px]"
-              >
-                进口品牌 | 瓷砖
-              </div>
-              <wd-button size="small" custom-class="my-4" @click="dealerPanelState = true">
-                联系商家
-              </wd-button>
-              <div class="text-black/30 text-xs font-normal font-['PingFang SC'] leading-[10.18px]">
-                {{ it.views }}次到店打卡
-              </div>
+
+      <template v-for="({ label }, i) in data" :key="i">
+        <SectionHeading :title="label" custom-class="mx-3.5"></SectionHeading>
+        <div class="my-6 flex px-3.5 gap-3">
+          <template v-for="(it, index) in materialsByBrandLevel[i]?.list" :key="index">
+            <div :style="{ width: '50%' }">
+              <Card @click="toDetail">
+                <div class="flex flex-col items-center">
+                  <wd-img
+                    width="78"
+                    height="78"
+                    custom-class="border border-[#f2f2f2] rounded-full overflow-hidden"
+                    :src="it.logoUrl"
+                  ></wd-img>
+                  <div
+                    class="my-4 text-black/90 text-base font-normal font-['PingFang SC'] leading-[10.18px]"
+                  >
+                    {{ it.materialsName }}
+                  </div>
+                  <div
+                    class="mb-4 text-black/60 text-sm font-normal font-['PingFang SC'] leading-[10.18px]"
+                  >
+                    进口品牌 {{ it.brandType }} |
+                    {{
+                      materialOperationTypes.find(({ value }) => value === String(it.manageType))
+                        ?.label
+                    }}
+                  </div>
+                  <wd-button size="small" custom-class="my-4" @click="dealerPanelState = true">
+                    联系商家
+                  </wd-button>
+                  <div
+                    class="text-black/30 text-xs font-normal font-['PingFang SC'] leading-[10.18px]"
+                  >
+                    {{ it.virtualArrival || 0 }}次到店打卡
+                  </div>
+                </div>
+              </Card>
             </div>
-          </Card>
-        </template>
-      </div>
+          </template>
+        </div>
+      </template>
     </view>
 
     <!-- <wd-action-sheet v-model="dealerPanelState">
@@ -137,7 +164,7 @@ onMounted(() => {
       <view style="padding: 15px 15px 150px 15px">内容</view>
     </wd-action-sheet> -->
     <wd-overlay :show="dealerPanelState" @click="dealerPanelState = false">
-      <view class="wrapper bg-amber/50 flex flex-col justify-end h-full">
+      <view class="wrapper flex flex-col justify-end h-full">
         <div class="w-full flex justify-end mb-4">
           <div class="mr-3.5">
             <wd-button type="text" custom-class="w-8! h-8! p-0!" size="small">

+ 28 - 0
packages/app/src/pages/material/mini-class/index.vue

@@ -0,0 +1,28 @@
+<route lang="yaml">
+style:
+  navigationStyle: custom
+  navigationBarTitleText: 材料小课堂
+</route>
+<script setup lang="ts">
+const imgs = ref([
+  'https://image.zhuchaohui.com/zhucaohui/ce3bacd03a3c8b4ffe65d9cf81111324475413b5d22e26749c868104cc40dafd.jpg',
+])
+const handleClickLeft = () => {
+  uni.navigateBack()
+}
+</script>
+<template>
+  <div>
+    <wd-navbar
+      left-arrow
+      fixed
+      safe-area-inset-top
+      custom-class="bg-transparent"
+      title="材料小课堂"
+      @click-left="handleClickLeft"
+    ></wd-navbar>
+    <template v-for="(it, i) in imgs" :key="i">
+      <wd-img width="100%" :src="it" mode="widthFix"></wd-img>
+    </template>
+  </div>
+</template>

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

@@ -22,7 +22,6 @@ import { useUserStore } from '../../store'
 import { storeToRefs } from 'pinia'
 import { isEmpty } from 'radash'
 import TasksCard from './components/tasks-card.vue'
-import Card from '@/components/card.vue'
 
 const userStore = useUserStore()
 const { isLogined, userInfo } = storeToRefs(userStore)

+ 1 - 0
packages/app/src/types/uni-pages.d.ts

@@ -23,6 +23,7 @@ interface NavigateToOptions {
        "/pages/home/study-tour/list" |
        "/pages/material/calculator/index" |
        "/pages/material/detail/index" |
+       "/pages/material/mini-class/index" |
        "/pages/material/recommend/index" |
        "/pages/mine/authentication/index" |
        "/pages/mine/homepage/index" |