更新:登录功能

This commit is contained in:
2025-11-04 12:37:04 +08:00
commit a21fb92916
897 changed files with 51500 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
export { useCell } from './useCell'
export { useChildren, flattenVNodes, sortChildren } from './useChildren'
export { useCountDown } from './useCountDown'
export { useLockScroll } from './useLockScroll'
export { useParent } from './useParent'
export { usePopover } from './usePopover'
export { useQueue } from './useQueue'
export { useRaf } from './useRaf'
export { useTouch } from './useTouch'
export { useTranslate } from './useTranslate'
export { useUpload } from './useUpload'

View File

@@ -0,0 +1,13 @@
import { computed } from 'vue'
import { useParent } from './useParent'
import { CELL_GROUP_KEY } from '../wd-cell-group/types'
export function useCell() {
const { parent: cellGroup, index } = useParent(CELL_GROUP_KEY)
const border = computed(() => {
return cellGroup && cellGroup.props.border && index.value
})
return { border }
}

View File

@@ -0,0 +1,113 @@
import {
provide,
reactive,
getCurrentInstance,
type VNode,
type InjectionKey,
type VNodeNormalizedChildren,
type ComponentPublicInstance,
type ComponentInternalInstance
} from 'vue'
// 小程序端不支持从vue导出的isVNode方法参考uni-mp-vue的实现
function isVNode(value: any): value is VNode {
return value ? value.__v_isVNode === true : false
}
export function flattenVNodes(children: VNodeNormalizedChildren) {
const result: VNode[] = []
const traverse = (children: VNodeNormalizedChildren) => {
if (Array.isArray(children)) {
children.forEach((child) => {
if (isVNode(child)) {
result.push(child)
if (child.component?.subTree) {
result.push(child.component.subTree)
traverse(child.component.subTree.children)
}
if (child.children) {
traverse(child.children)
}
}
})
}
}
traverse(children)
return result
}
const findVNodeIndex = (vnodes: VNode[], vnode: VNode) => {
const index = vnodes.indexOf(vnode)
if (index === -1) {
return vnodes.findIndex((item) => vnode.key !== undefined && vnode.key !== null && item.type === vnode.type && item.key === vnode.key)
}
return index
}
// sort children instances by vnodes order
export function sortChildren(
parent: ComponentInternalInstance,
publicChildren: ComponentPublicInstance[],
internalChildren: ComponentInternalInstance[]
) {
const vnodes = parent && parent.subTree && parent.subTree.children ? flattenVNodes(parent.subTree.children) : []
internalChildren.sort((a, b) => findVNodeIndex(vnodes, a.vnode) - findVNodeIndex(vnodes, b.vnode))
const orderedPublicChildren = internalChildren.map((item) => item.proxy!)
publicChildren.sort((a, b) => {
const indexA = orderedPublicChildren.indexOf(a)
const indexB = orderedPublicChildren.indexOf(b)
return indexA - indexB
})
}
export function useChildren<
// eslint-disable-next-line
Child extends ComponentPublicInstance = ComponentPublicInstance<{}, any>,
ProvideValue = never
>(key: InjectionKey<ProvideValue>) {
const publicChildren: Child[] = reactive([])
const internalChildren: ComponentInternalInstance[] = reactive([])
const parent = getCurrentInstance()!
const linkChildren = (value?: ProvideValue) => {
const link = (child: ComponentInternalInstance) => {
if (child.proxy) {
internalChildren.push(child)
publicChildren.push(child.proxy as Child)
sortChildren(parent, publicChildren, internalChildren)
}
}
const unlink = (child: ComponentInternalInstance) => {
const index = internalChildren.indexOf(child)
publicChildren.splice(index, 1)
internalChildren.splice(index, 1)
}
provide(
key,
Object.assign(
{
link,
unlink,
children: publicChildren,
internalChildren
},
value
)
)
}
return {
children: publicChildren,
linkChildren
}
}

View File

