| | |
| | | |
| | | /** |
| | | * 通用文件上传 |
| | | * @param formData |
| | | * @returns |
| | | * @param formData |
| | | * @returns |
| | | */ |
| | | export function uploadFile(formData: FormData) { |
| | | return request.Post<Service.ResponseResult<{ id: string, name: string, url: string }>>('/vehicleConvoy/api/v1/common/uploadFile', formData) |
| | | return request.Post<Service.ResponseResult<{ id: string, name: string, url: string }>>('/operation/base/v1/oss/upload', formData) |
| | | } |
| | |
| | | await new Promise(resolve => setTimeout(resolve, 600)) |
| | | |
| | | // TODO: 等待具体上传接口出来后,取消注释以下真实 API 调用逻辑 |
| | | /* |
| | | |
| | | const formData = new FormData() |
| | | if (file.file) { |
| | | formData.append('file', file.file) |
| | | } |
| | | const { data, error } = await uploadFile(formData) |
| | | if (data && !error) { |
| | | file.url = data.url |
| | | file.id = data.id |
| | | const res = await uploadFile(formData) |
| | | if (res.code === 200) { |
| | | file.url = res.data.url |
| | | file.id = res.data.id |
| | | file.status = 'finished' |
| | | onFinish() |
| | | } else { |
| | | onError() |
| | | window.$message.error('文件上传失败') |
| | | } |
| | | */ |
| | | console.log('模拟返回逻辑开始') |
| | | |
| | | // --- 模拟返回逻辑开始 --- |
| | | // 生成一个模拟的 URL (如果是图片则使用 base64 预览) |
| | | file.url = 'https://haitunyingyu.obs.cn-southwest-2.myhuaweicloud.com/admin/8bbba1ccafda4456bf7e3b2054d78541.jpg' // 默认占位图 |
| | | const newId = `mock_${Date.now()}` |
| | | file.status = 'finished' |
| | | onFinish() |
| | | // file.url = 'https://haitunyingyu.obs.cn-southwest-2.myhuaweicloud.com/admin/8bbba1ccafda4456bf7e3b2054d78541.jpg' // 默认占位图 |
| | | // const newId = `mock_${Date.now()}` |
| | | // file.status = 'finished' |
| | | // onFinish() |
| | | |
| | | // 关键修复:返回上传后的文件信息,供组件内使用 |
| | | return { |
| | | id: newId, |
| | | id: file.id, |
| | | url: file.url, |
| | | name: file.name, |
| | | status: 'finished', |
| | |
| | | |
| | | /** |
| | | * 文件上传前校验封装 |
| | | * @param data |
| | | * @param data |
| | | * @param options 校验配置 |
| | | */ |
| | | export function beforeUploadCheck( |
| | |
| | | <script setup lang="ts"> |
| | | import { ref, computed } from 'vue' |
| | | import type { FormInst, FormRules, UploadFileInfo } from 'naive-ui' |
| | | import type { FormInst, FormRules, UploadFileInfo , UploadCustomRequestOptions} from 'naive-ui' |
| | | import { customUploadRequest } from '@/utils/upload' |
| | | |
| | | interface FormModel { |
| | | nickName: string |
| | |
| | | fileList.value = [] |
| | | } |
| | | |
| | | const handleUploadChange = (options: { fileList: UploadFileInfo[] }) => { |
| | | fileList.value = options.fileList |
| | | if (options.fileList.length > 0) { |
| | | formModel.value.avatar = options.fileList[0].url || '' |
| | | const handleCustomUpload = async (options: UploadCustomRequestOptions) => { |
| | | const result = await customUploadRequest(options as any) |
| | | console.log('上传结果', result) |
| | | if (result) { |
| | | // 构建 JSON 数组字符串 |
| | | const pictureData = { |
| | | id: result.id, |
| | | name: result.name, |
| | | url: result.url |
| | | } |
| | | formModel.value.avatar = JSON.stringify(pictureData) |
| | | fileList.value = [{ |
| | | id: result.id, |
| | | name: result.name, |
| | | status: 'finished', |
| | | url: result.url |
| | | }] |
| | | // 触发校验 |
| | | formRef.value?.validate(errors => { |
| | | if (!errors) return |
| | | }, (rule) => rule?.key === 'bannerPictures') |
| | | } |
| | | } |
| | | |
| | | const handleRemove = () => { |
| | | formModel.value.avatar = '' |
| | | fileList.value = [] |
| | | } |
| | | </script> |
| | | |
| | |
| | | <div class="grid grid-cols-2 gap-4 items-start"> |
| | | <n-form-item label="头像" path="avatar"> |
| | | <n-upload |
| | | v-model:file-list="fileList" |
| | | :max="1" |
| | | list-type="image-card" |
| | | :file-list="fileList" |
| | | @change="handleUploadChange" |
| | | :custom-request="handleCustomUpload" |
| | | @remove="handleRemove" |
| | | > |
| | | <div class="flex flex-col items-center justify-center" style="width: 100px; height: 100px"> |
| | | <span style="font-size: 32px; color: #ccc">+</span> |
| | |
| | | resizable: true, |
| | | render: (row) => ( |
| | | <div class="flex items-center gap-2"> |
| | | {row.avatar && <img src={row.avatar} alt="头像" class="w-8 h-8 rounded-full" />} |
| | | {row.avatar && <img src={JSON.parse(row.avatar).url} alt="头像" class="w-8 h-8 rounded-full" />} |
| | | {!row.avatar && <div class="w-8 h-8 rounded-full bg-gray-300 flex items-center justify-center text-sm">头</div>} |
| | | <span>{row.nickName}</span> |
| | | </div> |
| | |
| | | |
| | | const handleCustomUpload = async (options: UploadCustomRequestOptions) => { |
| | | const result = await customUploadRequest(options as any) |
| | | console.log('上传结果', result) |
| | | if (result) { |
| | | // 构建 JSON 数组字符串 |
| | | const pictureData = [{ |
| | |
| | | url: result.url |
| | | }] |
| | | formModel.value.bannerPictures = JSON.stringify(pictureData) |
| | | fileList.value = [{ |
| | | id: result.id, |
| | | name: result.name, |
| | | status: 'finished', |
| | | url: result.url |
| | | }] |
| | | // 触发校验 |
| | | formRef.value?.validate(errors => { |
| | | if (!errors) return |
| | |
| | | const handleConfirm = async () => { |
| | | try { |
| | | await formRef.value?.validate() |
| | | |
| | | |
| | | const params = { |
| | | ...formModel.value, |
| | | bannerStatus: formModel.value.bannerStatus ? 1 : 2, |
| | |
| | | if (props.mode !== 'add' && props.rowData) { |
| | | // 编辑/查看模式,回显数据 |
| | | const row = props.rowData |
| | | |
| | | |
| | | // 解析图片 |
| | | try { |
| | | const pictures = JSON.parse(row.bannerPictures || '[]') |
| | |
| | | action: true |
| | | }" |
| | | :content-style="{ |
| | | padding: '16px 24px 0px 24px', |
| | | maxHeight: '60vh', |
| | | overflow: 'auto' |
| | | // padding: '16px 24px 0px 24px', |
| | | // maxHeight: '60vh', |
| | | // overflow: 'auto' |
| | | }" |
| | | @close="handleClose" |
| | | > |