|
|
|
@ -120,16 +120,16 @@ |
|
|
|
</div> |
|
|
|
<div class="logs-table-wrapper"> |
|
|
|
<el-table :data="selectedOrderLogList" border size="small" class="detail-table" v-loading="detailLogLoading" height="295px"> |
|
|
|
<el-table-column prop="logTime" label="时间" width="160" align="center"></el-table-column> |
|
|
|
<el-table-column prop="action" label="操作" width="95" align="center"></el-table-column> |
|
|
|
<el-table-column prop="nodeName" label="节点" width="130" align="center"> |
|
|
|
<el-table-column prop="logTime" label="时间" min-width="160" align="center"></el-table-column> |
|
|
|
<el-table-column prop="action" label="操作" min-width="95" align="center"></el-table-column> |
|
|
|
<el-table-column prop="nodeName" label="节点" min-width="130" align="center"> |
|
|
|
<template slot-scope="scope">{{ scope.row.nodeName || scope.row.nodeCode || '-' }}</template> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column prop="operatorName" label="操作人" width="100" align="center"></el-table-column> |
|
|
|
<el-table-column prop="comment" label="备注" min-width="220" show-overflow-tooltip> |
|
|
|
<el-table-column prop="operatorName" label="操作人" min-width="100" align="center"></el-table-column> |
|
|
|
<!-- <el-table-column prop="comment" label="备注" min-width="220" show-overflow-tooltip> |
|
|
|
<template slot-scope="scope">{{ scope.row.comment || '-' }}</template> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column label="影像" width="95" align="center"> |
|
|
|
</el-table-column>--> |
|
|
|
<el-table-column label="影像" min-width="95" align="center"> |
|
|
|
<template slot-scope="scope"> |
|
|
|
<a |
|
|
|
v-if="isMediaNodeLog(scope.row)" |
|
|
|
@ -262,8 +262,8 @@ |
|
|
|
alt="media-thumb" |
|
|
|
@click="previewMediaFile(scope.row)"> |
|
|
|
<video |
|
|
|
v-else-if="resolveMediaKind(scope.row) === 'video' && scope.row.previewUrl" |
|
|
|
:src="scope.row.previewUrl" |
|
|
|
v-else-if="resolveMediaKind(scope.row) === 'video'" |
|
|
|
:src="getVideoStreamUrl(scope.row)" |
|
|
|
class="media-thumb media-thumb-video" |
|
|
|
muted |
|
|
|
playsinline |
|
|
|
@ -302,10 +302,15 @@ |
|
|
|
@click.stop="closeMediaPreview"> |
|
|
|
<video |
|
|
|
v-else-if="mediaPreviewType === 'video'" |
|
|
|
ref="mediaPreviewVideo" |
|
|
|
:key="mediaPreviewUrl" |
|
|
|
:src="mediaPreviewUrl" |
|
|
|
class="media-preview-video" |
|
|
|
controls |
|
|
|
autoplay |
|
|
|
playsinline |
|
|
|
preload="auto" |
|
|
|
@error="handleMediaPreviewError" |
|
|
|
@click.stop> |
|
|
|
</video> |
|
|
|
</div> |
|
|
|
@ -314,7 +319,7 @@ |
|
|
|
|
|
|
|
<script> |
|
|
|
import { deleteRenovationOrder, finishRenovationOrder, getNodeAssigneeList, getNodeAssigneeUsers, getRenovationOrderList, getReportLogList, reportRenovationOrderNode, saveNodeAssignee, saveRenovationOrder } from '@/api/longchuang/productionPlan' |
|
|
|
import { previewOssFileById2, queryOssFilePlus } from '@/api/oss/oss' |
|
|
|
import { getOssVideoStreamUrl, previewOssFileById2, queryOssFilePlus } from '@/api/oss/oss' |
|
|
|
|
|
|
|
export default { |
|
|
|
name: 'ProductionPlanRenovationOrder', |
|
|
|
@ -499,7 +504,7 @@ export default { |
|
|
|
})) |
|
|
|
this.mediaFileList.forEach(item => { |
|
|
|
const kind = this.resolveMediaKind(item) |
|
|
|
if (kind !== 'other') { |
|
|
|
if (kind === 'image') { |
|
|
|
this.loadMediaPreviewUrl(item, kind, false) |
|
|
|
} |
|
|
|
}) |
|
|
|
@ -528,9 +533,17 @@ export default { |
|
|
|
if (!fileRow) { |
|
|
|
return '' |
|
|
|
} |
|
|
|
const ext = fileRow.fileType || fileRow.fileSuffix || '' |
|
|
|
const ext = fileRow.fileType || fileRow.fileSuffix || this.getExtFromFileName(fileRow.fileName || fileRow.newFileName || '') |
|
|
|
return String(ext).replace(/^\./, '').toLowerCase() |
|
|
|
}, |
|
|
|
getExtFromFileName(fileName) { |
|
|
|
const name = String(fileName || '') |
|
|
|
const dotIndex = name.lastIndexOf('.') |
|
|
|
if (dotIndex < 0 || dotIndex >= name.length - 1) { |
|
|
|
return '' |
|
|
|
} |
|
|
|
return name.slice(dotIndex + 1) |
|
|
|
}, |
|
|
|
resolveMediaKind(fileRow) { |
|
|
|
const ext = this.getMediaExt(fileRow) |
|
|
|
const imageExtList = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'] |
|
|
|
@ -556,13 +569,26 @@ export default { |
|
|
|
buildPreviewMimeType(fileRow, kind) { |
|
|
|
const ext = this.getMediaExt(fileRow) |
|
|
|
if (kind === 'image') { |
|
|
|
if (ext === 'jpg') { |
|
|
|
return 'image/jpeg' |
|
|
|
const imageMimeMap = { |
|
|
|
jpg: 'image/jpeg', |
|
|
|
jpeg: 'image/jpeg', |
|
|
|
png: 'image/png', |
|
|
|
gif: 'image/gif', |
|
|
|
bmp: 'image/bmp', |
|
|
|
webp: 'image/webp' |
|
|
|
} |
|
|
|
return ext ? `image/${ext}` : 'image/jpeg' |
|
|
|
return imageMimeMap[ext] || 'image/jpeg' |
|
|
|
} |
|
|
|
if (kind === 'video') { |
|
|
|
return ext ? `video/${ext}` : 'video/mp4' |
|
|
|
const videoMimeMap = { |
|
|
|
mp4: 'video/mp4', |
|
|
|
m4v: 'video/mp4', |
|
|
|
webm: 'video/webm', |
|
|
|
mov: 'video/quicktime', |
|
|
|
avi: 'video/x-msvideo', |
|
|
|
'3gp': 'video/3gpp' |
|
|
|
} |
|
|
|
return videoMimeMap[ext] || 'video/mp4' |
|
|
|
} |
|
|
|
return 'application/octet-stream' |
|
|
|
}, |
|
|
|
@ -584,7 +610,9 @@ export default { |
|
|
|
const mimeType = this.buildPreviewMimeType(fileRow, kind) |
|
|
|
try { |
|
|
|
const { data } = await previewOssFileById2({ id: fileRow.id, fileType: mimeType }) |
|
|
|
const blob = data instanceof Blob ? data : new Blob([data], { type: mimeType }) |
|
|
|
const sourceBlob = data instanceof Blob ? data : new Blob([data]) |
|
|
|
const blobType = mimeType || sourceBlob.type || 'application/octet-stream' |
|
|
|
const blob = new Blob([sourceBlob], { type: blobType }) |
|
|
|
this.$set(fileRow, 'previewUrl', URL.createObjectURL(blob)) |
|
|
|
return true |
|
|
|
} catch (e) { |
|
|
|
@ -596,6 +624,12 @@ export default { |
|
|
|
this.$set(fileRow, 'previewLoading', false) |
|
|
|
} |
|
|
|
}, |
|
|
|
getVideoStreamUrl(fileRow) { |
|
|
|
if (!fileRow || !fileRow.id) { |
|
|
|
return '' |
|
|
|
} |
|
|
|
return getOssVideoStreamUrl(fileRow.id) |
|
|
|
}, |
|
|
|
async previewMediaFile(fileRow) { |
|
|
|
const kind = this.resolveMediaKind(fileRow) |
|
|
|
if (kind === 'other') { |
|
|
|
@ -606,6 +640,27 @@ export default { |
|
|
|
this.$message.warning('文件信息不完整,无法预览') |
|
|
|
return |
|
|
|
} |
|
|
|
if (kind === 'video') { |
|
|
|
const videoUrl = this.getVideoStreamUrl(fileRow) |
|
|
|
if (!videoUrl) { |
|
|
|
this.$message.warning('视频地址无效,无法预览') |
|
|
|
return |
|
|
|
} |
|
|
|
this.mediaPreviewType = 'video' |
|
|
|
this.mediaPreviewName = fileRow.fileName || fileRow.newFileName || '' |
|
|
|
this.mediaPreviewUrl = videoUrl |
|
|
|
this.mediaPreviewVisible = true |
|
|
|
this.$nextTick(() => { |
|
|
|
const previewVideo = this.$refs.mediaPreviewVideo |
|
|
|
if (previewVideo && typeof previewVideo.play === 'function') { |
|
|
|
const playPromise = previewVideo.play() |
|
|
|
if (playPromise && typeof playPromise.catch === 'function') { |
|
|
|
playPromise.catch(() => {}) |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
return |
|
|
|
} |
|
|
|
const loaded = await this.loadMediaPreviewUrl(fileRow, kind, true) |
|
|
|
if (!loaded) { |
|
|
|
return |
|
|
|
@ -616,11 +671,18 @@ export default { |
|
|
|
this.mediaPreviewVisible = true |
|
|
|
}, |
|
|
|
closeMediaPreview() { |
|
|
|
const previewVideo = this.$refs.mediaPreviewVideo |
|
|
|
if (previewVideo && typeof previewVideo.pause === 'function') { |
|
|
|
previewVideo.pause() |
|
|
|
} |
|
|
|
this.mediaPreviewVisible = false |
|
|
|
this.mediaPreviewType = '' |
|
|
|
this.mediaPreviewName = '' |
|
|
|
this.mediaPreviewUrl = '' |
|
|
|
}, |
|
|
|
handleMediaPreviewError() { |
|
|
|
this.$message.warning('视频播放失败,请稍后重试') |
|
|
|
}, |
|
|
|
resetQuery() { |
|
|
|
this.searchData = { projectNo: '', modelNo: '', color: '', status: '', deliveryStartDate: '', deliveryEndDate: '', page: 1, limit: 20 } |
|
|
|
this.getDataList('Y') |
|
|
|
|