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([])
|
4c54ad5d
刘淇
转工单 选择是 传紧急程度和...
|
20
21
|
// 确保 rawImgList 响应式对象的初始值也是空数组
// const rawImgList = ref([]);
|
7b1f488f
刘淇
封装下图片上传
|
22
23
|
/**
|
dacff5e3
刘淇
养护员退回
|
24
25
26
27
28
29
30
31
32
33
34
35
36
|
* 新增:清空所有图片
* 功能:重置图片列表为空,并触发表单字段校验(如果有表单Ref)
*/
const clearImgs = () => {
imgList.value = [];
// 优化:先判断 formRef 存在,再判断 formRef.value 存在
if (defaultConfig.formRef && defaultConfig.formRef.value && defaultConfig.fieldName) {
defaultConfig.formRef.value.validateField(defaultConfig.fieldName);
}
};
/**
|
7b1f488f
刘淇
封装下图片上传
|
37
38
|
* 删除图片
*/
|
c7df828a
刘淇
快速工单 样式优化
|
39
|
const deleteImg = (event) => {
|
dacff5e3
刘淇
养护员退回
|
40
41
42
43
44
45
46
47
48
49
|
const index = Number(event.index);
if (isNaN(index) || index < 0 || index >= imgList.value.length) return;
imgList.value.splice(index, 1);
// 修复:先判断 formRef 存在,再访问 value
if (defaultConfig.formRef && defaultConfig.formRef.value && defaultConfig.fieldName) {
defaultConfig.formRef.value.validateField(defaultConfig.fieldName);
}
uni.showToast({ title: '图片删除成功', icon: 'success' });
};
|
7b1f488f
刘淇
封装下图片上传
|
50
51
|
/**
|
c7df828a
刘淇
快速工单 样式优化
|
52
|
* 上传图片(适配u-upload的file格式)
|
7b1f488f
刘淇
封装下图片上传
|
53
|
*/
|
c7df828a
刘淇
快速工单 样式优化
|
54
55
56
57
58
59
60
61
62
63
64
65
|
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
刘淇
封装下图片上传
|
66
67
|
const targetImgList = imgList.value
|
c7df828a
刘淇
快速工单 样式优化
|
68
69
|
// 校验最大数量
if (targetImgList.length + validFiles.length > defaultConfig.maxCount) {
|
7b1f488f
刘淇
封装下图片上传
|
70
71
72
73
|
uni.showToast({ title: `最多只能上传${defaultConfig.maxCount}张图片`, icon: 'none' })
return
}
|
c7df828a
刘淇
快速工单 样式优化
|
74
75
76
77
78
79
80
81
|
// 核心修复:转换为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
刘淇
封装下图片上传
|
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
}))
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
刘淇
快速工单 样式优化
|
96
97
|
url: url,
status: 'success',
|
7b1f488f
刘淇
封装下图片上传
|
98
|
message: '',
|
c7df828a
刘淇
快速工单 样式优化
|
99
100
|
name: validFiles[index].name || '',
size: validFiles[index].size || 0
|
7b1f488f
刘淇
封装下图片上传
|
101
102
103
104
105
|
})
}
})
// 处理上传失败的图片
|
c7df828a
刘淇
快速工单 样式优化
|
106
107
108
|
if (uploadResultUrls.length < validFiles.length) {
const failCount = validFiles.length - uploadResultUrls.length
for (let i = uploadResultUrls.length; i < validFiles.length; i++) {
|
7b1f488f
刘淇
封装下图片上传
|
109
110
|
if (targetImgList[startIndex + i]) {
targetImgList.splice(startIndex + i, 1, {
|
c7df828a
刘淇
快速工单 样式优化
|
111
112
113
114
115
|
url: validFiles[i].url,
status: 'failed',
message: '上传失败',
name: validFiles[i].name || '',
size: validFiles[i].size || 0
|
7b1f488f
刘淇
封装下图片上传
|
116
117
118
119
120
|
})
}
}
uni.showToast({ title: `成功上传${uploadResultUrls.length}张,失败${failCount}张`, icon: 'none' })
} else {
|
c7df828a
刘淇
快速工单 样式优化
|
121
|
uni.showToast({ title: `成功上传${validFiles.length}张图片`, icon: 'success' })
|
7b1f488f
刘淇
封装下图片上传
|
122
123
124
|
}
// 上传完成后校验
|
dacff5e3
刘淇
养护员退回
|
125
126
127
|
if (defaultConfig.formRef && defaultConfig.formRef.value && defaultConfig.fieldName) {
defaultConfig.formRef.value.validateField(defaultConfig.fieldName);
}
|
7b1f488f
刘淇
封装下图片上传
|
128
129
130
|
} catch (err) {
console.error(`【${defaultConfig.fieldName}】图片上传失败:`, err)
// 标记所有上传失败
|
c7df828a
刘淇
快速工单 样式优化
|
131
|
for (let i = 0; i < validFiles.length; i++) {
|
7b1f488f
刘淇
封装下图片上传
|
132
133
|
if (targetImgList[startIndex + i]) {
targetImgList.splice(startIndex + i, 1, {
|
c7df828a
刘淇
快速工单 样式优化
|
134
135
136
137
138
|
url: validFiles[i].url,
status: 'failed',
message: '上传失败',
name: validFiles[i].name || '',
size: validFiles[i].size || 0
|
7b1f488f
刘淇
封装下图片上传
|
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
})
}
}
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
刘淇
快速工单 样式优化
|
162
|
validator: (rule, value, callback) => {
|
7b1f488f
刘淇
封装下图片上传
|
163
164
165
166
167
|
const hasSuccessImg = imgList.value.some(item => item.status === 'success')
hasSuccessImg ? callback() : callback(new Error(`请上传至少1张${defaultConfig.uploadText.replace('选择', '')}`))
}
}
|
dacff5e3
刘淇
养护员退回
|
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
|
/**
* 新增:批量设置图片列表(图片回显核心方法,替代业务页面的setUploadImgsList)
* @param imgUrls 图片URL数组(如:['https://xxx.jpg', 'https://yyy.png'])
* 功能:将纯URL数组转换为u-upload兼容格式,实现静默回显,无数据时不提示
*/
const setImgList = (imgUrls = []) => {
// 容错处理:校验参数有效性,非数组/空数组直接重置
if (!Array.isArray(imgUrls) || imgUrls.length === 0) {
imgList.value = []
return
}
// 转换为u-upload兼容的格式(status: success 标记为已成功上传,可正常显示/删除)
const formatImgList = imgUrls.map(url => ({
url: url,
status: 'success', // 关键:标记为成功状态,兼容后续删除/校验逻辑
message: '',
name: url.substring(url.lastIndexOf('/') + 1), // 从URL截取文件名,优化显示
size: 0 // 历史图片无大小信息,默认0不影响使用
}))
// 额外优化:限制回显数量不超过maxCount,避免异常
const finalImgList = formatImgList.slice(0, defaultConfig.maxCount)
imgList.value = finalImgList
}
|
7b1f488f
刘淇
封装下图片上传
|
194
|
return {
|
dacff5e3
刘淇
养护员退回
|
195
|
imgList: imgList, // 核心修复:返回纯数组(解除响应式代理)
|
c7df828a
刘淇
快速工单 样式优化
|
196
|
rawImgList: imgList, // 保留响应式引用(内部使用)
|
7b1f488f
刘淇
封装下图片上传
|
197
198
|
uploadImgs,
deleteImg,
|
dacff5e3
刘淇
养护员退回
|
199
200
|
clearImgs,
setImgList,
|
7b1f488f
刘淇
封装下图片上传
|
201
202
203
204
205
|
getSuccessImgUrls,
imgValidateRule,
uploadConfig: defaultConfig
}
}
|