|
@@ -180,7 +180,7 @@
|
|
|
</view>
|
|
</view>
|
|
|
<view class="picker-options">
|
|
<view class="picker-options">
|
|
|
<view class="picker-option"
|
|
<view class="picker-option"
|
|
|
- v-for="category in dictDataOptions.agricultural_category"
|
|
|
|
|
|
|
+ v-for="category in (dictDataOptions.agricultural_category || [])"
|
|
|
:key="category.dictCode"
|
|
:key="category.dictCode"
|
|
|
@click="selectCategory(category)"
|
|
@click="selectCategory(category)"
|
|
|
:class="{ 'active': category.dictValue == formData.categoryId }">
|
|
:class="{ 'active': category.dictValue == formData.categoryId }">
|
|
@@ -198,7 +198,7 @@
|
|
|
</view>
|
|
</view>
|
|
|
<view class="picker-options">
|
|
<view class="picker-options">
|
|
|
<view class="picker-option"
|
|
<view class="picker-option"
|
|
|
- v-for="unit in dictDataOptions.agricultural_unit"
|
|
|
|
|
|
|
+ v-for="unit in (dictDataOptions.agricultural_unit || [])"
|
|
|
:key="unit.dictCode"
|
|
:key="unit.dictCode"
|
|
|
@click="selectUnit(unit)"
|
|
@click="selectUnit(unit)"
|
|
|
:class="{ 'active': unit.dictValue == formData.unit }">
|
|
:class="{ 'active': unit.dictValue == formData.unit }">
|
|
@@ -258,10 +258,12 @@
|
|
|
const currentUserInfo = storage.getUserInfo()
|
|
const currentUserInfo = storage.getUserInfo()
|
|
|
|
|
|
|
|
// 计算属性:dictDataOptions
|
|
// 计算属性:dictDataOptions
|
|
|
- const dictDataOptions = computed(() => dictData.value)
|
|
|
|
|
|
|
+ const dictDataOptions = computed(() => dictData)
|
|
|
|
|
|
|
|
// onLoad 替换为 onMounted + getCurrentPages
|
|
// onLoad 替换为 onMounted + getCurrentPages
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
|
|
+ console.log("dictDataOptions",dictDataOptions.value);
|
|
|
|
|
+
|
|
|
const pages = getCurrentPages()
|
|
const pages = getCurrentPages()
|
|
|
const currentPage = pages[pages.length - 1]
|
|
const currentPage = pages[pages.length - 1]
|
|
|
const options = currentPage.options
|
|
const options = currentPage.options
|
|
@@ -351,165 +353,275 @@
|
|
|
|
|
|
|
|
// 获取字典标签
|
|
// 获取字典标签
|
|
|
const getDictLabel = (dictKey, value) => {
|
|
const getDictLabel = (dictKey, value) => {
|
|
|
- if (!dictData.value || !dictData.value[dictKey]) {
|
|
|
|
|
|
|
+ if (!dictData || !dictData[dictKey]) {
|
|
|
return ''
|
|
return ''
|
|
|
}
|
|
}
|
|
|
- const list = dictData.value[dictKey] || []
|
|
|
|
|
|
|
+ const list = dictData[dictKey] || []
|
|
|
const item = list.find(u => u.dictValue == value)
|
|
const item = list.find(u => u.dictValue == value)
|
|
|
return item ? item.dictLabel : ''
|
|
return item ? item.dictLabel : ''
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 选择图片
|
|
|
|
|
|
|
+ // 选择图片(优化跨平台兼容性)
|
|
|
const chooseImage = () => {
|
|
const chooseImage = () => {
|
|
|
uni.chooseImage({
|
|
uni.chooseImage({
|
|
|
count: 6 - formData.images.length,
|
|
count: 6 - formData.images.length,
|
|
|
- sizeType: ['original', 'compressed'],
|
|
|
|
|
- sourceType: ['album', 'camera'],
|
|
|
|
|
- success: (res) => {
|
|
|
|
|
- console.log('选择图片成功:', res);
|
|
|
|
|
-
|
|
|
|
|
- // 验证文件类型和大小
|
|
|
|
|
- const validFiles = [];
|
|
|
|
|
- const invalidFiles = [];
|
|
|
|
|
- const maxSize = 5 * 1024 * 1024; // 5MB 最大限制
|
|
|
|
|
-
|
|
|
|
|
- // 检查每个文件
|
|
|
|
|
- res.tempFiles.forEach((file, index) => {
|
|
|
|
|
- // 检查文件类型
|
|
|
|
|
- const isImage = /\.(jpg|jpeg|png|gif)$/i.test(file.name);
|
|
|
|
|
- // 检查文件大小
|
|
|
|
|
- const isValidSize = file.size <= maxSize;
|
|
|
|
|
-
|
|
|
|
|
- if (isImage && isValidSize) {
|
|
|
|
|
- validFiles.push(res.tempFilePaths[index]);
|
|
|
|
|
- } else {
|
|
|
|
|
- invalidFiles.push({
|
|
|
|
|
- path: file.path,
|
|
|
|
|
- size: file.size,
|
|
|
|
|
- reason: !isImage ? '文件格式不支持' : '文件大于5MB'
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 显示无效文件提示
|
|
|
|
|
- if (invalidFiles.length > 0) {
|
|
|
|
|
- uni.showToast({
|
|
|
|
|
- title: `${invalidFiles.length}个文件无效,请检查格式和大小`,
|
|
|
|
|
- icon: 'none',
|
|
|
|
|
- duration: 2000
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 如果有有效文件,则上传
|
|
|
|
|
- if (validFiles.length > 0) {
|
|
|
|
|
- uploadImages(validFiles)
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- fail: (err) => {
|
|
|
|
|
- console.error('选择图片失败:', err)
|
|
|
|
|
- uni.showToast({
|
|
|
|
|
- title: '选择图片失败',
|
|
|
|
|
- icon: 'none'
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ sizeType: ['original', 'compressed'],
|
|
|
|
|
+ sourceType: ['album', 'camera'],
|
|
|
|
|
+ success: (res) => {
|
|
|
|
|
+ console.log('选择图片成功:', res);
|
|
|
|
|
+ console.log('tempFiles:', res.tempFiles);
|
|
|
|
|
+ console.log('tempFilePaths:', res.tempFilePaths);
|
|
|
|
|
+
|
|
|
|
|
+ // 验证文件类型和大小
|
|
|
|
|
+ const validFiles = [];
|
|
|
|
|
+ const invalidFiles = [];
|
|
|
|
|
+ const maxSize = 5 * 1024 * 1024; // 5MB 最大限制
|
|
|
|
|
+
|
|
|
|
|
+ // 兼容不同平台的文件信息获取方式
|
|
|
|
|
+ if (res.tempFiles && res.tempFiles.length > 0) {
|
|
|
|
|
+ // 检查每个文件
|
|
|
|
|
+ res.tempFiles.forEach((file, index) => {
|
|
|
|
|
+ console.log(`文件 ${index}:`, file);
|
|
|
|
|
+
|
|
|
|
|
+ // 获取文件路径
|
|
|
|
|
+ const filePath = res.tempFilePaths[index];
|
|
|
|
|
+
|
|
|
|
|
+ // 获取文件名(兼容不同平台)
|
|
|
|
|
+ let fileName = '';
|
|
|
|
|
+ if (file.name) {
|
|
|
|
|
+ fileName = file.name;
|
|
|
|
|
+ } else if (file.path) {
|
|
|
|
|
+ // 从路径中提取文件名
|
|
|
|
|
+ fileName = file.path.split('/').pop();
|
|
|
|
|
+ } else if (filePath) {
|
|
|
|
|
+ fileName = filePath.split('/').pop();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ console.log(`文件名: ${fileName}, 大小: ${file.size}`);
|
|
|
|
|
+
|
|
|
|
|
+ // 检查文件类型(兼容没有扩展名的情况)
|
|
|
|
|
+ let isImage = true;
|
|
|
|
|
+ if (fileName) {
|
|
|
|
|
+ isImage = /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(fileName);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 检查文件大小
|
|
|
|
|
+ const fileSize = file.size || 0;
|
|
|
|
|
+ const isValidSize = fileSize <= maxSize;
|
|
|
|
|
+
|
|
|
|
|
+ if (isImage && isValidSize) {
|
|
|
|
|
+ validFiles.push(filePath);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ invalidFiles.push({
|
|
|
|
|
+ path: filePath,
|
|
|
|
|
+ size: fileSize,
|
|
|
|
|
+ name: fileName,
|
|
|
|
|
+ reason: !isImage ? '文件格式不支持' : `文件大于5MB (${(fileSize / 1024 / 1024).toFixed(2)}MB)`
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果没有 tempFiles,直接使用 tempFilePaths(某些平台可能不返回详细信息)
|
|
|
|
|
+ console.warn('未获取到 tempFiles,直接使用 tempFilePaths');
|
|
|
|
|
+ res.tempFilePaths.forEach(path => {
|
|
|
|
|
+ validFiles.push(path);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ console.log('有效文件:', validFiles);
|
|
|
|
|
+ console.log('无效文件:', invalidFiles);
|
|
|
|
|
+
|
|
|
|
|
+ // 显示无效文件提示
|
|
|
|
|
+ if (invalidFiles.length > 0) {
|
|
|
|
|
+ const reasons = invalidFiles.map(f => `${f.name}: ${f.reason}`).join('\n');
|
|
|
|
|
+ uni.showModal({
|
|
|
|
|
+ title: '部分文件无效',
|
|
|
|
|
+ content: `${invalidFiles.length}个文件无效:\n${reasons}`,
|
|
|
|
|
+ showCancel: false
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果有有效文件,则上传
|
|
|
|
|
+ if (validFiles.length > 0) {
|
|
|
|
|
+ uploadImages(validFiles);
|
|
|
|
|
+ } else if (invalidFiles.length > 0) {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '没有可上传的文件',
|
|
|
|
|
+ icon: 'none',
|
|
|
|
|
+ duration: 2000
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ fail: (err) => {
|
|
|
|
|
+ console.error('选择图片失败:', err);
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '选择图片失败',
|
|
|
|
|
+ icon: 'none',
|
|
|
|
|
+ duration: 2000
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 上传图片到服务器
|
|
|
|
|
|
|
+ // 上传图片到服务器(优化跨平台兼容性)
|
|
|
const uploadImages = (tempFilePaths) => {
|
|
const uploadImages = (tempFilePaths) => {
|
|
|
- uni.showLoading({
|
|
|
|
|
- title: '上传中...',
|
|
|
|
|
- mask: true
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 上传成功的图片计数
|
|
|
|
|
- let successCount = 0;
|
|
|
|
|
- let failCount = 0;
|
|
|
|
|
- const totalFiles = tempFilePaths.length;
|
|
|
|
|
- const newImages = [];
|
|
|
|
|
-
|
|
|
|
|
- // 遍历处理每张图片
|
|
|
|
|
- tempFilePaths.forEach((path, index) => {
|
|
|
|
|
- // 调用上传API
|
|
|
|
|
- uni.uploadFile({
|
|
|
|
|
- // url: api.serve + '/base/tasks/uploadTaskImage',
|
|
|
|
|
- url: api.serve + '/file/upload',
|
|
|
|
|
- filePath: path,
|
|
|
|
|
- name: 'file', // 文件参数名称,需要与后端接口匹配
|
|
|
|
|
- formData: {
|
|
|
|
|
- type: 'task', // 标识文件类型,用于后端区分不同业务的文件
|
|
|
|
|
- // directory: '/opt/app/nongxiaoyu/uploadImage' // 指定保存目录
|
|
|
|
|
- },
|
|
|
|
|
- header: {
|
|
|
|
|
- 'Authorization': `Bearer ${storage.getAccessToken()}`
|
|
|
|
|
- },
|
|
|
|
|
- success: (res) => {
|
|
|
|
|
- try {
|
|
|
|
|
- const response = JSON.parse(res.data);
|
|
|
|
|
|
|
+ uni.showLoading({
|
|
|
|
|
+ title: '上传中...',
|
|
|
|
|
+ mask: true
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 上传成功的图片计数
|
|
|
|
|
+ let successCount = 0;
|
|
|
|
|
+ let failCount = 0;
|
|
|
|
|
+ const totalFiles = tempFilePaths.length;
|
|
|
|
|
+ const newImages = [];
|
|
|
|
|
+
|
|
|
|
|
+ // 遍历处理每张图片
|
|
|
|
|
+ tempFilePaths.forEach((path, index) => {
|
|
|
|
|
+ // 调用上传API
|
|
|
|
|
+ uni.uploadFile({
|
|
|
|
|
+ url: api.serve + '/file/upload',
|
|
|
|
|
+ filePath: path,
|
|
|
|
|
+ name: 'file',
|
|
|
|
|
+ formData: {
|
|
|
|
|
+ type: 'task'
|
|
|
|
|
+ },
|
|
|
|
|
+ header: {
|
|
|
|
|
+ 'Authorization': `Bearer ${storage.getAccessToken()}`
|
|
|
|
|
+ },
|
|
|
|
|
+ success: (res) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ console.log('上传原始响应:', res);
|
|
|
|
|
+ console.log('响应数据类型:', typeof res.data);
|
|
|
|
|
+ console.log('响应状态码:', res.statusCode);
|
|
|
|
|
+
|
|
|
|
|
+ let response;
|
|
|
|
|
+
|
|
|
|
|
+ // 兼容不同平台的响应格式
|
|
|
|
|
+ if (typeof res.data === 'string') {
|
|
|
|
|
+ // H5 端返回字符串,需要解析
|
|
|
|
|
+ response = JSON.parse(res.data);
|
|
|
|
|
+ } else if (typeof res.data === 'object') {
|
|
|
|
|
+ // Android/鸿蒙端可能直接返回对象
|
|
|
|
|
+ response = res.data;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ throw new Error('未知的响应格式');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ console.log('解析后的响应:', response);
|
|
|
|
|
+
|
|
|
|
|
+ // 检查响应是否成功
|
|
|
|
|
+ if (response.code === 200 || response.code === '200') {
|
|
|
|
|
+ // 兼容不同的数据结构
|
|
|
|
|
+ let imageUrl = '';
|
|
|
|
|
+
|
|
|
|
|
+ // 情况1: response.data 是字符串(直接是URL)
|
|
|
|
|
+ if (typeof response.data === 'string') {
|
|
|
|
|
+ imageUrl = response.data;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 情况2: response.data 是对象,包含 url 字段
|
|
|
|
|
+ else if (response.data && response.data.url) {
|
|
|
|
|
+ imageUrl = response.data.url;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 情况3: response 直接包含 url 字段
|
|
|
|
|
+ else if (response.url) {
|
|
|
|
|
+ imageUrl = response.url;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 情况4: response.data 是数组
|
|
|
|
|
+ else if (Array.isArray(response.data) && response.data.length > 0) {
|
|
|
|
|
+ imageUrl = response.data[0].url || response.data[0];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (imageUrl) {
|
|
|
|
|
+ console.log('上传成功,图片URL:', imageUrl);
|
|
|
|
|
+
|
|
|
|
|
+ // 上传成功,将图片信息添加到数组
|
|
|
|
|
+ newImages.push({
|
|
|
|
|
+ url: imageUrl,
|
|
|
|
|
+ path: path,
|
|
|
|
|
+ status: 'success',
|
|
|
|
|
+ fileName: (response.data && response.data.fileName) || ''
|
|
|
|
|
+ });
|
|
|
|
|
+ successCount++;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.error('无法从响应中提取图片URL:', response);
|
|
|
|
|
+ failCount++;
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '图片URL解析失败',
|
|
|
|
|
+ icon: 'none',
|
|
|
|
|
+ duration: 2000
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ failCount++;
|
|
|
|
|
+ console.error('上传失败,错误信息:', response.msg || response.message);
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: response.msg || response.message || '上传失败',
|
|
|
|
|
+ icon: 'none',
|
|
|
|
|
+ duration: 2000
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ failCount++;
|
|
|
|
|
+ console.error('解析响应失败:', e);
|
|
|
|
|
+ console.error('原始响应数据:', res.data);
|
|
|
uni.showToast({
|
|
uni.showToast({
|
|
|
- title: `返回: ${response.data}`,
|
|
|
|
|
- icon: 'none',
|
|
|
|
|
|
|
+ title: `解析失败: ${e.message}`,
|
|
|
|
|
+ icon: 'none',
|
|
|
|
|
+ duration: 2000
|
|
|
});
|
|
});
|
|
|
- if (response.code === 200) {
|
|
|
|
|
- // 获取返回的URL
|
|
|
|
|
- const imageUrl = response.data.url;
|
|
|
|
|
- console.log('上传成功,返回的图片URL:', imageUrl);
|
|
|
|
|
-
|
|
|
|
|
- // 上传成功,将图片信息添加到数组
|
|
|
|
|
- newImages.push({
|
|
|
|
|
- url: imageUrl, // 保存原始URL,在显示时会通过getImageUrl方法处理
|
|
|
|
|
- path: path, // 保存本地路径用于预览
|
|
|
|
|
- status: 'success',
|
|
|
|
|
- fileName: response.data.fileName || '' // 保存文件名,如果后端返回的话
|
|
|
|
|
- });
|
|
|
|
|
- successCount++;
|
|
|
|
|
- } else {
|
|
|
|
|
- failCount++;
|
|
|
|
|
- console.error('上传失败:', response.msg);
|
|
|
|
|
- }
|
|
|
|
|
- } catch (e) {
|
|
|
|
|
- failCount++;
|
|
|
|
|
- uni.showToast({
|
|
|
|
|
- title: `解析响应失败: ${e}`,
|
|
|
|
|
- icon: 'none',
|
|
|
|
|
- });
|
|
|
|
|
- console.error('解析响应失败:', e);
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- fail: (err) => {
|
|
|
|
|
- failCount++;
|
|
|
|
|
- console.error('上传请求失败:', err);
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ fail: (err) => {
|
|
|
|
|
+ failCount++;
|
|
|
|
|
+ console.error('上传请求失败:', err);
|
|
|
uni.showToast({
|
|
uni.showToast({
|
|
|
- title: `上传请求失败: ${err}`,
|
|
|
|
|
- icon: 'none',
|
|
|
|
|
|
|
+ title: '上传请求失败',
|
|
|
|
|
+ icon: 'none',
|
|
|
|
|
+ duration: 2000
|
|
|
});
|
|
});
|
|
|
- },
|
|
|
|
|
- complete: () => {
|
|
|
|
|
- // 当所有文件都已处理完成
|
|
|
|
|
- if (successCount + failCount === totalFiles) {
|
|
|
|
|
- if (newImages.length > 0) {
|
|
|
|
|
- // 将新上传的图片添加到已有图片列表
|
|
|
|
|
- formData.images = [...formData.images, ...newImages]
|
|
|
|
|
- // 更新taskImages字段,将图片URL用逗号连接
|
|
|
|
|
- formData.imageUrl = formData.images.map(item => item.url).join(',')
|
|
|
|
|
- // 显示成功提示
|
|
|
|
|
- uni.hideLoading()
|
|
|
|
|
- uni.showToast({
|
|
|
|
|
- title: `成功上传${successCount}张图片`,
|
|
|
|
|
- icon: 'success'
|
|
|
|
|
- })
|
|
|
|
|
- } else {
|
|
|
|
|
- // 全部失败
|
|
|
|
|
- uni.showToast({
|
|
|
|
|
- title: `图片上传: ${newImages}`,
|
|
|
|
|
- icon: 'none'
|
|
|
|
|
- })
|
|
|
|
|
- uni.hideLoading()
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ },
|
|
|
|
|
+ complete: () => {
|
|
|
|
|
+ // 当所有文件都已处理完成
|
|
|
|
|
+ if (successCount + failCount === totalFiles) {
|
|
|
|
|
+ uni.hideLoading();
|
|
|
|
|
+
|
|
|
|
|
+ if (newImages.length > 0) {
|
|
|
|
|
+ // 将新上传的图片添加到已有图片列表
|
|
|
|
|
+ formData.images = [...formData.images, ...newImages];
|
|
|
|
|
+ // 更新imageUrl字段,将图片URL用逗号连接
|
|
|
|
|
+ formData.imageUrl = formData.images.map(item => item.url).join(',');
|
|
|
|
|
+
|
|
|
|
|
+ console.log('所有图片上传完成:', formData.images);
|
|
|
|
|
+ console.log('imageUrl:', formData.imageUrl);
|
|
|
|
|
+
|
|
|
|
|
+ // 显示成功提示
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: `成功上传${successCount}张图片`,
|
|
|
|
|
+ icon: 'success',
|
|
|
|
|
+ duration: 2000
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 全部失败
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '图片上传失败,请重试',
|
|
|
|
|
+ icon: 'none',
|
|
|
|
|
+ duration: 2000
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果有部分失败
|
|
|
|
|
+ if (failCount > 0 && successCount > 0) {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: `成功${successCount}张,失败${failCount}张`,
|
|
|
|
|
+ icon: 'none',
|
|
|
|
|
+ duration: 2000
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const removeImage = (index) => {
|
|
const removeImage = (index) => {
|