Przeglądaj źródła

Merge branch 'base' into tabbar

菲鸽 1 rok temu
rodzic
commit
556f9052d1

+ 7 - 6
env/.env

@@ -1,14 +1,15 @@
 VITE_APP_TITLE = 'unibest'
 VITE_APP_PORT = 9000
 
-# h5部署网站的base,配置到 manifest.config.ts 里的 h5.router.base
-VITE_APP_PUBLIC_BASE=/
-
 VITE_UNI_APPID = 'H57F2ACE4'
 VITE_WX_APPID = 'wxa2abb91f64032a2b'
 
-# 非h5端只能使用完整的baseurl,否则无法请求,本地proxy只支持h5端
-# VITE_SERVER_BASEURL = '/api'
-VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run'
+# h5部署网站的base,配置到 manifest.config.ts 里的 h5.router.base
+VITE_APP_PUBLIC_BASE=/
 
+VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run'
 VITE_UPLOAD_BASEURL = 'https://ukw0y1.laf.run/upload'
+
+# h5是否需要配置代理
+VITE_APP_PROXY=true
+VITE_APP_PROXY_PREFIX = '/api'

+ 3 - 3
manifest.config.ts

@@ -29,12 +29,12 @@ export default defineManifestConfig({
   },
   /* 5+App特有相关 */
   'app-plus': {
-    compatible: {
-      ignoreVersion: true,
-    },
     usingComponents: true,
     nvueStyleCompiler: 'uni-app',
     compilerVersion: 3,
+    compatible: {
+      ignoreVersion: true,
+    },
     splashscreen: {
       alwaysShowBeforeRender: true,
       waiting: true,

+ 3 - 0
package.json

@@ -109,7 +109,10 @@
     "@dcloudio/uni-cli-shared": "3.0.0-4010420240430001",
     "@dcloudio/uni-stacktracey": "3.0.0-4010420240430001",
     "@dcloudio/vite-plugin-uni": "3.0.0-4010420240430001",
+    "@esbuild/darwin-arm64": "0.20.2",
+    "@esbuild/darwin-x64": "0.20.2",
     "@iconify-json/carbon": "^1.1.27",
+    "@rollup/rollup-darwin-x64": "^4.17.2",
     "@types/node": "^20.11.5",
     "@types/wechat-miniprogram": "^3.4.7",
     "@typescript-eslint/eslint-plugin": "^6.15.0",

+ 4 - 0
src/env.d.ts

@@ -15,6 +15,10 @@ interface ImportMetaEnv {
   readonly VITE_SERVER_PORT: string
   /** 后台接口地址 */
   readonly VITE_SERVER_BASEURL: string
+  /** H5是否需要代理 */
+  readonly VITE_APP_PROXY: 'true' | 'false'
+  /** H5是否需要代理,需要的话有个前缀 */
+  readonly VITE_APP_PROXY_PREFIX: string // 一般是/api
   /** 上传图片地址 */
   readonly VITE_UPLOAD_BASEURL: string
   /** 是否清除console */

+ 25 - 38
src/hooks/useUpload.ts

@@ -1,13 +1,15 @@
+// TODO: 别忘加更改环境变量的 VITE_UPLOAD_BASEURL 地址。
+const VITE_UPLOAD_BASEURL = import.meta.env.VITE_UPLOAD_BASEURL
+
 /**
  * useUpload 是一个定制化的请求钩子,用于处理上传图片。
  * @param formData 额外传递给后台的数据,如{name: '菲鸽'}。
  * @returns 返回一个对象{loading, error, data, run},包含请求的加载状态、错误信息、响应数据和手动触发请求的函数。
  */
-export default function useUpload<T>(formData: Record<string, any> = {}) {
+export default function useUpload<T = string>(formData: Record<string, any> = {}) {
   const loading = ref(false)
   const error = ref(false)
   const data = ref<T>()
-  const url = import.meta.env.VITE_UPLOAD_BASEURL
   const run = () => {
     // #ifdef MP-WEIXIN
     // 微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
@@ -16,26 +18,9 @@ export default function useUpload<T>(formData: Record<string, any> = {}) {
       count: 1,
       mediaType: ['image'],
       success: (res) => {
-        console.log(res)
         loading.value = true
         const tempFilePath = res.tempFiles[0].tempFilePath
-        uni.uploadFile({
-          url,
-          filePath: tempFilePath,
-          name: 'file',
-          formData,
-          success: (uploadFileRes) => {
-            console.log(uploadFileRes.data)
-            data.value = uploadFileRes.data as T
-          },
-          fail: (err) => {
-            console.log('uni.uploadFile err->', err)
-            error.value = true
-          },
-          complete: () => {
-            loading.value = false
-          },
-        })
+        uploadFile<T>({ tempFilePath, formData, data, error, loading })
       },
       fail: (err) => {
         console.log('uni.chooseMedia err->', err)
@@ -47,26 +32,9 @@ export default function useUpload<T>(formData: Record<string, any> = {}) {
     uni.chooseImage({
       count: 1,
       success: (res) => {
-        console.log(res)
         loading.value = true
         const tempFilePath = res.tempFilePaths[0]
-        uni.uploadFile({
-          url,
-          filePath: tempFilePath,
-          name: 'file',
-          formData,
-          success: (uploadFileRes) => {
-            console.log(uploadFileRes.data)
-            data.value = uploadFileRes.data as T
-          },
-          fail: (err) => {
-            console.log('uni.uploadFile err->', err)
-            error.value = true
-          },
-          complete: () => {
-            loading.value = false
-          },
-        })
+        uploadFile<T>({ tempFilePath, formData, data, error, loading })
       },
       fail: (err) => {
         console.log('uni.chooseImage err->', err)
@@ -78,3 +46,22 @@ export default function useUpload<T>(formData: Record<string, any> = {}) {
 
   return { loading, error, data, run }
 }
+
+function uploadFile<T>({ tempFilePath, formData, data, error, loading }) {
+  uni.uploadFile({
+    url: VITE_UPLOAD_BASEURL,
+    filePath: tempFilePath,
+    name: 'file',
+    formData,
+    success: (uploadFileRes) => {
+      data.value = uploadFileRes.data as T
+    },
+    fail: (err) => {
+      console.log('uni.uploadFile err->', err)
+      error.value = true
+    },
+    complete: () => {
+      loading.value = false
+    },
+  })
+}

+ 0 - 82
src/hooks/useUpload2.ts

@@ -1,82 +0,0 @@
-/**
- * useUpload 是一个定制化的请求钩子,用于处理上传图片。
- * @param url 上传图片的后台地址,如 https://ukw0y1.laf.run/upload。
- * 如果上传地址是固定的,那就可以配置到 .env 里面,函数里面不需要再传了。
- * @param formData 额外传递给后台的数据,如{name: '菲鸽'}。
- * @returns 返回一个对象{loading, error, data, run},包含请求的加载状态、错误信息、响应数据和手动触发请求的函数。
- */
-export default function useUpload<T>(url: string, formData: Record<string, any> = {}) {
-  const loading = ref(false)
-  const error = ref(false)
-  const data = ref<T>()
-
-  const run = () => {
-    // #ifdef MP-WEIXIN
-    // 微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
-    // 微信小程序在2023年10月17日之后,使用本API需要配置隐私协议
-    uni.chooseMedia({
-      count: 1,
-      mediaType: ['image'],
-      success: (res) => {
-        console.log(res)
-        loading.value = true
-        const tempFilePath = res.tempFiles[0].tempFilePath
-        uni.uploadFile({
-          url,
-          filePath: tempFilePath,
-          name: 'file',
-          formData,
-          success: (uploadFileRes) => {
-            console.log(uploadFileRes.data)
-            data.value = uploadFileRes.data as T
-          },
-          fail: (err) => {
-            console.log('uni.uploadFile err->', err)
-            error.value = true
-          },
-          complete: () => {
-            loading.value = false
-          },
-        })
-      },
-      fail: (err) => {
-        console.log('uni.chooseMedia err->', err)
-        error.value = true
-      },
-    })
-    // #endif
-    // #ifndef MP-WEIXIN
-    uni.chooseImage({
-      count: 1,
-      success: (res) => {
-        console.log(res)
-        loading.value = true
-        const tempFilePath = res.tempFilePaths[0]
-        uni.uploadFile({
-          url,
-          filePath: tempFilePath,
-          name: 'file',
-          formData,
-          success: (uploadFileRes) => {
-            console.log(uploadFileRes.data)
-            data.value = uploadFileRes.data as T
-          },
-          fail: (err) => {
-            console.log('uni.uploadFile err->', err)
-            error.value = true
-          },
-          complete: () => {
-            loading.value = false
-          },
-        })
-      },
-      fail: (err) => {
-        console.log('uni.chooseImage err->', err)
-        error.value = true
-      },
-    })
-    // #endif
-  }
-
-  return { loading, error, data, run }
-}

+ 11 - 0
src/interceptors/request.ts

@@ -27,7 +27,18 @@ const httpInterceptor = {
     }
     // 非 http 开头需拼接地址
     if (!options.url.startsWith('http')) {
+      // #ifdef H5
+      console.log(__VITE_APP_PROXY__)
+      if (JSON.parse(__VITE_APP_PROXY__)) {
+        // 啥都不需要做
+      } else {
+        options.url = baseUrl + options.url
+      }
+      // #endif
+      // 非H5正常拼接
+      // #ifndef H5
       options.url = baseUrl + options.url
+      // #endif
       // TIPS: 如果需要对接多个后端服务,也可以在这里处理,拼接成所需要的地址
     }
     // 1. 请求超时

+ 3 - 28
src/pages.json

@@ -55,42 +55,17 @@
       }
     },
     {
-      "path": "pages/index/about",
+      "path": "pages/about/about",
       "type": "page",
       "style": {
         "navigationBarTitleText": "关于"
       }
     },
     {
-      "path": "pages/index/request",
-      "type": "page",
-      "layout": "demo",
-      "style": {
-        "navigationBarTitleText": "请求"
-      }
-    },
-    {
-      "path": "pages/index/request2",
-      "type": "page",
-      "layout": "demo",
-      "style": {
-        "navigationBarTitleText": "请求-状态一体化"
-      }
-    },
-    {
-      "path": "pages/index/upload",
-      "type": "page",
-      "layout": "default",
-      "style": {
-        "navigationBarTitleText": "上传"
-      }
-    },
-    {
-      "path": "pages/index/upload2",
+      "path": "pages/index/about",
       "type": "page",
-      "layout": "default",
       "style": {
-        "navigationBarTitleText": "上传-状态一体化"
+        "navigationBarTitleText": "关于"
       }
     },
     {

+ 36 - 0
src/pages/about/about.vue

@@ -0,0 +1,36 @@
+<route lang="json5">
+{
+  style: {
+    navigationBarTitleText: '关于',
+  },
+}
+</route>
+
+<template>
+  <view
+    class="bg-white overflow-hidden pt-2 px-4"
+    :style="{ marginTop: safeAreaInsets?.top + 'px' }"
+  >
+    <view class="text-center text-3xl mt-8">
+      鸽友们好,我是
+      <text class="text-red-500">菲鸽</text>
+    </view>
+    <RequestComp />
+    <UploadComp />
+  </view>
+</template>
+
+<script lang="ts" setup>
+import RequestComp from './components/request.vue'
+import UploadComp from './components/upload.vue'
+
+// 获取屏幕边界到安全区域距离
+const { safeAreaInsets } = uni.getSystemInfoSync()
+</script>
+
+<style lang="scss" scoped>
+.test-css {
+  // mt-4=>1rem=>16px;
+  margin-top: 16px;
+}
+</style>

+ 43 - 0
src/pages/about/components/request.vue

@@ -0,0 +1,43 @@
+<route lang="json5">
+{
+  layout: 'demo',
+  style: {
+    navigationBarTitleText: '请求',
+  },
+}
+</route>
+
+<template>
+  <view class="p-6 text-center">
+    <view class="my-2">使用的是 laf 云后台</view>
+    <view class="text-green-400">我的推荐码,可以获得佣金</view>
+
+    <!-- #ifdef H5 -->
+    <view class="my-2">
+      <a class="my-2" :href="recommendUrl" target="_blank">{{ recommendUrl }}</a>
+    </view>
+    <!-- #endif -->
+
+    <!-- #ifndef H5 -->
+    <view class="my-2 text-left text-sm">{{ recommendUrl }}</view>
+    <!-- #endif -->
+
+    <!-- http://localhost:9000/#/pages/index/request -->
+    <button @click="run" class="my-6">发送请求</button>
+    <view class="text-xl">请求数据如下</view>
+    <view class="text-green h-6">{{ JSON.stringify(data) }}</view>
+    <button type="warn" @click="reset" class="my-6">清除数据</button>
+  </view>
+</template>
+
+<script lang="ts" setup>
+import { getFooAPI, postFooAPI, IFooItem } from '@/service/index/foo'
+
+const recommendUrl = ref('http://laf.run/signup?code=ohaOgIX')
+
+// 适合少部分全局性的接口————多个页面都需要的请求接口,额外编写一个 Service 层
+const { loading, error, data, run } = useRequest<IFooItem>(() => getFooAPI('菲鸽'))
+const reset = () => {
+  data.value = undefined
+}
+</script>

+ 3 - 4
src/pages/index/upload2.vue

@@ -12,18 +12,17 @@
     <wd-button @click="run">选择图片并上传</wd-button>
     <view v-if="loading" class="text-blue h-10">上传...</view>
     <template v-else>
-      <view class="m-2">上传后返回的图片地址:</view>
+      <view class="m-2">上传后返回的接口数据:</view>
       <view class="m-2">{{ data }}</view>
       <view class="h-80 w-full">
-        <image v-if="data" :src="data" mode="scaleToFill" />
+        <image v-if="data" :src="data || data" mode="scaleToFill" />
       </view>
     </template>
   </view>
 </template>
 
 <script lang="ts" setup>
-// const { loading, data, run } = useUpload2<string>('https://ukw0y1.laf.run/upload', { user: '菲鸽' })
-const { loading, data, run } = useUpload<string>({ user: '菲鸽' })
+const { loading, data, run } = useUpload({ user: '菲鸽' })
 </script>
 
 <style lang="scss" scoped>

+ 0 - 67
src/pages/index/request.vue

@@ -1,67 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: {
-    navigationBarTitleText: '请求',
-  },
-}
-</route>
-
-<template>
-  <view class="p-6 text-center">
-    <view class="my-2">使用的是 laf 云后台</view>
-    <view class="text-green-400">我的推荐码,可以获得佣金</view>
-
-    <!-- #ifdef H5 -->
-    <view class="my-2">
-      <a class="my-2" :href="recommendUrl" target="_blank">{{ recommendUrl }}</a>
-    </view>
-    <!-- #endif -->
-
-    <!-- #ifndef H5 -->
-    <view class="my-2 text-left text-sm">{{ recommendUrl }}</view>
-    <!-- #endif -->
-
-    <!-- http://localhost:9000/#/pages/index/request -->
-    <button @click="getFoo" class="my-6">1.测试 GET 请求</button>
-    <view class="text-xl">请求数据如下</view>
-    <view class="text-green h-10">{{ JSON.stringify(data) }}</view>
-    <view class="text-xl">完整数据</view>
-    <view class="text-green h-16">{{ JSON.stringify(originalData) }}</view>
-    <button @click="postFoo" class="my-6">2.测试 POST 请求</button>
-    <view class="text-xl">请求数据如下</view>
-    <view class="text-green h-10">{{ JSON.stringify(data2) }}</view>
-    <button class="my-6" type="warn" @click="reset">3.一键清空数据</button>
-  </view>
-</template>
-
-<script lang="ts" setup>
-import { getFooAPI, postFooAPI, IFooItem } from '@/service/index/foo'
-
-const recommendUrl = ref('http://laf.run/signup?code=ohaOgIX')
-
-onLoad(() => {
-  getFoo()
-  postFoo()
-})
-
-const originalData = ref<IResData<IFooItem>>()
-const data = ref<IFooItem>()
-const getFoo = async () => {
-  const res = await getFooAPI('菲鸽')
-  data.value = res.data
-  originalData.value = res
-}
-
-const data2 = ref<IFooItem>()
-const postFoo = async () => {
-  const res = await postFooAPI('菲鸽2')
-  data2.value = res.data
-}
-
-const reset = () => {
-  data.value = undefined
-  data2.value = undefined
-  originalData.value = undefined
-}
-</script>

+ 0 - 35
src/pages/index/request2.vue

@@ -1,35 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: {
-    navigationBarTitleText: '请求-状态一体化',
-  },
-}
-</route>
-
-<template>
-  <view class="p-6 text-center">
-    <!-- http://localhost:9000/#/pages/index/request -->
-    <button @click="getFoo" class="my-6">测试 GET 请求</button>
-    <view class="text-xl">请求数据如下</view>
-    <view v-if="loading" class="text-blue h-10">加载中...</view>
-    <view v-if="error" class="text-red h-10">请求错误</view>
-    <view v-else class="text-green h-10">{{ JSON.stringify(data) }}</view>
-    <button class="my-6" type="warn" @click="reset">一键清空数据</button>
-  </view>
-</template>
-
-<script lang="ts" setup>
-import { getFooAPI2, IFooItem } from '@/service/index/foo'
-import { httpGet } from '@/utils/http'
-
-// 适合少部分全局性的接口————多个页面都需要的请求接口,额外编写一个 Service 层
-const { loading, error, data, run } = useRequest<IFooItem>(() => getFooAPI2('菲鸽'))
-// 再次简化,一行代码搞定,方便一次性的请求,适用大部分请求
-// const { loading, error, data, run } = useRequest<IFooItem>(() => httpGet('/foo', { name: '菲鸽' }))
-
-const getFoo = () => run()
-const reset = () => {
-  data.value = undefined
-}
-</script>

+ 0 - 75
src/pages/index/upload.vue

@@ -1,75 +0,0 @@
-<route lang="json5" type="page">
-{
-  layout: 'default',
-  style: {
-    navigationBarTitleText: '上传',
-  },
-}
-</route>
-
-<template>
-  <view class="p-4 text-center">
-    <wd-button @click="chooseImage">选择图片并上传</wd-button>
-    <view class="m-2">上传后返回的图片地址:</view>
-    <view class="m-2">{{ imgStr }}</view>
-    <view class="h-80 w-full">
-      <image v-if="imgStr" :src="imgStr" mode="scaleToFill" />
-    </view>
-  </view>
-</template>
-
-<script lang="ts" setup>
-const imgStr = ref('')
-
-const chooseImage = () => {
-  // #ifdef MP-WEIXIN
-  // 微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
-  // 微信小程序在2023年10月17日之后,使用本API需要配置隐私协议
-  uni.chooseMedia({
-    count: 1,
-    mediaType: ['image'],
-    success: (res) => {
-      console.log(res)
-      const tempFilePath = res.tempFiles[0].tempFilePath
-      uni.uploadFile({
-        url: 'https://ukw0y1.laf.run/upload',
-        filePath: tempFilePath,
-        name: 'file',
-        formData: {
-          user: '菲鸽',
-        },
-        success: (uploadFileRes) => {
-          console.log(uploadFileRes.data)
-          imgStr.value = uploadFileRes.data
-        },
-      })
-    },
-  })
-  // #endif
-  // #ifndef MP-WEIXIN
-  uni.chooseImage({
-    count: 1,
-    success: (res) => {
-      console.log(res)
-      const tempFilePath = res.tempFilePaths[0]
-      uni.uploadFile({
-        url: 'https://ukw0y1.laf.run/upload',
-        filePath: tempFilePath,
-        name: 'file',
-        formData: {
-          user: '菲鸽',
-        },
-        success: (uploadFileRes) => {
-          console.log(uploadFileRes.data)
-          imgStr.value = uploadFileRes.data
-        },
-      })
-    },
-  })
-  // #endif
-}
-</script>
-
-<style lang="scss" scoped>
-//
-</style>

+ 0 - 18
src/service/index/foo.ts

@@ -6,28 +6,10 @@ export interface IFooItem {
 
 /** GET 请求 */
 export const getFooAPI = (name: string) => {
-  return http<IFooItem>({
-    url: `/foo`,
-    method: 'GET',
-    query: { name },
-  })
-}
-
-/** GET 请求 - 再次简化,看大家是否喜欢这种简化 */
-export const getFooAPI2 = (name: string) => {
   return http.get<IFooItem>('/foo', { name })
 }
 
 /** POST 请求 */
 export const postFooAPI = (name: string) => {
-  return http<IFooItem>({
-    url: `/foo`,
-    method: 'POST',
-    query: { name }, // post 请求也支持 query
-    data: { name },
-  })
-}
-/** POST 请求 - 再次简化,看大家是否喜欢这种简化 */
-export const postFooAPI2 = (name: string) => {
   return http.post<IFooItem>('/foo', { name }, { name })
 }

+ 0 - 2
src/types/auto-import.d.ts

@@ -170,7 +170,6 @@ declare module 'vue' {
     readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
     readonly useRequest: UnwrapRef<typeof import('../hooks/useRequest')['default']>
     readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
-    readonly useUpload2: UnwrapRef<typeof import('../hooks/useUpload2')['default']>
     readonly useUpload: UnwrapRef<typeof import('../hooks/useUpload')['default']>
     readonly watch: UnwrapRef<typeof import('vue')['watch']>
     readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
@@ -254,7 +253,6 @@ declare module '@vue/runtime-core' {
     readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
     readonly useRequest: UnwrapRef<typeof import('../hooks/useRequest')['default']>
     readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
-    readonly useUpload2: UnwrapRef<typeof import('../hooks/useUpload2')['default']>
     readonly useUpload: UnwrapRef<typeof import('../hooks/useUpload')['default']>
     readonly watch: UnwrapRef<typeof import('vue')['watch']>
     readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>

+ 2 - 0
src/types/global.d.ts

@@ -12,3 +12,5 @@ declare const __UNI_PLATFORM__:
   | 'quickapp-webview'
   | 'quickapp-webview-huawei'
   | 'quickapp-webview-union'
+
+declare const __VITE_APP_PROXY__: 'true' | 'false'

+ 1 - 4
src/types/uni-pages.d.ts

@@ -5,11 +5,8 @@
 
 interface NavigateToOptions {
   url: "/pages/index/index" |
+       "/pages/about/about" |
        "/pages/index/about" |
-       "/pages/index/request" |
-       "/pages/index/request2" |
-       "/pages/index/upload" |
-       "/pages/index/upload2" |
        "/pages/my/index";
 }
 interface RedirectToOptions extends NavigateToOptions {}

+ 18 - 8
vite.config.ts

@@ -35,7 +35,14 @@ export default ({ command, mode }) => {
   console.log('UNI_PLATFORM -> ', UNI_PLATFORM) // 得到 mp-weixin, h5, app 等
 
   const env = loadEnv(mode, path.resolve(process.cwd(), 'env'))
-  const { VITE_APP_PORT, VITE_SERVER_BASEURL, VITE_DELETE_CONSOLE, VITE_SHOW_SOURCEMAP } = env
+  const {
+    VITE_APP_PORT,
+    VITE_SERVER_BASEURL,
+    VITE_DELETE_CONSOLE,
+    VITE_SHOW_SOURCEMAP,
+    VITE_APP_PROXY,
+    VITE_APP_PROXY_PREFIX,
+  } = env
   console.log('环境变量 env -> ', env)
 
   return defineConfig({
@@ -87,6 +94,7 @@ export default ({ command, mode }) => {
     ],
     define: {
       __UNI_PLATFORM__: JSON.stringify(UNI_PLATFORM),
+      __VITE_APP_PROXY__: JSON.stringify(VITE_APP_PROXY),
     },
     css: {
       postcss: {
@@ -110,13 +118,15 @@ export default ({ command, mode }) => {
       hmr: true,
       port: Number.parseInt(VITE_APP_PORT, 10),
       // 仅 H5 端生效,其他端不生效(其他端走build,不走devServer)
-      // proxy: {
-      //   '/api': {
-      //     target: VITE_SERVER_BASEURL,
-      //     changeOrigin: true,
-      //     rewrite: (path) => path.replace(/^\/api/, ''),
-      //   },
-      // },
+      proxy: JSON.parse(VITE_APP_PROXY)
+        ? {
+            [VITE_APP_PROXY_PREFIX]: {
+              target: VITE_SERVER_BASEURL,
+              changeOrigin: true,
+              rewrite: (path) => path.replace(new RegExp(`^${VITE_APP_PROXY_PREFIX}`), ''),
+            },
+          }
+        : undefined,
     },
     build: {
       // 方便非h5端调试