@@ -0,0 +1,138 @@
import { ref, computed, onBeforeUnmount } from 'vue'
import { isDef } from '../common/util'
import { useRaf } from './useRaf'
// 定义倒计时时间的数据结构
export type CurrentTime = {
days: number
hours: number
total: number
minutes: number
seconds: number
milliseconds: number
}
// 定义倒计时的配置项
export type UseCountDownOptions = {
time: number // 倒计时总时间,单位为毫秒
millisecond?: boolean // 是否开启毫秒级倒计时,默认为 false
onChange?: (current: CurrentTime) => void // 倒计时每次变化时的回调函数
onFinish?: () => void // 倒计时结束时的回调函数
}
// 定义常量
const SECOND = 1000
const MINUTE = 60 * SECOND
const HOUR = 60 * MINUTE
const DAY = 24 * HOUR
// 将时间转换为倒计时数据结构
function parseTime(time: number): CurrentTime {
const days = Math.floor(time / DAY)
const hours = Math.floor((time % DAY) / HOUR)
const minutes = Math.floor((time % HOUR) / MINUTE)
const seconds = Math.floor((time % MINUTE) / SECOND)
const milliseconds = Math.floor(time % SECOND)
return {
total: time,
days,
hours,
minutes,
seconds,
milliseconds
}
}
// 判断两个时间是否在同一秒内
function isSameSecond(time1: number, time2: number): boolean {
return Math.floor(time1 / 1000) === Math.floor(time2 / 1000)
}
// 定义 useCountDown 函数
export function useCountDown(options: UseCountDownOptions) {
let endTime: number // 结束时间
let counting: boolean // 是否计时中
const { start: startRaf, cancel: cancelRaf } = useRaf(tick)
const remain = ref(options.time) // 剩余时间
const current = computed(() => parseTime(remain.value)) // 当前倒计时数据
// 暂停倒计时
const pause = () => {
counting = false
cancelRaf()
}
// 获取当前剩余时间
const getCurrentRemain = () => Math.max(endTime - Date.now(), 0)
// 设置剩余时间
const setRemain = (value: number) => {
remain.value = value
isDef(options.onChange) && options.onChange(current.value)
if (value === 0) {
pause()
isDef(options.onFinish) && options.onFinish()
}
}
// 每毫秒更新一次倒计时
const microTick = () => {
if (counting) {
setRemain(getCurrentRemain())
if (remain.value > 0) {
startRaf()
}
}
}
// 每秒更新一次倒计时
const macroTick = () => {
if (counting) {
const remainRemain = getCurrentRemain()
if (!isSameSecond(remainRemain, remain.value) || remainRemain === 0) {
setRemain(remainRemain)
}
if (remain.value > 0) {
startRaf()
}
}
}
// 根据配置项选择更新方式
function tick() {
if (options.millisecond) {
microTick()
} else {
macroTick()
}
}
// 开始倒计时
const start = () => {
if (!counting) {
endTime = Date.now() + remain.value
counting = true
startRaf()
}
}
// 重置倒计时
const reset = (totalTime: number = options.time) => {
pause()
remain.value = totalTime
}
// 在组件卸载前暂停倒计时
onBeforeUnmount(pause)
return {
start,
pause,
reset,
current
}
}

View File

@@ -0,0 +1,37 @@
import { onBeforeUnmount, onDeactivated, ref, watch } from 'vue'
export function useLockScroll(shouldLock: () => boolean) {
const scrollLockCount = ref(0)
const lock = () => {
if (scrollLockCount.value === 0) {
document.getElementsByTagName('body')[0].style.overflow = 'hidden'
}
scrollLockCount.value++
}
const unlock = () => {
if (scrollLockCount.value > 0) {
scrollLockCount.value--
if (scrollLockCount.value === 0) {
document.getElementsByTagName('body')[0].style.overflow = ''
}
}
}
const destroy = () => {
shouldLock() && unlock()
}
watch(shouldLock, (value) => {
value ? lock() : unlock()
})
onDeactivated(destroy)
onBeforeUnmount(destroy)
return {
lock,
unlock
}
}

View File

