Merge branch 'base' into i18n

This commit is contained in:
菲鸽 2024-05-03 20:00:52 +08:00
commit 5849176b59
14 changed files with 352 additions and 53 deletions

View File

@ -87,6 +87,8 @@
"watchEffect": true, "watchEffect": true,
"watchPostEffect": true, "watchPostEffect": true,
"watchSyncEffect": true, "watchSyncEffect": true,
"useRequest": true "useRequest": true,
"useUpload": true,
"useUpload2": true
} }
} }

2
env/.env vendored
View File

@ -10,3 +10,5 @@ VITE_WX_APPID = 'wxa2abb91f64032a2b'
# 非h5端只能使用完整的baseurl否则无法请求本地proxy只支持h5端 # 非h5端只能使用完整的baseurl否则无法请求本地proxy只支持h5端
# VITE_SERVER_BASEURL = '/api' # VITE_SERVER_BASEURL = '/api'
VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run' VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run'
VITE_UPLOAD_BASEURL = 'https://ukw0y1.laf.run/upload'

View File

@ -96,7 +96,7 @@
"dayjs": "1.11.10", "dayjs": "1.11.10",
"pinia": "2.0.36", "pinia": "2.0.36",
"pinia-plugin-persistedstate": "3.2.1", "pinia-plugin-persistedstate": "3.2.1",
"qs": "^6.11.2", "qs": "6.5.3",
"vue": "3.3.11", "vue": "3.3.11",
"wot-design-uni": "^1.2.13" "wot-design-uni": "^1.2.13"
}, },

6
src/env.d.ts vendored
View File

@ -9,9 +9,15 @@ declare module '*.vue' {
} }
interface ImportMetaEnv { interface ImportMetaEnv {
/** 网站标题,应用名称 */
readonly VITE_APP_TITLE: string readonly VITE_APP_TITLE: string
/** 服务端口号 */
readonly VITE_SERVER_PORT: string readonly VITE_SERVER_PORT: string
/** 后台接口地址 */
readonly VITE_SERVER_BASEURL: string readonly VITE_SERVER_BASEURL: string
/** 上传图片地址 */
readonly VITE_UPLOAD_BASEURL: string
/** 是否清除console */
readonly VITE_DELETE_CONSOLE: string readonly VITE_DELETE_CONSOLE: string
// 更多环境变量... // 更多环境变量...
} }

80
src/hooks/useUpload.ts Normal file
View File

@ -0,0 +1,80 @@
/**
* useUpload
* @param formData {name: '菲鸽'}
* @returns {loading, error, data, run}
*/
export default function useUpload<T>(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 代替。
// 微信小程序在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 }
}

82
src/hooks/useUpload2.ts Normal file
View File

@ -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<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 }
}

View File

@ -72,7 +72,23 @@
"type": "page", "type": "page",
"layout": "demo", "layout": "demo",
"style": { "style": {
"navigationBarTitleText": "请求" "navigationBarTitleText": "请求-状态一体化"
}
},
{
"path": "pages/index/upload",
"type": "page",
"layout": "default",
"style": {
"navigationBarTitleText": "上传"
}
},
{
"path": "pages/index/upload2",
"type": "page",
"layout": "default",
"style": {
"navigationBarTitleText": "上传-状态一体化"
} }
} }
], ],

View File

@ -20,6 +20,10 @@
<wd-button type="primary" @click="gotoPage('i18n')">进入多语言页面</wd-button> <wd-button type="primary" @click="gotoPage('i18n')">进入多语言页面</wd-button>
<wd-button type="primary" @click="gotoPage('request')" class="ml-2">去请求页</wd-button> <wd-button type="primary" @click="gotoPage('request')" class="ml-2">去请求页</wd-button>
</view> </view>
<view class="text-center mt-8 text-#fff">
<wd-button type="primary" @click="gotoPage('upload')">上传demo</wd-button>
<wd-button type="primary" @click="gotoPage('upload2')">上传demo2(请求状态一体化)</wd-button>
</view>
</view> </view>
</template> </template>

View File

