c7df828a
刘淇
快速工单 样式优化
|
1
|
import { ref } from 'vue'
|
7b1f488f
刘淇
封装下图片上传
|
2
|
import { uploadImages } from '@/common/utils/upload'
|
7b1f488f
刘淇
封装下图片上传
|
3
4
|
/**
|
c7df828a
刘淇
快速工单 样式优化
|
5
|
* 图片上传组合式函数(兼容非TS环境,纯数组格式)
|
7b1f488f
刘淇
封装下图片上传
|
6
7
8
|
* @param config 上传配置
* @returns 上传相关方法和状态
*/
|
c7df828a
刘淇
快速工单 样式优化
|
9
|
export function useUploadImgs(config) {
|
7b1f488f
刘淇
封装下图片上传
|
10
11
12
13
|
// 默认配置
const defaultConfig = {
maxCount: 3,
uploadText: '选择图片',
|
c7df828a
刘淇
快速工单 样式优化
|
14
|
sizeType: ['compressed'],
|
7b1f488f
刘淇
封装下图片上传
|
15
16
17
|
...config
}
|
c7df828a
刘淇
快速工单 样式优化
|
18
19
|
// 核心修复:初始化为纯数组,且格式适配u-upload
const imgList = ref([])
|
7b1f488f
刘淇
封装下图片上传
|
20
21
22
23
|
/**
* 删除图片
*/
|
c7df828a
刘淇
快速工单 样式优化
|
24
25
26
27
28
29
|
const deleteImg = (event) => {
// 确保index是有效数字
const index = Number(event.index)
if (isNaN(index) || index < 0 || index >= imgList.value.length) return
imgList.value.splice(index, 1)
|
7b1f488f
刘淇
封装下图片上传
|
30
31
32
33
34
35
|
// 删除后重新校验
defaultConfig.formRef.value?.validateField(defaultConfig.fieldName)
uni.showToast({ title: '图片删除成功', icon: 'success' })
}
/**
|
c7df828a
刘淇
快速工单 样式优化
|
36
|
* 上传图片(适配u-upload的file格式)
|
7b1f488f
刘淇
封装下图片上传
|
37
|
*/
|
c7df828a
刘淇
快速工单 样式优化
|
38
39
40
41
42
43
44
45
46
47
48
49
|
const uploadImgs = async (event) => {
// 核心修复:标准化file数据格式
const rawFile = event.file || {}
const fileList = Array.isArray(rawFile) ? rawFile : [rawFile]
// 过滤无效文件
const validFiles = fileList.filter(file => file && file.url)
if (validFiles.length === 0) {
uni.showToast({ title: '请选择有效图片', icon: 'none' })
return
}
|
7b1f488f
刘淇
封装下图片上传
|
50
51
|
const targetImgList = imgList.value
|
c7df828a
刘淇
快速工单 样式优化
|
52
53
|
// 校验最大数量
if (targetImgList.length + validFiles.length > defaultConfig.maxCount) {
|
7b1f488f
刘淇
封装下图片上传
|
54
55
56
57
|
uni.showToast({ title: `最多只能上传${defaultConfig.maxCount}张图片`, icon: 'none' })
return
}
|
c7df828a
刘淇
快速工单 样式优化
|
58
59
60
61
62
63
64
65
|
// 核心修复:转换为u-upload兼容的格式
const filePaths = validFiles.map(item => item.url)
const tempItems = validFiles.map(item => ({
url: item.url,
status: 'uploading',
message: '上传中',
name: item.name || '',
size: item.size || 0
|
7b1f488f
刘淇
封装下图片上传
|
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
}))
const startIndex = targetImgList.length
targetImgList.push(...tempItems)
try {
const uploadResultUrls = await uploadImages({
filePaths: filePaths,
ignoreError: true
})
// 更新上传成功的图片
uploadResultUrls.forEach((url, index) => {
if (targetImgList[startIndex + index]) {
targetImgList.splice(startIndex + index, 1, {
|
c7df828a
刘淇
快速工单 样式优化
|
80
81
|
url: url,
status: 'success',
|
7b1f488f
刘淇
封装下图片上传
|
82
|
message: '',
|
c7df828a
刘淇
快速工单 样式优化
|
83
84
|
name: validFiles[index].name || '',
size: validFiles[index].size || 0
|
7b1f488f
刘淇
封装下图片上传
|
85
86
87
88
89
|
})
}
})
// 处理上传失败的图片
|
c7df828a
刘淇
快速工单 样式优化
|
90
91
92
|
if (uploadResultUrls.length < validFiles.length) {
const failCount = validFiles.length - uploadResultUrls.length
for (let i = uploadResultUrls.length; i < validFiles.length; i++) {
|
7b1f488f
刘淇
封装下图片上传
|
93
94
|
if (targetImgList[startIndex + i]) {
targetImgList.splice(startIndex + i, 1, {
|
c7df828a
刘淇
快速工单 样式优化
|
95
96
97
98
99
|
url: validFiles[i].url,
status: 'failed',
message: '上传失败',
name: validFiles[i].name || '',
size: validFiles[i].size || 0
|
7b1f488f
刘淇
封装下图片上传
|
100
101
102
103
104
|
})
}
}
uni.showToast({ title: `成功上传${uploadResultUrls.length}张,失败${failCount}张`, icon: 'none' })
} else {
|
c7df828a
刘淇
快速工单 样式优化
|
105
|
uni.showToast({ title: `成功上传${validFiles.length}张图片`, icon: 'success' })
|
7b1f488f
刘淇
封装下图片上传
|
106
107
108
109
110
111
112
|
}
// 上传完成后校验
defaultConfig.formRef.value?.validateField(defaultConfig.fieldName)
} catch (err) {
console.error(`【${defaultConfig.fieldName}】图片上传失败:`, err)
// 标记所有上传失败
|
c7df828a
刘淇
快速工单 样式优化
|
113
|
for (let i = 0; i < validFiles.length; i++) {
|
7b1f488f
刘淇
封装下图片上传
|
114
115
|
if (targetImgList[startIndex + i]) {
targetImgList.splice(startIndex + i, 1, {
|
c7df828a
刘淇
快速工单 样式优化
|
116
117
118
119
120
|
url: validFiles[i].url,
status: 'failed',
message: '上传失败',
name: validFiles[i].name || '',
size: validFiles[i].size || 0
|
7b1f488f
刘淇
封装下图片上传
|
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
})
}
}
uni.showToast({ title: '图片上传失败,请重试', icon: 'none' })
// 上传失败后校验
defaultConfig.formRef.value?.validateField(defaultConfig.fieldName)
}
}
/**
* 获取成功上传的图片URL列表
*/
const getSuccessImgUrls = () => {
return imgList.value.filter(item => item.status === 'success').map(item => item.url)
}
/**
* 图片校验规则(供表单使用)
*/
const imgValidateRule = {
required: true,
message: `请上传${defaultConfig.uploadText.replace('选择', '')}`,
trigger: 'change',
|
c7df828a
刘淇
快速工单 样式优化
|
144
|
validator: (rule, value, callback) => {
|
7b1f488f
刘淇
封装下图片上传
|
145
146
147
148
149
150
|
const hasSuccessImg = imgList.value.some(item => item.status === 'success')
hasSuccessImg ? callback() : callback(new Error(`请上传至少1张${defaultConfig.uploadText.replace('选择', '')}`))
}
}
return {
|
c7df828a
刘淇
快速工单 样式优化
|
151
152
|
imgList: imgList.value, // 核心修复:返回纯数组(解除响应式代理)
rawImgList: imgList, // 保留响应式引用(内部使用)
|
7b1f488f
刘淇
封装下图片上传
|
153
154
155
156
157
158
159
|
uploadImgs,
deleteImg,
getSuccessImgUrls,
imgValidateRule,
uploadConfig: defaultConfig
}
}
|