@@ -0,0 +1,41 @@
import {
ref,
inject,
computed,
onUnmounted,
type InjectionKey,
getCurrentInstance,
type ComponentPublicInstance,
type ComponentInternalInstance
} from 'vue'
type ParentProvide<T> = T & {
link(child: ComponentInternalInstance): void
unlink(child: ComponentInternalInstance): void
children: ComponentPublicInstance[]
internalChildren: ComponentInternalInstance[]
}
export function useParent<T>(key: InjectionKey<ParentProvide<T>>) {
const parent = inject(key, null)
if (parent) {
const instance = getCurrentInstance()!
const { link, unlink, internalChildren } = parent
link(instance)
onUnmounted(() => unlink(instance))
const index = computed(() => internalChildren.indexOf(instance))
return {
parent,
index
}
}
return {
parent: null,
index: ref(-1)
}
}

View File

@@ -0,0 +1,176 @@
import { getCurrentInstance, ref } from 'vue'
import { getRect, isObj } from '../common/util'
export function usePopover(visibleArrow = true) {
const { proxy } = getCurrentInstance() as any
const popStyle = ref<string>('')
const arrowStyle = ref<string>('')
const showStyle = ref<string>('')
const arrowClass = ref<string>('')
const popWidth = ref<number>(0)
const popHeight = ref<number>(0)
const left = ref<number>(0)
const bottom = ref<number>(0)
const width = ref<number>(0)
const height = ref<number>(0)
const top = ref<number>(0)
function noop() {}
function init(
placement:
| 'top'
| 'top-start'
| 'top-end'
| 'bottom'
| 'bottom-start'
| 'bottom-end'
| 'left'
| 'left-start'
| 'left-end'
| 'right'
| 'right-start'
| 'right-end',
visibleArrow: boolean,
selector: string
) {
// 初始化 class
if (visibleArrow) {
const arrowClassArr = [
`wd-${selector}__arrow`,
placement === 'bottom' || placement === 'bottom-start' || placement === 'bottom-end' ? `wd-${selector}__arrow-up` : '',
placement === 'left' || placement === 'left-start' || placement === 'left-end' ? `wd-${selector}__arrow-right` : '',
placement === 'right' || placement === 'right-start' || placement === 'right-end' ? `wd-${selector}__arrow-left` : '',
placement === 'top' || placement === 'top-start' || placement === 'top-end' ? `wd-${selector}__arrow-down` : ''
]
arrowClass.value = arrowClassArr.join(' ')
}
// 初始化数据获取
getRect('#target', false, proxy).then((rect) => {
if (!rect) return
left.value = rect.left as number
bottom.value = rect.bottom as number
width.value = rect.width as number
height.value = rect.height as number
top.value = rect.top as number
})
// 用透明度可在初始化时获取到pop尺寸
getRect('#pos', false, proxy).then((rect) => {
if (!rect) return
popWidth.value = rect.width as number
popHeight.value = rect.height as number
})
}
function control(
placement:
| 'top'
| 'top-start'
| 'top-end'
| 'bottom'
| 'bottom-start'
| 'bottom-end'
| 'left'
| 'left-start'
| 'left-end'
| 'right'
| 'right-start'
| 'right-end',
offset: number | number[] | Record<'x' | 'y', number>
) {
// arrow size
const arrowSize = visibleArrow ? 9 : 0
// 上下位(纵轴)对应的距离左边的距离
const verticalX = width.value / 2
// 上下位(纵轴)对应的距离底部的距离
const verticalY = arrowSize + height.value + 5
// 左右位(横轴)对应的距离左边的距离
const horizontalX = width.value + arrowSize + 5
// 左右位(横轴)对应的距离底部的距离
const horizontalY = height.value / 2
let offsetX = 0
let offsetY = 0
if (Array.isArray(offset)) {
offsetX = (verticalX - 17 > 0 ? 0 : verticalX - 25) + offset[0]
offsetY = (horizontalY - 17 > 0 ? 0 : horizontalY - 25) + (offset[1] ? offset[1] : offset[0])
} else if (isObj(offset)) {
offsetX = (verticalX - 17 > 0 ? 0 : verticalX - 25) + offset.x
offsetY = (horizontalY - 17 > 0 ? 0 : horizontalY - 25) + offset.y
} else {
offsetX = (verticalX - 17 > 0 ? 0 : verticalX - 25) + offset
offsetY = (horizontalY - 17 > 0 ? 0 : horizontalY - 25) + offset
}
// const offsetX = (verticalX - 17 > 0 ? 0 : verticalX - 25) + offset
// const offsetY = (horizontalY - 17 > 0 ? 0 : horizontalY - 25) + offset
const placements = new Map([
// 上
['top', [`left: ${verticalX}px; bottom: ${verticalY}px; transform: translateX(-50%);`, 'left: 50%;']],
[
'top-start',
[
`left: ${offsetX}px; bottom: ${verticalY}px;`,
`left: ${(popWidth.value >= width.value ? width.value / 2 : popWidth.value - 25) - offsetX}px;`
]
],
[
'top-end',
[
`right: ${offsetX}px; bottom: ${verticalY}px;`,
`right: ${(popWidth.value >= width.value ? width.value / 2 : popWidth.value - 25) - offsetX}px; transform: translateX(50%);`
]
],
// 下
['bottom', [`left: ${verticalX}px; top: ${verticalY}px; transform: translateX(-50%);`, 'left: 50%;']],
[
'bottom-start',
[`left: ${offsetX}px; top: ${verticalY}px;`, `left: ${(popWidth.value >= width.value ? width.value / 2 : popWidth.value - 25) - offsetX}px;`]
],
[
'bottom-end',
[
`right: ${offsetX}px; top: ${verticalY}px;`,
`right: ${(popWidth.value >= width.value ? width.value / 2 : popWidth.value - 25) - offsetX}px; transform: translateX(50%);`
]
],
// 左
['left', [`right: ${horizontalX}px; top: ${horizontalY}px; transform: translateY(-50%);`, 'top: 50%']],
[
'left-start',
[
`right: ${horizontalX}px; top: ${offsetY}px;`,
`top: ${(popHeight.value >= height.value ? height.value / 2 : popHeight.value - 20) - offsetY}px;`
]
],
[
'left-end',
[
`right: ${horizontalX}px; bottom: ${offsetY}px;`,
`bottom: ${(popHeight.value >= height.value ? height.value / 2 : popHeight.value - 20) - offsetY}px; transform: translateY(50%);`
]
],
// 右
['right', [`left: ${horizontalX}px; top: ${horizontalY}px; transform: translateY(-50%);`, 'top: 50%']],
[
'right-start',
[
`left: ${horizontalX}px; top: ${offsetY}px;`,
`top: ${(popHeight.value >= height.value ? height.value / 2 : popHeight.value - 20) - offsetY}px;`
]
],
[
'right-end',
[
`left: ${horizontalX}px; bottom: ${offsetY}px;`,
`bottom: ${(popHeight.value >= height.value ? height.value / 2 : popHeight.value - 20) - offsetY}px; transform: translateY(50%);`
]
]
])
popStyle.value = placements.get(placement)![0]
arrowStyle.value = placements.get(placement)![1]
}
return { popStyle, arrowStyle, showStyle, arrowClass, init, control, noop }
}

