diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json index 9988edd..de203b7 100644 --- a/.eslintrc-auto-import.json +++ b/.eslintrc-auto-import.json @@ -87,6 +87,8 @@ "watchEffect": true, "watchPostEffect": true, "watchSyncEffect": true, - "useRequest": true + "useRequest": true, + "useUpload": true, + "useUpload2": true } } diff --git a/env/.env b/env/.env index c71934d..8f89c8f 100644 --- a/env/.env +++ b/env/.env @@ -10,3 +10,5 @@ VITE_WX_APPID = 'wxa2abb91f64032a2b' # 非h5端只能使用完整的baseurl,否则无法请求,本地proxy只支持h5端 # VITE_SERVER_BASEURL = '/api' VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run' + +VITE_UPLOAD_BASEURL = 'https://ukw0y1.laf.run/upload' diff --git a/package.json b/package.json index 8a0b16e..5a549f4 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "dayjs": "1.11.10", "pinia": "2.0.36", "pinia-plugin-persistedstate": "3.2.1", - "qs": "^6.11.2", + "qs": "6.5.3", "vue": "3.3.11", "wot-design-uni": "^1.2.13" }, @@ -150,8 +150,6 @@ "unplugin-auto-import": "^0.17.2", "vite": "4.3.5", "vite-plugin-restart": "^0.4.0", - "vite-plugin-svg-icons": "^2.0.1", - "vite-svg-loader": "^5.1.0", "vue-tsc": "^1.8.25" } } diff --git a/src/env.d.ts b/src/env.d.ts index fa8c7d8..f19eda8 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -9,9 +9,15 @@ declare module '*.vue' { } interface ImportMetaEnv { + /** 网站标题,应用名称 */ readonly VITE_APP_TITLE: string + /** 服务端口号 */ readonly VITE_SERVER_PORT: string + /** 后台接口地址 */ readonly VITE_SERVER_BASEURL: string + /** 上传图片地址 */ + readonly VITE_UPLOAD_BASEURL: string + /** 是否清除console */ readonly VITE_DELETE_CONSOLE: string // 更多环境变量... } diff --git a/src/hooks/useUpload.ts b/src/hooks/useUpload.ts new file mode 100644 index 0000000..d14e1f1 --- /dev/null +++ b/src/hooks/useUpload.ts @@ -0,0 +1,80 @@ +/** + * useUpload 是一个定制化的请求钩子,用于处理上传图片。 + * @param formData 额外传递给后台的数据,如{name: '菲鸽'}。 + * @returns 返回一个对象{loading, error, data, run},包含请求的加载状态、错误信息、响应数据和手动触发请求的函数。 + */ +export default function useUpload(formData: Record = {}) { + const loading = ref(false) + const error = ref(false) + const data = ref() + const url = import.meta.env.VITE_UPLOAD_BASEURL + 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 } +} diff --git a/src/hooks/useUpload2.ts b/src/hooks/useUpload2.ts new file mode 100644 index 0000000..b99e374 --- /dev/null +++ b/src/hooks/useUpload2.ts @@ -0,0 +1,82 @@ +/** + * useUpload 是一个定制化的请求钩子,用于处理上传图片。 + * @param url 上传图片的后台地址,如 https://ukw0y1.laf.run/upload。 + * 如果上传地址是固定的,那就可以配置到 .env 里面,函数里面不需要再传了。 + * @param formData 额外传递给后台的数据,如{name: '菲鸽'}。 + * @returns 返回一个对象{loading, error, data, run},包含请求的加载状态、错误信息、响应数据和手动触发请求的函数。 + */ +export default function useUpload(url: string, formData: Record = {}) { + const loading = ref(false) + const error = ref(false) + const data = ref() + + 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 } +} diff --git a/src/pages.json b/src/pages.json index 04886e9..29cf368 100644 --- a/src/pages.json +++ b/src/pages.json @@ -66,7 +66,23 @@ "type": "page", "layout": "demo", "style": { - "navigationBarTitleText": "请求" + "navigationBarTitleText": "请求-状态一体化" + } + }, + { + "path": "pages/index/upload", + "type": "page", + "layout": "default", + "style": { + "navigationBarTitleText": "上传" + } + }, + { + "path": "pages/index/upload2", + "type": "page", + "layout": "default", + "style": { + "navigationBarTitleText": "上传-状态一体化" } } ], diff --git a/src/pages/index/about.vue b/src/pages/index/about.vue index 043833f..5ce4ae4 100644 --- a/src/pages/index/about.vue +++ b/src/pages/index/about.vue @@ -22,6 +22,10 @@ 去请求页2 (请求状态一体化) + + 上传demo + 上传demo2(请求状态一体化) + diff --git a/src/pages/index/request2.vue b/src/pages/index/request2.vue index df06848..3f63f9e 100644 --- a/src/pages/index/request2.vue +++ b/src/pages/index/request2.vue @@ -2,7 +2,7 @@ { layout: 'demo', style: { - navigationBarTitleText: '请求', + navigationBarTitleText: '请求-状态一体化', }, } @@ -13,15 +13,20 @@ 请求数据如下 加载中... + 请求错误 {{ JSON.stringify(data) }} + + diff --git a/src/pages/index/upload2.vue b/src/pages/index/upload2.vue new file mode 100644 index 0000000..42c54f4 --- /dev/null +++ b/src/pages/index/upload2.vue @@ -0,0 +1,31 @@ + +{ + layout: 'default', + style: { + navigationBarTitleText: '上传-状态一体化', + }, +} + + + + + + + diff --git a/src/service/index/foo.d.ts b/src/service/index/foo.d.ts deleted file mode 100644 index 81bc41a..0000000 --- a/src/service/index/foo.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface IFooItem { - id: string - name: string -} diff --git a/src/service/index/foo.ts b/src/service/index/foo.ts index 30cc470..7263dfc 100644 --- a/src/service/index/foo.ts +++ b/src/service/index/foo.ts @@ -1,9 +1,10 @@ -import { http } from '@/utils/http' -import type { IFooItem } from './foo.d' +import { http, httpGet } from '@/utils/http' +export interface IFooItem { + id: string + name: string +} -export { IFooItem } - -/** get 请求 */ +/** GET 请求 */ export const getFooAPI = (name: string) => { return http({ url: `/foo`, @@ -12,7 +13,12 @@ export const getFooAPI = (name: string) => { }) } -/** get 请求 */ +/** GET 请求 - 再次简化,看大家是否喜欢这种简化 */ +export const getFooAPI2 = (name: string) => { + return httpGet('/foo', { name }) +} + +/** POST 请求 */ export const postFooAPI = (name: string) => { return http({ url: `/foo`, diff --git a/src/utils/http.ts b/src/utils/http.ts index b275bc2..db4c6aa 100644 --- a/src/utils/http.ts +++ b/src/utils/http.ts @@ -41,42 +41,36 @@ export const http = (options: CustomRequestOptions) => { }) }) } - -// uni.uploadFile封装 -export const uniFileUpload = (options: CustomRequestOptions) => { - // 1. 返回 Promise 对象 - return new Promise>((resolve, reject) => { - uni.uploadFile({ - ...options, - // 响应成功 - success(res) { - // 状态码 2xx,参考 axios 的设计 - if (res.statusCode >= 200 && res.statusCode < 300) { - // 文件上传接口的rea.data的类型为string,这里转一下 - const resData = JSON.parse(res.data) as IResData - resolve(resData) - } else if (res.statusCode === 401) { - // 401错误 -> 清理用户信息,跳转到登录页 - // userStore.clearUserInfo() - // uni.navigateTo({ url: '/pages/login/login' }) - reject(res) - } else { - // 其他错误 -> 根据后端错误信息轻提示 - uni.showToast({ - icon: 'none', - title: '文件上传错误', - }) - reject(res) - } - }, - // 响应失败 - fail(err) { - uni.showToast({ - icon: 'none', - title: '网络错误,换个网络试试', - }) - reject(err) - }, - }) +/** + * GET 请求 + * @param url 后台地址 + * @param query 请求query参数 + * @returns + */ +export const httpGet = (url: string, query?: Record) => { + return http({ + url, + query, + method: 'GET', + }) +} + +/** + * POST 请求 + * @param url 后台地址 + * @param data 请求body参数 + * @param query 请求query参数,post请求也支持query,很多微信接口都需要 + * @returns + */ +export const httpPost = ( + url: string, + data?: Record, + query?: Record, +) => { + return http({ + url, + query, + data, + method: 'POST', }) } diff --git a/vite.config.ts b/vite.config.ts index bc192e9..e678465 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -13,8 +13,6 @@ import UniPlatform from '@uni-helper/vite-plugin-uni-platform' import UniManifest from '@uni-helper/vite-plugin-uni-manifest' // @see https://unocss.dev/ import UnoCSS from 'unocss/vite' -// @see https://github.com/jpkleemans/vite-svg-loader -import svgLoader from 'vite-svg-loader' import AutoImport from 'unplugin-auto-import/vite' import { visualizer } from 'rollup-plugin-visualizer' import ViteRestart from 'vite-plugin-restart' @@ -58,10 +56,6 @@ export default ({ command, mode }) => { // UniXXX 需要在 Uni 之前引入 Uni(), UnoCSS(), - // svg 可以当做组件来使用(Vite plugin to load SVG files as Vue components, using SVGO for optimization.) - svgLoader({ - defaultImport: 'url', // or 'raw' - }), AutoImport({ imports: ['vue', 'uni-app'], dts: 'src/types/auto-import.d.ts',