Browse Source

feat: 添加待办页面,更新路由和请求逻辑,优化首页导航样式

EvilDragon 3 months ago
parent
commit
80dfa36d2c

+ 82 - 0
packages/merchant/src/components/navbar-evo.vue

@@ -0,0 +1,82 @@
+<script lang="ts" setup>
+import { ConfigProviderThemeVars } from 'wot-design-uni'
+import {
+  type CSSProperties,
+  computed,
+  getCurrentInstance,
+  nextTick,
+  onMounted,
+  ref,
+  watch,
+} from 'vue'
+
+const props = withDefaults(
+  defineProps<{
+    transparent?: boolean
+    title?: string
+    dark?: boolean
+    placeholder?: boolean
+    isShowBack?: boolean
+  }>(),
+  { isShowBack: true },
+)
+const slots = defineSlots<{
+  prepend(): any
+}>()
+const aa = computed(() => (slots.prepend ? 'left' : 'capsule'))
+const pages = computed(() => getCurrentPages())
+const themeVars = computed<ConfigProviderThemeVars>(() => ({
+  navbarColor: props.dark ? 'white' : 'black',
+  // buttonIconSize: '100rpx',
+}))
+const handleToHome = () => {
+  uni.reLaunch({ url: '/pages/home/index' })
+}
+const handleBack = () => {
+  uni.navigateBack()
+}
+onMounted(() => {})
+</script>
+<template>
+  <div>
+    <wd-config-provider :themeVars="themeVars">
+      <wd-navbar
+        fixed
+        left-arrow
+        safe-area-inset-top
+        :bordered="false"
+        :custom-class="`${transparent ? 'bg-transparent!' : ''} `"
+        v-bind="{ title }"
+      >
+        <template v-slot:[aa]>
+          <div class="flex items-center gap-4.5 w-full h-full">
+            <div class="flex items-center justify-center overflow-hidden" v-if="isShowBack">
+              <wd-icon
+                v-if="pages.length === 1"
+                name="home"
+                size="50rpx"
+                :color="dark ? 'white' : 'blacak'"
+                @click="handleToHome"
+              ></wd-icon>
+              <wd-icon
+                v-else
+                name="arrow-left"
+                size="48rpx"
+                :color="dark ? 'white' : 'blacak'"
+                @click="handleBack"
+              ></wd-icon>
+            </div>
+            <slot name="prepend"></slot>
+          </div>
+        </template>
+      </wd-navbar>
+      <template v-if="props.placeholder">
+        <wd-navbar
+          safe-area-inset-top
+          :bordered="false"
+          :custom-class="`${transparent ? 'bg-transparent!' : ''} `"
+        ></wd-navbar>
+      </template>
+    </wd-config-provider>
+  </div>
+</template>

+ 106 - 0
packages/merchant/src/components/page-helper-evo.vue