View File

@@ -0,0 +1,52 @@
import { type Ref, provide, ref } from 'vue'
export const queueKey = '__QUEUE_KEY__'
export interface Queue {
queue: Ref<any[]>
pushToQueue: (comp: any) => void
removeFromQueue: (comp: any) => void
closeOther: (comp: any) => void
closeOutside: () => void
}
export function useQueue() {
const queue = ref<any[]>([])
function pushToQueue(comp: any) {
queue.value.push(comp)
}
function removeFromQueue(comp: any) {
queue.value = queue.value.filter((item) => {
return item.$.uid !== comp.$.uid
})
}
function closeOther(comp: any) {
queue.value.forEach((item) => {
if (item.$.uid !== comp.$.uid) {
item.$.exposed.close()
}
})
}
function closeOutside() {
queue.value.forEach((item) => {
item.$.exposed.close()
})
}
provide(queueKey, {
queue,
pushToQueue,
removeFromQueue,
closeOther,
closeOutside
})
return {
closeOther,
closeOutside
}
}

View File

@@ -0,0 +1,37 @@
import { ref, onUnmounted } from 'vue'
import { isDef, isH5, isNumber } from '../common/util'
// 定义回调函数类型
type RafCallback = (time: number) => void
export function useRaf(callback: RafCallback) {
const requestRef = ref<number | null | ReturnType<typeof setTimeout>>(null)
// 启动动画帧
const start = () => {
const handle = (time: number) => {
callback(time)
}
if (isH5) {
requestRef.value = requestAnimationFrame(handle)
} else {
requestRef.value = setTimeout(() => handle(Date.now()), 1000 / 30)
}
}
// 取消动画帧
const cancel = () => {
if (isH5 && isNumber(requestRef.value)) {
cancelAnimationFrame(requestRef.value!)
} else if (isDef(requestRef.value)) {
clearTimeout(requestRef.value)
}
}
onUnmounted(() => {
cancel()
})
return { start, cancel }
}

