@@ -0,0 +1,294 @@ | |||
<template> | |||
<div class="oss-filed"> | |||
<n-upload | |||
action="#" | |||
:max="limit" | |||
:file-list="data.fileList" | |||
:default-upload="false" | |||
:list-type="fileType == 'img' ? 'image-card' : 'text'" | |||
@change="handleChange" | |||
@before-upload="beforeUpload" | |||
> | |||
<n-button v-if="fileType != 'img'"> | |||
<n-icon> | |||
<FileOutlined /> | |||
</n-icon> | |||
{{ btnName }} | |||
</n-button> | |||
<div v-if="fileType == 'img'" class="oss-upload-text" /> | |||
</n-upload> | |||
</div> | |||
</template> | |||
<script setup name="fileOss"> | |||
import OSS from 'ali-oss' | |||
import { getOssAuth } from '@/api/common/upload.js' | |||
import { FileOutlined, UploadOutlined } from '@vicons/antd' | |||
import { reactive, onMounted, watch, toRefs } from 'vue' | |||
const props = defineProps({ | |||
limit: { | |||
type: Number, | |||
default: 1 | |||
}, | |||
defaultList: { | |||
type: String, | |||
default: '' | |||
}, | |||
fileType: { | |||
type: String, | |||
default: 'img' | |||
}, | |||
btnName: { | |||
type: String, | |||
default: '选择文件' | |||
} | |||
}) | |||
const emit = defineEmits(['uploadStatus']) | |||
const data = reactive({ | |||
...props, | |||
client: null, | |||
fileList: [], | |||
hasUploadInfo: {} | |||
}) | |||
onMounted(() => { | |||
if (props.defaultList) { | |||
const list = props.defaultList.split(',') | |||
const fileList = list.map((item) => { | |||
const objectName = item.split('/').slice(3).join('/') | |||
const obj = { | |||
name: objectName, | |||
id: objectName, | |||
type: 'image/png', | |||
url: item, | |||
objectName: objectName, | |||
status: 'finished' | |||
} | |||
data.hasUploadInfo[obj.id] = { | |||
id: objectName, | |||
objectName: objectName | |||
} | |||
return obj | |||
}) | |||
data.fileList = fileList | |||
emit('uploadStatus', 'upload') | |||
} else { | |||
data.fileList = [] | |||
} | |||
}) | |||
/* 监听默认文件列表 */ | |||
watch(() => props.defaultList, (value) => { | |||
if (value.length) { | |||
const list = value.split(',') | |||
const fileList = list.map((item) => { | |||
const objectName = item.split('/').slice(3).join('/') | |||
const obj = { | |||
name: objectName, | |||
id: objectName, | |||
type: 'image/png', | |||
url: item, | |||
objectName: objectName | |||
} | |||
data.hasUploadInfo[obj.id] = { | |||
id: objectName, | |||
objectName: objectName | |||
} | |||
return obj | |||
}) | |||
data.fileList = fileList | |||
emit('uploadStatus', 'upload') | |||
} else { | |||
data.fileList = [] | |||
// emit('uploadStatus', 'hasFile') | |||
} | |||
}) | |||
/** | |||
* @description: 上传文件 | |||
* @return {*} | |||
*/ | |||
const startUpload = () => { | |||
return new Promise((resolve, reject) => { | |||
/* 定义要上传文件 */ | |||
const uploads = [] | |||
/* 从待文件列表中获取没有上传过的文件 */ | |||
const uloadList = data.fileList.filter((item) => { | |||
return !item.url | |||
}) | |||
/* 如果待上传列表长度为0,则返回,否则获取上传鉴权 */ | |||
if (!uloadList.length) { | |||
/* 如果没有要上传的文件信息则返回oss的文件名 */ | |||
/* 不存在objectName的文件表示上传失败 */ | |||
const objectList = data.fileList.map((item) => item.objectName || 'error') | |||
resolve(objectList) | |||
} else { | |||
getOssAuth().then(res => { | |||
/* 初始化oss上传客户端 */ | |||
data.client = new OSS({ | |||
region: 'oss-cn-shanghai', | |||
secure: true, | |||
accessKeyId: res.data.accessKeyId, | |||
accessKeySecret: res.data.accessKeySecret, | |||
stsToken: res.data.securityToken, | |||
bucket: 'ta-tech-image' | |||
}) | |||
/* promise上传要上传的文件 */ | |||
uloadList.forEach(item => { | |||
uploads.push(uploadOss(item)) | |||
}) | |||
Promise.all(uploads) | |||
.then((response) => { | |||
/* 获取fileList内的文件存储名称 */ | |||
const objectList = data.fileList.map((item) => item.objectName || 'error') | |||
resolve(objectList) | |||
emit('uploadStatus', 'success') | |||
}) | |||
.catch((error) => { | |||
console.log('error', error) | |||
resolve(error) | |||
}) | |||
}) | |||
} | |||
}) | |||
} | |||
/** | |||
* 上传到 OSS | |||
* @param {*} files | |||
*/ | |||
const uploadOss = (files) => { | |||
const file = files.file | |||
return new Promise((resolve, reject) => { | |||
/* 生成随机文件名称 */ | |||
const randomString = Math.random().toString(36).slice(2) | |||
const suffix = /\.[^\.]+/.exec(file.name) | |||
const timestamp = new Date().getTime() | |||
const objectName = `imagedir/${randomString}_${timestamp}${suffix}` | |||
/* 上传文件至oss */ | |||
data.client.put(objectName, file) | |||
.then((res) => { | |||
const index = data.fileList.findIndex(list => list.id === files.id) | |||
data.fileList[index].url = res.url | |||
data.fileList[index].objectName = objectName | |||
const id = data.fileList[index].id | |||
data.hasUploadInfo[id] = { | |||
id: objectName, | |||
objectName: objectName | |||
} | |||
resolve(objectName) | |||
}) | |||
.catch((err) => { | |||
console.log('err', err) | |||
resolve('error') | |||
console.log(err) | |||
}) | |||
}) | |||
} | |||
/** | |||
* @description: 上传前的判断文件类型 | |||
* @param {*} file 当前选择的文件 | |||
* @return {*} | |||
*/ | |||
const beforeUpload = ({ file }) => { | |||
if (props.fileType === 'img') { | |||
if (!file.type.match('image.*')) { | |||
$message.error('请选择正确的图片类型') | |||
/* 中断流程 */ | |||
return false | |||
} | |||
} | |||
if (props.fileType === 'srt') { | |||
const type = ['srt', 'SRT'] | |||
const temp = type.includes(file.name.split('.')[1]) | |||
if (!temp) { | |||
$message.error('请选择SRT类型文件') | |||
/* 中断流程 */ | |||
return false | |||
} | |||
} | |||
if (props.fileType === 'tif') { | |||
const type = ['tif', 'TIF'] | |||
const temp = type.includes(file.name.split('.')[1]) | |||
if (!temp) { | |||
$message.error('请选择tif类型文件') | |||
/* 中断流程 */ | |||
return false | |||
} | |||
} | |||
} | |||
/** | |||
* @description: 文件发生变化时 | |||
* @param {Array} fileList | |||
* @return {*} | |||
*/ | |||
const handleChange = ({ fileList }) => { | |||
data.fileList = fileList.map((item) => { | |||
if (Object.keys(data.hasUploadInfo).includes(item.id)) { | |||
item.objectName = data.hasUploadInfo[item.id].objectName | |||
} | |||
return item | |||
}) | |||
/* 判断是否存在文件 */ | |||
const status = fileList.length ? 'ready' : 'no-file' | |||
emit('uploadStatus', status) | |||
} | |||
defineExpose({ startUpload, ...toRefs(data) }) | |||
</script> | |||
<style lang="scss" scoped> | |||
.oss-filed { | |||
width: 100%; | |||
padding: 10px 20px; | |||
} | |||
.oss-upload-picture-card-wrapper { | |||
min-height: 122px; | |||
padding: 10px 0 0 10px; | |||
} | |||
.oss-upload-text { | |||
// width: 100px; | |||
// height: 100px; | |||
// cursor: pointer; | |||
// border: 1px solid #e1e1e1; | |||
// margin: 10px 0 0 10px; | |||
position: relative; | |||
} | |||
.oss-upload-text::before { | |||
content: ''; | |||
position: absolute; | |||
left: 50%; | |||
top: 50%; | |||
width: 30px; | |||
transform: translate(-50%, -50%); | |||
border-top: 2px solid #e1e1e1; | |||
} | |||
.oss-upload-text::after { | |||
content: ''; | |||
position: absolute; | |||
left: 50%; | |||
top: 50%; | |||
height: 30px; | |||
transform: translate(-50%, -50%); | |||
border-left: 2px solid #e1e1e1; | |||
} | |||
.n-image { | |||
img { | |||
overflow: hidden; | |||
} | |||
} | |||
.oss-upload-type { | |||
text-align: center; | |||
font-size: 14px; | |||
color: rgb(64, 152, 252); | |||
// cursor: pointer; | |||
} | |||
</style> |
@@ -49,7 +49,7 @@ | |||
<!-- 设备/影响基本信息 - 飞手接单: 管理员 --> | |||
<div v-if="current == 2 && isAdmin" class="cont"> | |||
<n-descriptions label-placement="left" label-align="right" :column="4" title="设备/影响基本信息"> | |||
<n-descriptions label-placement="left" label-align="right" :column="4" title="设备/影像基本信息"> | |||
<template v-for="(it, i) in equipmentInfo" :key="i + it.label"> | |||
<n-descriptions-item v-if="it?.isLive !== data.isLive" :label="it.label"> | |||
{{ it.value }} | |||
@@ -80,7 +80,7 @@ | |||
<!-- 设备/影响基本信息 - 已接单 --> | |||
<div v-if="current === 3" class="cont"> | |||
<n-descriptions label-placement="left" label-align="right" :column="4" title="设备/影响基本信息"> | |||
<n-descriptions label-placement="left" label-align="right" :column="4" title="设备/影像基本信息"> | |||
<template v-for="(it, i) in executionInfo" :key="i + it.label"> | |||
<n-descriptions-item :label="it.label"> | |||
{{ it.value }} | |||
@@ -92,7 +92,7 @@ | |||
<!-- 设备/影响基本信息 - 执行中: 管理员 --> | |||
<div v-if="current === 4" class="cont"> | |||
<n-descriptions label-placement="left" label-align="right" :column="4" title="设备/影响基本信息"> | |||
<n-descriptions label-placement="left" label-align="right" :column="4" title="设备/影像基本信息"> | |||
<template v-for="(it, i) in executionInfo" :key="i + it.label"> | |||
<n-descriptions-item :label="it.label"> | |||
{{ it.value }} | |||
@@ -105,8 +105,20 @@ | |||
<div v-if="current === 5" class="cont"> | |||
<div class="title">飞行文件</div> | |||
<UploadVod @upload-status="vodStatus" /> | |||
<UploadVod v-if="data.photographyWay === 1" :auto-upload="true" :upload-name="'选择【视频】'" :limit="1" @upload-status="vodStatusVideo" /> | |||
<fileOss v-if="data.photographyWay === 1" ref="srtRefs" :file-type="'srt'" :btn-name="'选择【轨迹】'" :limit="1" :default-list="data.srtUrl" @upload-status="vodStatusSRT" /> | |||
<fileOss v-if="data.photographyWay !== 1" ref="ortRefs" :file-type="'tif'" :btn-name="'选择【正射影像】'" :limit="9" :default-list="data.orthoUrl" @upload-status="vodStatusZS" /> | |||
<fileOss v-if="data.photographyWay !== 1" ref="inclinedRefs" :file-type="'tif'" :btn-name="'选择【倾斜影像】'" :limit="9" :default-list="data.inclinedUrl" @upload-status="vodStatusQX" /> | |||
<!-- <UploadVod v-if="data.photographyWay === 1" :auto-upload="true" :upload-name="'选择【轨迹】'" :limit="1" @upload-status="vodStatusSRT" /> | |||
<UploadVod v-if="data.photographyWay !== 1" :auto-upload="true" :upload-name="'选择【正射影像】tif文件'" @upload-status="vodStatusZS" /> | |||
<UploadVod v-if="data.photographyWay !== 1" :auto-upload="true" :upload-name="'选择【倾斜影像】tif文件'" @upload-status="vodStatusQX" /> --> | |||
<n-button type="primary" class="btn" @click="submitFile"> | |||
<n-icon> | |||
<UploadOutlined /> | |||
</n-icon> | |||
开始上传 | |||
</n-button> | |||
</div> | |||
</template> | |||
@@ -118,6 +130,8 @@ import { distributionPilot, pilotOrder, pilotStart, pilotEnd, uploadFlightUrl } | |||
import { form, getPilotList, getEquipment, getEquipmentMount, getCloudMount } from '../tools/drawForm' | |||
import { basic, fly, equipment, execution } from '../hook/index' | |||
import UploadVod from '@/components/UploadVod/index.vue' | |||
import fileOss from '@/components/UploadOss/fileOss.vue' | |||
import { UploadOutlined } from '@vicons/antd' | |||
getPilotList() // 获取飞手列表 | |||
getEquipment() // 无人机列表 | |||
@@ -132,6 +146,7 @@ const props = defineProps({ | |||
}) | |||
const { detail: { data }} = props // 传来的详情数据 | |||
form.userForm = data | |||
const current = data.pilotStatus / 5 // 当前状态 | |||
@@ -146,6 +161,15 @@ const flyInfo = fly(data) // 飞行信息 | |||
const equipmentInfo = equipment(data) // 设备/影响基本信息 | |||
const executionInfo = execution(data) // 执行中信息 | |||
const videoUrl = ref('') // 视频文件 | |||
const srtUrl = ref('') // srt文件 | |||
const inclinedUrl = ref('') // 倾斜摄影 | |||
const orthoUrl = ref('') // 正射影像 | |||
const srtRefs = ref(null) // srt refs | |||
const ortRefs = ref(null) // 正射 refs | |||
const inclinedRefs = ref(null) // 倾斜 refs | |||
const emit = defineEmits(['close']) | |||
// 分配飞手 | |||
@@ -204,27 +228,63 @@ const endFly = () => { | |||
}) | |||
} | |||
// 视频上传 | |||
const vodStatus = ({ status, list }) => { | |||
console.log(status, list) | |||
const videoUrl = [] | |||
// 上传 - 视频 | |||
const vodStatusVideo = ({ status, list }) => { | |||
const arr = [] | |||
for (var key in list) { | |||
videoUrl.push(list[key].url) | |||
arr.push(list[key].url) | |||
} | |||
const videoList = videoUrl.join(',') | |||
console.log('videoList', videoList) | |||
return | |||
if (status === 'success') { | |||
// 视频上传 | |||
uploadFlightUrl({ | |||
id: data.id, | |||
videoUrl: videoList | |||
}).then(({ code }) => { | |||
console.log(code) | |||
}) | |||
videoUrl.value = arr.join(',') | |||
} | |||
} | |||
// 上传 - SRT | |||
const vodStatusSRT = async(status) => { | |||
const res = await srtRefs.value.startUpload() | |||
console.log('status: ', status) | |||
console.log(res) | |||
if (status === 'success' && res.includes('error')) { | |||
$message.error('上传失败,请稍后重试') | |||
} else if (status === 'success') { | |||
srtUrl.value = res.join() | |||
} | |||
} | |||
// 上传 - 倾斜 | |||
const vodStatusQX = async(status) => { | |||
const res = await inclinedRefs.value.startUpload() | |||
if (status === 'success' && res.includes('error')) { | |||
$message.error('上传失败,请稍后重试') | |||
} else if (status === 'success') { | |||
inclinedUrl.value = res.join() | |||
} | |||
} | |||
// 上传 - 正射 | |||
const vodStatusZS = async(status) => { | |||
const res = await ortRefs.value.startUpload() | |||
if (status === 'success' && res.includes('error')) { | |||
$message.error('上传失败,请稍后重试') | |||
} else if (status === 'success') { | |||
orthoUrl.value = res.join() | |||
} | |||
} | |||
// 上传 | |||
const submitFile = () => { | |||
uploadFlightUrl({ | |||
id: data.id, | |||
videoUrl: videoUrl.value ? videoUrl.value : data.videoUrl, | |||
srtUrl: srtUrl.value ? srtUrl.value : data.srtUrl, | |||
inclinedUrl: data.inclinedUrl + ',' + inclinedUrl.value, | |||
orthoUrl: data.orthoUrl + ',' + orthoUrl.value | |||
}).then(({ code }) => { | |||
console.log(code) | |||
if (code === 0) { | |||
emit('close') | |||
} | |||
}) | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
@@ -246,8 +306,8 @@ const vodStatus = ({ status, list }) => { | |||
} | |||
.btn { | |||
width: 70px; | |||
margin-left: calc(50% - 30px); | |||
width: 90px; | |||
margin-left: calc(50% - 45px); | |||
margin-top: 10px; | |||
margin-bottom: 30px; | |||
} |