@@ -0,0 +1,106 @@
+<script setup lang="ts" generic="T extends Object, R extends { list: T[] }, Q extends T">
+import { ResPageData } from '@designer-hub/app/src/core/libs/models'
+// import { NetImages } from '../core/libs/net-images'
+import { NetImages } from '@designer-hub/app/src/core/libs/net-images'
+import { getRect, addUnit } from 'wot-design-uni/components/common/util'
+
+const props = withDefaults(
+  defineProps<{
+    request: (query: any) => Promise<IResData<R>>
+    query?: Partial<Q> & { [key: symbol]: any }
+    automatic?: boolean
+  }>(),
+  { automatic: true, query: () => ({}) },
+)
+const slot = defineSlots<{
+  default(props: { data?: R['list']; items?: T[]; source?: R }): any
+  top: () => any
+}>()
+const { proxy } = getCurrentInstance() as any
+const pageNo = ref(1)
+const pageSize = ref(10)
+const nomore = ref(false)
+const topRef = ref()
+const height = ref(0)
+const windowInfo = ref<UniNamespace.GetWindowInfoResult>()
+const { data, run: setData } = useRequest(
+  () => props.request({ pageNo: pageNo.value, pageSize: pageSize.value, ...props.query }),
+  { immediate: false },
+)
+const items = ref<T[]>([])
+
+const setPlaceholderHeight = () => {
+  getRect('.bottom-app-bar', false, proxy).then((res) => {
+    height.value = res.height as number
+  })
+}
+onMounted(async () => {
+  nextTick(() => {
+    setPlaceholderHeight()
+  })
+  windowInfo.value = await uni.getWindowInfo()
+  if (props.automatic) {
+    console.log('Page Helper Automatic')
+    await setData()
+    items.value = data.value?.list || []
+  }
+})
+watch(
+  () => props.query,
+  async () => {
+    console.log('Page Helper Query Change')
+    pageNo.value = 1
+    pageSize.value = 10
+    await setData()
+    items.value = data.value?.list || []
+  },
+)
+onReachBottom(async () => {
+  console.log('Page Helper Reach Bottom')
+
+  if (data.value?.list?.length < pageSize.value) {
+    return (nomore.value = true)
+  }
+  pageNo.value++
+  await setData()
+  items.value = items.value.concat(data.value?.list || [])
+})
+defineExpose({
+  reload: async () => {
+    console.log('Page Helper Reload')
+    pageNo.value = 1
+    pageSize.value = 10
+    await setData()
+    items.value = data.value?.list || []
+  },
+  refresh: async () => {
+    console.log('Page Helper Refresh')
+    await setData()
+  },
+})
+</script>
+<template>
+  <div
+    class="flex-grow flex flex-col"
+    :style="{ paddingBottom: addUnit(windowInfo?.safeAreaInsets.bottom || 0) }"
+  >
+    <div class="relative" :style="{ height: addUnit(height) }">
+      <div
+        ref="topRef"
+        class="bottom-app-bar fixed absolute left-0 right-0 z-1"
+        :style="{ top: addUnit(windowInfo?.windowTop || 0) }"
+      >
+        <!-- {{ topRef.offsetHeight }} -->
+        <slot name="top"></slot>
+      </div>
+    </div>
+
+    <template v-if="!items?.length">
+      <wd-status-tip :image="NetImages.NotContent" tip="暂无内容"></wd-status-tip>
+    </template>
+    <slot :source="{ list: items }"></slot>
+    <template v-if="nomore">
+      <div class="my-4"><wd-divider>没有更多了</wd-divider></div>
+    </template>
+  </div>
+</template>

+ 33 - 0
packages/merchant/src/composables/router.ts

@@ -0,0 +1,33 @@
+export const back = () => {
+  uni.navigateBack()
+}
+export const useRouter = () => {
+  const push = async (url: string, switchTab = false) => {
+    const path = url.split('?')[0]
+    // const route = routes.find((it) => it.path === path)
+    // if (route && !route.meta.canNotLogin && !isLogined.value) {
+    //   if (route.meta.showToast) {
+    //     uni.showToast({ title: '暂无权限', icon: 'none' })
+    //   }
+    //   if (route.meta.toLogin) {
+    //     push('/pages/login/index')
+    //   }
+    //   return false
+    // }
+    // if (route && !route.meta.canNotDesigner && !isDesigner.value) {
+    //   return push('/pages/mine/authentication/index')
+    // }
+    if (switchTab) {
+      uni.switchTab({ url })
+    } else {
+      uni.navigateTo({ url })
+    }
+  }
+  const replace = async (path: string) => {
+    uni.redirectTo({ url: path })
+  }
+  const back = () => {
+    uni.navigateBack()
+  }
+  return { push, replace, back }
+}

+ 14 - 1
packages/merchant/src/core/libs/requests.ts

@@ -2,7 +2,7 @@ import { http, httpGet, httpPost } from '../../utils/http'
 import { Schedule } from '../models/schedule'
 import { Moment } from '../models/moment'
 import dayjs from 'dayjs'