View File

@@ -0,0 +1,43 @@
import { ref } from 'vue'
export function useTouch() {
const direction = ref<string>('')
const deltaX = ref<number>(0)
const deltaY = ref<number>(0)
const offsetX = ref<number>(0)
const offsetY = ref<number>(0)
const startX = ref<number>(0)
const startY = ref<number>(0)
function touchStart(event: any) {
const touch = event.touches[0]
direction.value = ''
deltaX.value = 0
deltaY.value = 0
offsetX.value = 0
offsetY.value = 0
startX.value = touch.clientX
startY.value = touch.clientY
}
function touchMove(event: any) {
const touch = event.touches[0]
deltaX.value = touch.clientX - startX.value
deltaY.value = touch.clientY - startY.value
offsetX.value = Math.abs(deltaX.value)
offsetY.value = Math.abs(deltaY.value)
direction.value = offsetX.value > offsetY.value ? 'horizontal' : offsetX.value < offsetY.value ? 'vertical' : ''
}
return {
touchStart,
touchMove,
direction,
deltaX,
deltaY,
offsetX,
offsetY,
startX,
startY
}
}

View File

@@ -0,0 +1,12 @@
import { camelCase, getPropByPath, isDef, isFunction } from '../common/util'
import Locale from '../../locale'
export const useTranslate = (name?: string) => {
const prefix = name ? camelCase(name) + '.' : ''
const translate = (key: string, ...args: unknown[]) => {
const currentMessages = Locale.messages()
const message = getPropByPath(currentMessages, prefix + key)
return isFunction(message) ? message(...args) : isDef(message) ? message : `${prefix}${key}`
}
return { translate }
}

View File

