更新
This commit is contained in:
@ -443,6 +443,18 @@ export function upImage(data) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 单个文件上传
|
||||||
|
export function uploadFile(file) {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('file', file)
|
||||||
|
return service({
|
||||||
|
url: '/common/upload',
|
||||||
|
method: 'post',
|
||||||
|
data: formData,
|
||||||
|
headers: { 'Content-Type': 'multipart/form-data' }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
//根据身份证号查询涉疫登记信息
|
//根据身份证号查询涉疫登记信息
|
||||||
export function getRySydjInfo(data) {
|
export function getRySydjInfo(data) {
|
||||||
return service({
|
return service({
|
||||||
|
|||||||
141
src/components/FileUploader.vue
Normal file
141
src/components/FileUploader.vue
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
<template>
|
||||||
|
<div class="file-uploader">
|
||||||
|
<van-uploader
|
||||||
|
:max-count="1"
|
||||||
|
:after-read="handleAfterRead"
|
||||||
|
:preview-size="previewSize"
|
||||||
|
:show-upload="!modelValue"
|
||||||
|
:disabled="uploading"
|
||||||
|
>
|
||||||
|
<slot v-if="!modelValue">
|
||||||
|
<div class="upload-placeholder" :style="{ width: previewSize + 'px', height: previewSize + 'px' }">
|
||||||
|
<van-icon name="photograph" class="upload-icon" />
|
||||||
|
<div class="upload-text">{{ uploading ? '上传中...' : placeholder }}</div>
|
||||||
|
</div>
|
||||||
|
</slot>
|
||||||
|
</van-uploader>
|
||||||
|
<div v-if="modelValue" class="preview-wrapper">
|
||||||
|
<van-image
|
||||||
|
:src="modelValue"
|
||||||
|
:preview-src-list="[modelValue]"
|
||||||
|
class="preview-image"
|
||||||
|
:width="previewSize"
|
||||||
|
:height="previewSize"
|
||||||
|
fit="cover"
|
||||||
|
radius="6"
|
||||||
|
preview
|
||||||
|
/>
|
||||||
|
<van-icon v-if="showDelete" name="cross" class="delete-btn" @click.stop="handleDelete" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { Toast } from 'vant'
|
||||||
|
import { uploadFile } from '@/api/common'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: { type: String, default: '' },
|
||||||
|
previewSize: { type: [Number, String], default: 100 },
|
||||||
|
placeholder: { type: String, default: '点击上传' },
|
||||||
|
showDelete: { type: Boolean, default: true }
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue', 'success', 'error', 'delete'])
|
||||||
|
|
||||||
|
const uploading = ref(false)
|
||||||
|
|
||||||
|
async function handleAfterRead(file) {
|
||||||
|
uploading.value = true
|
||||||
|
try {
|
||||||
|
const fileObj = file.file
|
||||||
|
const res = await uploadFile(fileObj)
|
||||||
|
// 根据响应结构获取 URL,请根据实际返回调整
|
||||||
|
const url = res? res.fileName : ''
|
||||||
|
if (url) {
|
||||||
|
emit('update:modelValue', url)
|
||||||
|
emit('success', url)
|
||||||
|
} else {
|
||||||
|
throw new Error('上传失败')
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('上传失败:', err)
|
||||||
|
Toast('上传失败,请重试')
|
||||||
|
emit('error', err)
|
||||||
|
} finally {
|
||||||
|
uploading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDelete() {
|
||||||
|
emit('update:modelValue', '')
|
||||||
|
emit('delete')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.file-uploader {
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
:deep(.van-uploader) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.van-uploader__wrapper) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.van-uploader__preview) {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .upload-placeholder {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px dashed #d1d5db;
|
||||||
|
border-radius: 6px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 6px;
|
||||||
|
width: 135px !important;
|
||||||
|
height: 135px !important;
|
||||||
|
|
||||||
|
.upload-icon {
|
||||||
|
font-size: 28px;
|
||||||
|
color: #9ca3af;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-text {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-wrapper {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
.preview-image {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-btn {
|
||||||
|
position: absolute;
|
||||||
|
top: -6px;
|
||||||
|
right: -6px;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
border-radius: 50%;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -89,15 +89,13 @@
|
|||||||
<div class="photo-upload-list">
|
<div class="photo-upload-list">
|
||||||
<div class="photo-upload-item" v-for="(photo, index) in photoList" :key="index">
|
<div class="photo-upload-item" v-for="(photo, index) in photoList" :key="index">
|
||||||
<div style="text-align: left;">照片{{ index + 1 }}</div>
|
<div style="text-align: left;">照片{{ index + 1 }}</div>
|
||||||
<van-uploader :max-count="1" :after-read="(file) => onPhotoRead(file, index)" :preview-size="200"
|
<FileUploader
|
||||||
:show-upload="!photo.url">
|
v-model="photo.url"
|
||||||
<div class="photo-upload-content" v-if="!photo.url">
|
:preview-size="200"
|
||||||
<van-icon name="photograph" class="photo-icon" />
|
placeholder="点击拍照/上传"
|
||||||
<div class="photo-text">点击拍照/上传</div>
|
@success="(url) => onPhotoUploaded(url, index)"
|
||||||
</div>
|
@delete="onPhotoDelete(index)"
|
||||||
</van-uploader>
|
/>
|
||||||
<van-image v-if="photo.url" :src="photo.url" :preview-src-list="[photo.url]" class="photo-preview-img" width="100" height="100" fit="cover" radius="6" preview/>
|
|
||||||
<van-icon v-if="photo.url" @click.stop="deletePhoto(index)" name="cross" class="photo-delete" />
|
|
||||||
<van-field v-model="photo.url" label="图片链接" placeholder="请输入图片链接" class="photo-link-field" />
|
<van-field v-model="photo.url" label="图片链接" placeholder="请输入图片链接" class="photo-link-field" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -141,10 +139,10 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import PopupView from '@/components/popupView.vue'
|
import PopupView from '@/components/popupView.vue'
|
||||||
|
import FileUploader from '@/components/FileUploader.vue'
|
||||||
import { ref, reactive, onMounted } from "vue";
|
import { ref, reactive, onMounted } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { Toast } from "vant";
|
import { Toast } from "vant";
|
||||||
import { upImage } from "@/api/common";
|
|
||||||
import { addSsPai } from "@/api/traffic";
|
import { addSsPai } from "@/api/traffic";
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -297,18 +295,18 @@ function toggleSection(key) {
|
|||||||
openSections[key] = !openSections[key];
|
openSections[key] = !openSections[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除照片
|
// 照片上传成功回调
|
||||||
function deletePhoto(index) {
|
function onPhotoUploaded(url, index) {
|
||||||
photoList.value[index].url = "";
|
photoList.value[index].url = url
|
||||||
const uploadedCount = photoList.value.filter(p => p.url).length;
|
const uploadedCount = photoList.value.filter(p => p.url).length
|
||||||
formData.zpsl = uploadedCount.toString();
|
formData.zpsl = uploadedCount.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
// vant upload上传后处理
|
// 照片删除回调
|
||||||
function onPhotoRead(file, index) {
|
function onPhotoDelete(index) {
|
||||||
photoList.value[index].url = file.content;
|
photoList.value[index].url = ""
|
||||||
const uploadedCount = photoList.value.filter(p => p.url).length;
|
const uploadedCount = photoList.value.filter(p => p.url).length
|
||||||
formData.zpsl = uploadedCount.toString();
|
formData.zpsl = uploadedCount.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回上一页
|
// 返回上一页
|
||||||
@ -564,98 +562,6 @@ onMounted(() => {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 1px solid #e5e7eb;
|
border: 1px solid #e5e7eb;
|
||||||
|
|
||||||
:deep(.van-uploader) {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.van-uploader__wrapper) {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.van-uploader__preview) {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.van-uploader__preview-image) {
|
|
||||||
width: 100%;
|
|
||||||
aspect-ratio: 3/1;
|
|
||||||
border-radius: 6px;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.van-uploader__preview-delete) {
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
background: rgba(0, 0, 0, 0.6);
|
|
||||||
border-radius: 50%;
|
|
||||||
top: -6px;
|
|
||||||
right: -6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.van-uploader__upload) {
|
|
||||||
margin: 0;
|
|
||||||
width: 100%;
|
|
||||||
aspect-ratio: 3/1;
|
|
||||||
background: #fff;
|
|
||||||
border: 1px dashed #d1d5db;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.van-uploader__upload-icon) {
|
|
||||||
font-size: 28px;
|
|
||||||
color: #9ca3af;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.van-uploader__upload-text) {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #6b7280;
|
|
||||||
}
|
|
||||||
|
|
||||||
.photo-upload-content {
|
|
||||||
width: 100%;
|
|
||||||
aspect-ratio: 3/1;
|
|
||||||
background: #fff;
|
|
||||||
border: 1px dashed #d1d5db;
|
|
||||||
border-radius: 6px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 6px;
|
|
||||||
|
|
||||||
.photo-icon {
|
|
||||||
font-size: 32px;
|
|
||||||
color: #9ca3af;
|
|
||||||
}
|
|
||||||
|
|
||||||
.photo-text {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #6b7280;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.photo-preview-img {
|
|
||||||
width: 100px;
|
|
||||||
border-radius: 6px;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.photo-delete {
|
|
||||||
position: absolute;
|
|
||||||
top: 8px;
|
|
||||||
right: 8px;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
background: rgba(0, 0, 0, 0.6);
|
|
||||||
border-radius: 50%;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.photo-label {
|
.photo-label {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: #374151;
|
color: #374151;
|
||||||
|
|||||||
Reference in New Issue
Block a user