-import { ResPageData } from '@designer-hub/app/src/core/libs/models'
+import { PointsOrder, ResPageData } from '@designer-hub/app/src/core/libs/models'
 
 export const getUserInfo = () =>
   httpGetMock<any>({
@@ -316,6 +316,19 @@ export const getOrders = () =>
  */
 export const getPointsOrder = (id) =>
   httpGet<Partial<PointsOrder>>('/app-api/member/points-order/get', { id })
+/**
+ * 渠道端-获取待办列表
+ */
+export const getTodos = (query: { brokerId: string; executionTime: string }) =>
+  httpGet<
+    {
+      id: number
+      content: string
+      status: number
+      executionTime: string
+      createTime: string
+    }[]
+  >('/app-api/member/todo/list', query)
 export const httpGetMock = <T>(data: T) =>
   new Promise<IResData<T>>((resolve) => resolve({ code: 1, msg: '', data } as IResData<T>))
 export interface Circle {

+ 10 - 1
packages/merchant/src/pages.json

@@ -88,7 +88,8 @@
       "layout": "tabbar",
       "style": {
         "navigationBarTitleText": "首页",
-        "navigationBarBackgroundColor": "#fff"
+        "navigationBarBackgroundColor": "#fff",
+        "navigationStyle": "custom"
       }
     },
     {
@@ -149,6 +150,14 @@
       }
     },
     {
+      "path": "pages/home/agent/todo/index",
+      "type": "page",
+      "style": {
+        "navigationBarTitleText": "待办",
+        "navigationBarBackgroundColor": "#f2f3f6"
+      }
+    },
+    {
       "path": "pages/home/tasks/detail/index",
       "type": "page",
       "style": {

+ 26 - 0
packages/merchant/src/pages/home/agent/todo/index.vue

@@ -0,0 +1,26 @@
+<route lang="json">
+{ "style": { "navigationBarTitleText": "待办", "navigationBarBackgroundColor": "#f2f3f6" } }
+</route>
+<script setup lang="ts">
+import PageHelperEvo from '@/components/page-helper-evo.vue'
+import { getTodos } from '../../../../core/libs/requests'
+
+const value = ref(Date.now())
+const { data, run: setData } = useRequest(() => getTodos({ brokerId: '', executionTime: '' }), {
+  initialData: [],
+})
+onMounted(async () => {
+  await setData()
+})
+</script>
+<template>
+  <div class="flex-grow">
+    <wd-calendar-view v-model="value" />
+    <wd-floating-panel>
+      <!-- <PageHelperEvo :request=""></PageHelperEvo> -->
+      <template v-for="(it, i) in data" :key="i">
+        <div>{{ it }}</div>
+      </template>
+    </wd-floating-panel>
+  </div>
+</template>

+ 26 - 2
packages/merchant/src/pages/home/index.vue

@@ -4,6 +4,7 @@
   style: {
     navigationBarTitleText: '首页',
     navigationBarBackgroundColor: '#fff',
+    navigationStyle: 'custom',
   },
 }
 </route>
@@ -18,8 +19,9 @@ import { merchantPageHeaderBg, scanIcon, bookIcon } from '@designer-hub/assets/s
 import { useUserStore } from '../../store'
 import { storeToRefs } from 'pinia'
 import { qrCodeString2Object, requestToast } from '@designer-hub/app/src/core/utils/common'
-import { useRouter } from '@designer-hub/app/src/core/utils/router'
 import { QrCodeBusinessType } from '../../core/libs/enums'
+import NavbarEvo from '@/components/navbar-evo.vue'
+import { useRouter } from '../../composables/router'
 
 defineOptions({
   name: 'Home',
@@ -152,7 +154,6 @@ onShareAppMessage(() => ({}))
           custom-class="vertical-bottom"
         ></wd-img>
       </div>
-      1
       <wd-navbar custom-class="bg-transparent!" safe-area-inset-top :bordered="false">
         <template #left>
           <div
@@ -165,6 +166,29 @@ onShareAppMessage(() => ({}))
       </wd-navbar>
       <div class="flex flex-col gap-8 p-4 relative box-border">
         <div>
+          <div class="text-white text-sm font-normal font-['PingFang_SC'] leading-relaxed my-2.5">
+            {{ dayjs().format('YYYY-MM-DD') }}
+          </div>
+          <Card>
+            <div>
+              <!-- <wd-steps :active="1" vertical>
+                <wd-step description="注册1个账号" />
+                <wd-step description="登录账号并绑定手机" />
+                <wd-step description="完善个人信息" />
+              </wd-steps> -->
+              <div
+                class="flex items-center justify-center b-t b-t-solid b-t-[#f6f6f6] pt-3.5"
+                @click="router.push('/pages/home/agent/todo/index')"
+              >
+                <div class="text-[#2357e9] text-xs font-normal font-['PingFang SC'] leading-none">
+                  全部待办
+                </div>
+                <wd-icon name="arrow-right" size="10" color="#2357e9" />
+              </div>
+            </div>
+          </Card>
+        </div>
+        <div>
           <SectionHeading
             title="渠道任务"
             path="/pages/home/tasks/index"

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

@@ -16,6 +16,7 @@ interface NavigateToOptions {
        "/pages/home/merchant/settlement" |
        "/pages/home/tasks/index" |
        "/pages/mine/merchant/merchant_settings" |
+       "/pages/home/agent/todo/index" |
        "/pages/home/tasks/detail/index" |
        "/pages/mine/merchant/orders/detail/index";
 }

+ 18 - 9
packages/merchant/src/utils/http.ts

@@ -3,13 +3,15 @@ import { CustomRequestOptions } from '../interceptors/request'
 import { useUserStore } from '../store'
 import dayjs from 'dayjs'
 
-// const userStore = useUserStore()
-// const Authorization = userStore.userInfo.token
-
-const header = {
+const userStore = useUserStore()
+// console.log(userStore.userInfo)
+const Authorization = userStore.userInfo?.token
+// console.log(Authorization)
+const header: { 'tenant-id': number; Authorization?: string } = {
   'tenant-id': 1,
-  // Authorization,
+  Authorization,
 }
+// Authorization && (header.Authorization = `Bearer ${Authorization}`)
 export const http = async <T>(options: CustomRequestOptions) => {
   const userStore = useUserStore()
   // console.log(dayjs(userStore.userInfo.expiresTime).format('YYYY-MM-DD HH:mm:ss'))
@@ -41,19 +43,26 @@ export const http = async <T>(options: CustomRequestOptions) => {
       // 响应成功
       success(res) {
         // console.log(res)
-
         // 状态码 2xx,参考 axios 的设计
         if (res.statusCode >= 200 && res.statusCode < 300) {
           // 2.1 提取核心数据 res.data
-          if ((res.data as IResData<T>).code === 401) {
+          if ((res.data as IResData<T>).code === 0) {
+            resolve(res.data as IResData<T>)
+          } else if ((res.data as IResData<T>).code === 401) {
             userStore.clearUserInfo()
+            // uni.navigateTo({ url: '/pages/login/index' })
+            reject(res)
           } else {
-            resolve(res.data as IResData<T>)
+            !options.hideErrorToast &&
+              uni.showToast({
+                icon: 'none',
+                title: (res.data as IResData<T>).msg || '请求错误',
+              })
+            reject(res.data)
           }
         } else if (res.statusCode === 401) {
           // 401错误  -> 清理用户信息,跳转到登录页
           userStore.clearUserInfo()
-          // uni.navigateTo({ url: '/pages/login/login' })
           reject(res)
         } else {
           // 其他错误 -> 根据后端错误信息轻提示