@@ -0,0 +1,364 @@
import { isArray, isDef, isFunction } from '../common/util'
import type { ChooseFile, ChooseFileOption, UploadFileItem, UploadMethod, UploadStatusType } from '../wd-upload/types'
export const UPLOAD_STATUS: Record<string, UploadStatusType> = {
PENDING: 'pending',
LOADING: 'loading',
SUCCESS: 'success',
FAIL: 'fail'
}
export interface UseUploadReturn {
// 开始上传文件
startUpload: (file: UploadFileItem, options: UseUploadOptions) => UniApp.UploadTask | void | Promise<void>
// 中断上传
abort: (task?: UniApp.UploadTask) => void
// 上传状态常量
UPLOAD_STATUS: Record<string, UploadStatusType>
// 选择文件
chooseFile: (options: ChooseFileOption) => Promise<ChooseFile[]>
}
export interface UseUploadOptions {
// 上传地址
action: string
// 请求头
header?: Record<string, any>
// 文件对应的 key
name?: string
// 其它表单数据
formData?: Record<string, any>
// 文件类型 仅支付宝支持且在支付宝平台必填
fileType?: 'image' | 'video' | 'audio'
// 成功状态码
statusCode?: number
// 文件状态的key
statusKey?: string
// 自定义上传方法
uploadMethod?: UploadMethod
// 上传成功回调
onSuccess?: (res: UniApp.UploadFileSuccessCallbackResult, file: UploadFileItem, formData: Record<string, any>) => void
// 上传失败回调
onError?: (res: UniApp.GeneralCallbackResult, file: UploadFileItem, formData: Record<string, any>) => void
// 上传进度回调
onProgress?: (res: UniApp.OnProgressUpdateResult, file: UploadFileItem) => void
// 是否自动中断之前的上传任务
abortPrevious?: boolean
// 根据文件拓展名过滤(H5支持全部类型过滤,微信小程序支持all和file时过滤,其余平台不支持)
extension?: string[]
}
export function useUpload(): UseUploadReturn {
let currentTask: UniApp.UploadTask | null = null
// 中断上传
const abort = (task?: UniApp.UploadTask) => {
if (task) {
task.abort()
} else if (currentTask) {
currentTask.abort()
currentTask = null
}
}
/**
* 默认上传方法
*/
const defaultUpload: UploadMethod = (file, formData, options) => {
// 如果配置了自动中断,则中断之前的上传任务
if (options.abortPrevious) {
abort()
}
const uploadTask = uni.uploadFile({
url: options.action,
header: options.header,
name: options.name,
fileName: options.name,
fileType: options.fileType,
formData,
filePath: file.url,
success(res) {
if (res.statusCode === options.statusCode) {
// 上传成功
options.onSuccess(res, file, formData)
} else {
// 上传失败
options.onError({ ...res, errMsg: res.errMsg || '' }, file, formData)
}
},
fail(err) {
// 上传失败
options.onError(err, file, formData)
}
})
currentTask = uploadTask
// 获取当前文件加载的百分比
uploadTask.onProgressUpdate((res) => {
options.onProgress(res, file)
})
// 返回上传任务实例,让外部可以控制上传过程
return uploadTask
}
/**
* 开始上传文件
*/
const startUpload = (file: UploadFileItem, options: UseUploadOptions) => {
const {
uploadMethod,
formData = {},
action,
name = 'file',
header = {},
fileType = 'image',
statusCode = 200,
statusKey = 'status',
abortPrevious = false
} = options
// 设置上传中状态
file[statusKey] = UPLOAD_STATUS.LOADING
const uploadOptions = {
action,
header,
name,
fileName: name,
fileType,
statusCode,
abortPrevious,
onSuccess: (res: UniApp.UploadFileSuccessCallbackResult, file: UploadFileItem, formData: Record<string, any>) => {
// 更新文件状态
file[statusKey] = UPLOAD_STATUS.SUCCESS
currentTask = null
options.onSuccess?.(res, file, formData)
},
onError: (error: UniApp.GeneralCallbackResult, file: UploadFileItem, formData: Record<string, any>) => {
// 更新文件状态和错误信息
file[statusKey] = UPLOAD_STATUS.FAIL
file.error = error.errMsg
currentTask = null
options.onError?.(error, file, formData)
},
onProgress: (res: UniApp.OnProgressUpdateResult, file: UploadFileItem) => {
// 更新上传进度
file.percent = res.progress
options.onProgress?.(res, file)
}
}
// 返回上传任务实例,支持外部获取uploadTask进行操作
if (isFunction(uploadMethod)) {
return uploadMethod(file, formData, uploadOptions)
} else {
return defaultUpload(file, formData, uploadOptions)
}
}
/**
* 格式化图片信息
*/
function formatImage(res: UniApp.ChooseImageSuccessCallbackResult): ChooseFile[] {
// #ifdef MP-DINGTALK
// 钉钉文件在files中
res.tempFiles = isDef((res as any).files) ? (res as any).files : res.tempFiles
// #endif
if (isArray(res.tempFiles)) {
return res.tempFiles.map((item: any) => ({
path: item.path || '',
name: item.name || '',
size: item.size,
type: 'image',
thumb: item.path || ''
}))
}
return [
{
path: (res.tempFiles as any).path || '',
name: (res.tempFiles as any).name || '',
size: (res.tempFiles as any).size,
type: 'image',
thumb: (res.tempFiles as any).path || ''
}
]
}
/**
* 格式化视频信息
*/
function formatVideo(res: UniApp.ChooseVideoSuccess): ChooseFile[] {
return [
{
path: res.tempFilePath || (res as any).filePath || '',
name: res.name || '',
size: res.size,
type: 'video',
thumb: (res as any).thumbTempFilePath || '',
duration: res.duration
}
]
}
/**
* 格式化媒体信息
*/
function formatMedia(res: UniApp.ChooseMediaSuccessCallbackResult): ChooseFile[] {
return res.tempFiles.map((item) => ({
type: item.fileType,
path: item.tempFilePath,
thumb: item.fileType === 'video' ? item.thumbTempFilePath : item.tempFilePath,
size: item.size,
duration: item.duration
}))
}
/**
* 选择文件
*/
function chooseFile({
multiple,
sizeType,
sourceType,
maxCount,
accept,
compressed,
maxDuration,
camera,
extension
}: ChooseFileOption): Promise<ChooseFile[]> {
return new Promise((resolve, reject) => {
switch (accept) {
case 'image':
// #ifdef MP-WEIXIN
uni.chooseMedia({
count: multiple ? maxCount : 1,
mediaType: ['image'],
sourceType,
sizeType,
camera,
success: (res) => resolve(formatMedia(res)),
fail: reject
})
// #endif
// #ifndef MP-WEIXIN
uni.chooseImage({
count: multiple ? maxCount : 1,
sizeType,
sourceType,
// #ifdef H5
extension,
// #endif
success: (res) => resolve(formatImage(res)),
fail: reject
})
// #endif
break
case 'video':
// #ifdef MP-WEIXIN
uni.chooseMedia({
count: multiple ? maxCount : 1,
mediaType: ['video'],
sourceType,
camera,
maxDuration,
success: (res) => resolve(formatMedia(res)),
fail: reject
})
// #endif
// #ifndef MP-WEIXIN
uni.chooseVideo({
sourceType,
compressed,
maxDuration,
camera,
// #ifdef H5
extension,
// #endif
success: (res) => resolve(formatVideo(res)),
fail: reject
})
// #endif
break
// #ifdef MP-WEIXIN
case 'media':
uni.chooseMedia({
count: multiple ? maxCount : 1,
sourceType,
sizeType,
camera,
maxDuration,
success: (res) => resolve(formatMedia(res)),
fail: reject
})
break
case 'file':
uni.chooseMessageFile({
count: multiple ? (isDef(maxCount) ? maxCount : 100) : 1,
type: accept,
extension,
success: (res) => resolve(res.tempFiles),
fail: reject
})
break
// #endif
case 'all':
// #ifdef H5
uni.chooseFile({
count: multiple ? maxCount : 1,
type: accept,
extension,
success: (res) => resolve(res.tempFiles as ChooseFile[]),
fail: reject
})
// #endif
// #ifdef MP-WEIXIN
uni.chooseMessageFile({
count: multiple ? Number(maxCount) : 1,
type: accept,
extension,
success: (res) => resolve(res.tempFiles),
fail: reject
})
// #endif
break
default:
// #ifdef MP-WEIXIN
uni.chooseMedia({
count: multiple ? maxCount : 1,
mediaType: ['image'],
sourceType,
sizeType,
camera,
success: (res) => resolve(formatMedia(res)),
fail: reject
})
// #endif
// #ifndef MP-WEIXIN
uni.chooseImage({
count: multiple ? maxCount : 1,
sizeType,
sourceType,
// #ifdef H5
extension,
// #endif
success: (res) => resolve(formatImage(res)),
fail: reject
})
// #endif
break
}
})
}
return {
startUpload,
abort,
UPLOAD_STATUS,
chooseFile
}
}