初始化仓库
This commit is contained in:
50
src/hooks/usePageAuth.ts
Normal file
50
src/hooks/usePageAuth.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useUserStore } from '@/store'
|
||||
import { needLoginPages as _needLoginPages, getNeedLoginPages } from '@/utils'
|
||||
|
||||
const loginRoute = import.meta.env.VITE_LOGIN_URL
|
||||
const isDev = import.meta.env.DEV
|
||||
function isLogined() {
|
||||
const userStore = useUserStore()
|
||||
return !!userStore.userInfo.username
|
||||
}
|
||||
// 检查当前页面是否需要登录
|
||||
export function usePageAuth() {
|
||||
onLoad((options) => {
|
||||
// 获取当前页面路径
|
||||
const pages = getCurrentPages()
|
||||
const currentPage = pages[pages.length - 1]
|
||||
const currentPath = `/${currentPage.route}`
|
||||
|
||||
// 获取需要登录的页面列表
|
||||
let needLoginPages: string[] = []
|
||||
if (isDev) {
|
||||
needLoginPages = getNeedLoginPages()
|
||||
}
|
||||
else {
|
||||
needLoginPages = _needLoginPages
|
||||
}
|
||||
|
||||
// 检查当前页面是否需要登录
|
||||
const isNeedLogin = needLoginPages.includes(currentPath)
|
||||
if (!isNeedLogin) {
|
||||
return
|
||||
}
|
||||
|
||||
const hasLogin = isLogined()
|
||||
if (hasLogin) {
|
||||
return true
|
||||
}
|
||||
|
||||
// 构建重定向URL
|
||||
const queryString = Object.entries(options || {})
|
||||
.map(([key, value]) => `${key}=${encodeURIComponent(String(value))}`)
|
||||
.join('&')
|
||||
|
||||
const currentFullPath = queryString ? `${currentPath}?${queryString}` : currentPath
|
||||
const redirectRoute = `${loginRoute}?redirect=${encodeURIComponent(currentFullPath)}`
|
||||
|
||||
// 重定向到登录页
|
||||
uni.redirectTo({ url: redirectRoute })
|
||||
})
|
||||
}
|
||||
51
src/hooks/useRequest.ts
Normal file
51
src/hooks/useRequest.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
interface IUseRequestOptions<T> {
|
||||
/** 是否立即执行 */
|
||||
immediate?: boolean
|
||||
/** 初始化数据 */
|
||||
initialData?: T
|
||||
}
|
||||
|
||||
interface IUseRequestReturn<T> {
|
||||
loading: Ref<boolean>
|
||||
error: Ref<boolean | Error>
|
||||
data: Ref<T | undefined>
|
||||
run: () => Promise<T | undefined>
|
||||
}
|
||||
|
||||
/**
|
||||
* useRequest是一个定制化的请求钩子,用于处理异步请求和响应。
|
||||
* @param func 一个执行异步请求的函数,返回一个包含响应数据的Promise。
|
||||
* @param options 包含请求选项的对象 {immediate, initialData}。
|
||||
* @param options.immediate 是否立即执行请求,默认为false。
|
||||
* @param options.initialData 初始化数据,默认为undefined。
|
||||
* @returns 返回一个对象{loading, error, data, run},包含请求的加载状态、错误信息、响应数据和手动触发请求的函数。
|
||||
*/
|
||||
export default function useRequest<T>(
|
||||
func: () => Promise<IResData<T>>,
|
||||
options: IUseRequestOptions<T> = { immediate: false },
|
||||
): IUseRequestReturn<T> {
|
||||
const loading = ref(false)
|
||||
const error = ref(false)
|
||||
const data = ref<T | undefined>(options.initialData) as Ref<T | undefined>
|
||||
const run = async () => {
|
||||
loading.value = true
|
||||
return func()
|
||||
.then((res) => {
|
||||
data.value = res.data
|
||||
error.value = false
|
||||
return data.value
|
||||
})
|
||||
.catch((err) => {
|
||||
error.value = err
|
||||
throw err
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
options.immediate && run()
|
||||
return { loading, error, data, run }
|
||||
}
|
||||
160
src/hooks/useUpload.ts
Normal file
160
src/hooks/useUpload.ts
Normal file
@ -0,0 +1,160 @@
|
||||
import { ref } from 'vue'
|
||||
import { getEnvBaseUploadUrl } from '@/utils'
|
||||
|
||||
const VITE_UPLOAD_BASEURL = `${getEnvBaseUploadUrl()}`
|
||||
|
||||
type TfileType = 'image' | 'file'
|
||||
type TImage = 'png' | 'jpg' | 'jpeg' | 'webp' | '*'
|
||||
type TFile = 'doc' | 'docx' | 'ppt' | 'zip' | 'xls' | 'xlsx' | 'txt' | TImage
|
||||
|
||||
interface TOptions<T extends TfileType> {
|
||||
formData?: Record<string, any>
|
||||
maxSize?: number
|
||||
accept?: T extends 'image' ? TImage[] : TFile[]
|
||||
fileType?: T
|
||||
success?: (params: any) => void
|
||||
error?: (err: any) => void
|
||||
}
|
||||
|
||||
export default function useUpload<T extends TfileType>(options: TOptions<T> = {} as TOptions<T>) {
|
||||
const {
|
||||
formData = {},
|
||||
maxSize = 5 * 1024 * 1024,
|
||||
accept = ['*'],
|
||||
fileType = 'image',
|
||||
success,
|
||||
error: onError,
|
||||
} = options
|
||||
|
||||
const loading = ref(false)
|
||||
const error = ref<Error | null>(null)
|
||||
const data = ref<any>(null)
|
||||
|
||||
const handleFileChoose = ({ tempFilePath, size }: { tempFilePath: string, size: number }) => {
|
||||
if (size > maxSize) {
|
||||
uni.showToast({
|
||||
title: `文件大小不能超过 ${maxSize / 1024 / 1024}MB`,
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// const fileExtension = file?.tempFiles?.name?.split('.').pop()?.toLowerCase()
|
||||
// const isTypeValid = accept.some((type) => type === '*' || type.toLowerCase() === fileExtension)
|
||||
|
||||
// if (!isTypeValid) {
|
||||
// uni.showToast({
|
||||
// title: `仅支持 ${accept.join(', ')} 格式的文件`,
|
||||
// icon: 'none',
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
|
||||
loading.value = true
|
||||
uploadFile({
|
||||
tempFilePath,
|
||||
formData,
|
||||
onSuccess: (res) => {
|
||||
const { data: _data } = JSON.parse(res)
|
||||
data.value = _data
|
||||
// console.log('上传成功', res)
|
||||
success?.(_data)
|
||||
},
|
||||
onError: (err) => {
|
||||
error.value = err
|
||||
onError?.(err)
|
||||
},
|
||||
onComplete: () => {
|
||||
loading.value = false
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const run = () => {
|
||||
// 微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
|
||||
// 微信小程序在2023年10月17日之后,使用本API需要配置隐私协议
|
||||
const chooseFileOptions = {
|
||||
count: 1,
|
||||
success: (res: any) => {
|
||||
console.log('File selected successfully:', res)
|
||||
// 小程序中res:{errMsg: "chooseImage:ok", tempFiles: [{fileType: "image", size: 48976, tempFilePath: "http://tmp/5iG1WpIxTaJf3ece38692a337dc06df7eb69ecb49c6b.jpeg"}]}
|
||||
// h5中res:{errMsg: "chooseImage:ok", tempFilePaths: "blob:http://localhost:9000/f74ab6b8-a14d-4cb6-a10d-fcf4511a0de5", tempFiles: [File]}
|
||||
// h5的File有以下字段:{name: "girl.jpeg", size: 48976, type: "image/jpeg"}
|
||||
// App中res:{errMsg: "chooseImage:ok", tempFilePaths: "file:///Users/feige/xxx/gallery/1522437259-compressed-IMG_0006.jpg", tempFiles: [File]}
|
||||
// App的File有以下字段:{path: "file:///Users/feige/xxx/gallery/1522437259-compressed-IMG_0006.jpg", size: 48976}
|
||||
let tempFilePath = ''
|
||||
let size = 0
|
||||
// #ifdef MP-WEIXIN
|
||||
tempFilePath = res.tempFiles[0].tempFilePath
|
||||
size = res.tempFiles[0].size
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
tempFilePath = res.tempFilePaths[0]
|
||||
size = res.tempFiles[0].size
|
||||
// #endif
|
||||
handleFileChoose({ tempFilePath, size })
|
||||
},
|
||||
fail: (err: any) => {
|
||||
console.error('File selection failed:', err)
|
||||
error.value = err
|
||||
onError?.(err)
|
||||
},
|
||||
}
|
||||
|
||||
if (fileType === 'image') {
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.chooseMedia({
|
||||
...chooseFileOptions,
|
||||
mediaType: ['image'],
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifndef MP-WEIXIN
|
||||
uni.chooseImage(chooseFileOptions)
|
||||
// #endif
|
||||
}
|
||||
else {
|
||||
uni.chooseFile({
|
||||
...chooseFileOptions,
|
||||
type: 'all',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return { loading, error, data, run }
|
||||
}
|
||||
|
||||
async function uploadFile({
|
||||
tempFilePath,
|
||||
formData,
|
||||
onSuccess,
|
||||
onError,
|
||||
onComplete,
|
||||
}: {
|
||||
tempFilePath: string
|
||||
formData: Record<string, any>
|
||||
onSuccess: (data: any) => void
|
||||
onError: (err: any) => void
|
||||
onComplete: () => void
|
||||
}) {
|
||||
uni.uploadFile({
|
||||
url: VITE_UPLOAD_BASEURL,
|
||||
filePath: tempFilePath,
|
||||
name: 'file',
|
||||
formData,
|
||||
success: (uploadFileRes) => {
|
||||
try {
|
||||
const data = uploadFileRes.data
|
||||
onSuccess(data)
|
||||
}
|
||||
catch (err) {
|
||||
onError(err)
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('Upload failed:', err)
|
||||
onError(err)
|
||||
},
|
||||
complete: onComplete,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user