@ -2,7 +2,7 @@
{ {
layout: 'demo', layout: 'demo',
style: { style: {
navigationBarTitleText: '请求', navigationBarTitleText: '请求-状态一体化',
}, },
} }
</route> </route>
@ -13,15 +13,20 @@
<button @click="getFoo" class="my-6">测试 GET 请求</button> <button @click="getFoo" class="my-6">测试 GET 请求</button>
<view class="text-xl">请求数据如下</view> <view class="text-xl">请求数据如下</view>
<view v-if="loading" class="text-blue h-10">加载中...</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> <view v-else class="text-green h-10">{{ JSON.stringify(data) }}</view>
<button class="my-6" type="warn" @click="reset">一键清空数据</button> <button class="my-6" type="warn" @click="reset">一键清空数据</button>
</view> </view>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { getFooAPI, IFooItem } from '@/service/index/foo' import { getFooAPI2, IFooItem } from '@/service/index/foo'
import { httpGet } from '@/utils/http'
const { loading, data, run } = useRequest<IFooItem>(() => getFooAPI('菲鸽'), { immediate: true }) // Service
const { loading, error, data, run } = useRequest<IFooItem>(() => getFooAPI2('菲鸽'))
// 便
// const { loading, error, data, run } = useRequest<IFooItem>(() => httpGet('/foo', { name: '' }))
const getFoo = () => run() const getFoo = () => run()
const reset = () => { const reset = () => {

View File

@ -0,0 +1,75 @@
<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
// 20231017使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>

View File

@ -0,0 +1,31 @@
<route lang="json5" type="page">
{
layout: 'default',
style: {
navigationBarTitleText: '上传-状态一体化',
},
}
</route>
<template>
<view class="p-4 text-center">
<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">{{ data }}</view>
<view class="h-80 w-full">
<image v-if="data" :src="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: '菲鸽' })
</script>
<style lang="scss" scoped>
//
</style>

View File

@ -1,4 +0,0 @@
export interface IFooItem {
id: string
name: string
}

View File

@ -1,9 +1,10 @@
import { http } from '@/utils/http' import { http, httpGet } from '@/utils/http'
import type { IFooItem } from './foo.d' export interface IFooItem {
id: string
name: string
}
export { IFooItem } /** GET 请求 */
/** get 请求 */
export const getFooAPI = (name: string) => { export const getFooAPI = (name: string) => {
return http<IFooItem>({ return http<IFooItem>({
url: `/foo`, url: `/foo`,
@ -12,7 +13,12 @@ export const getFooAPI = (name: string) => {
}) })
} }
/** get 请求 */ /** GET 请求 - 再次简化,看大家是否喜欢这种简化 */
export const getFooAPI2 = (name: string) => {
return httpGet<IFooItem>('/foo', { name })
}
/** POST 请求 */
export const postFooAPI = (name: string) => { export const postFooAPI = (name: string) => {
return http<IFooItem>({ return http<IFooItem>({
url: `/foo`, url: `/foo`,

View File

@ -41,42 +41,36 @@ export const http = <T>(options: CustomRequestOptions) => {
}) })
}) })
} }
/**
// uni.uploadFile封装 * GET
export const uniFileUpload = <T>(options: CustomRequestOptions) => { * @param url
// 1. 返回 Promise 对象 * @param query query参数
return new Promise<IResData<T>>((resolve, reject) => { * @returns
uni.uploadFile({ */
...options, export const httpGet = <T>(url: string, query?: Record<string, any>) => {
// 响应成功 return http<T>({
success(res) { url,
// 状态码 2xx参考 axios 的设计 query,
if (res.statusCode >= 200 && res.statusCode < 300) { method: 'GET',
// 文件上传接口的rea.data的类型为string这里转一下 })
const resData = JSON.parse(res.data) as IResData<T> }
resolve(resData)
} else if (res.statusCode === 401) { /**
// 401错误 -> 清理用户信息,跳转到登录页 * POST
// userStore.clearUserInfo() * @param url
// uni.navigateTo({ url: '/pages/login/login' }) * @param data body参数
reject(res) * @param query query参数post请求也支持query
} else { * @returns
// 其他错误 -> 根据后端错误信息轻提示 */
uni.showToast({ export const httpPost = <T>(
icon: 'none', url: string,
title: '文件上传错误', data?: Record<string, any>,
}) query?: Record<string, any>,
reject(res) ) => {
} return http<T>({
}, url,
// 响应失败 query,
fail(err) { data,
uni.showToast({ method: 'POST',
icon: 'none',
title: '网络错误,换个网络试试',
})
reject(err)
},
})
}) })
} }