| | |
| | | </template> |
| | | |
| | | <script> |
| | | import JSZip from 'jszip'; |
| | | import { getMedia, deleteAllFile } from '@/api/resource/media'; |
| | | import { getAirportList } from '@/api/device/device'; |
| | | import { mapGetters } from 'vuex'; |
| | | import func from '@/utils/func'; |
| | | import JSZip from 'jszip' |
| | | import { getMedia, deleteAllFile } from '@/api/resource/media' |
| | | import { getAirportList } from '@/api/device/device' |
| | | import { mapGetters } from 'vuex' |
| | | import func from '@/utils/func' |
| | | |
| | | export default { |
| | | data() { |
| | | const endDate = new Date(); |
| | | const startDate = new Date(); |
| | | startDate.setMonth(startDate.getMonth() - 1); |
| | | const defaultStartDate = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}-${String(startDate.getDate()).padStart(2, '0')}`; |
| | | const defaultEndDate = `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, '0')}-${String(endDate.getDate()).padStart(2, '0')}`; |
| | | data () { |
| | | const endDate = new Date() |
| | | const startDate = new Date() |
| | | startDate.setMonth(startDate.getMonth() - 1) |
| | | const defaultStartDate = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}-${String(startDate.getDate()).padStart(2, '0')}` |
| | | const defaultEndDate = `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, '0')}-${String(endDate.getDate()).padStart(2, '0')}` |
| | | |
| | | return { |
| | | form: {}, |
| | |
| | | selection: true, |
| | | dialogClickModal: false, |
| | | delBtn: false, |
| | | |
| | | height: 'auto', |
| | | calcHeight: 20, |
| | | column: [ |
| | | { label: '机场选择', prop: 'airportNickname', type: 'select', search: true, searchSpan: 5, dicData: [], props: { label: 'nickname', value: 'nickname' }, hide: true }, |
| | | { label: '创建日期', prop: 'daterange', type: 'daterange', search: true, searchRange: true, searchSpan: 6, format: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD', startPlaceholder: '开始时间', endPlaceholder: '结束时间', viewDisplay: false, hide: true, searchValue: [defaultStartDate, defaultEndDate] }, |
| | |
| | | }, |
| | | domainUrl: '', |
| | | isDownloading: false, // 控制按钮加载状态 |
| | | }; |
| | | } |
| | | }, |
| | | computed: { |
| | | func() { return func; }, |
| | | func () { return func }, |
| | | ...mapGetters(['permission']), |
| | | permissionList() { |
| | | permissionList () { |
| | | return { |
| | | addBtn: false, |
| | | editBtn: false, |
| | | viewBtn: this.validData(this.permission.attach_view, false), |
| | | delBtn: this.validData(this.permission.attach_delete, false), |
| | | }; |
| | | } |
| | | }, |
| | | ids() { return this.selectionList.map(ele => ele.id).join(','); }, |
| | | ids () { return this.selectionList.map(ele => ele.id).join(',') }, |
| | | }, |
| | | mounted() { |
| | | this.loadAirportList(); |
| | | this.$refs.crud.setSearch({ daterange: this.query.daterange }); |
| | | this.onLoad(this.page, this.query); |
| | | mounted () { |
| | | this.loadAirportList() |
| | | this.$refs.crud.setSearch({ daterange: this.query.daterange }) |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | methods: { |
| | | loadAirportList() { |
| | | loadAirportList () { |
| | | getAirportList().then(res => { |
| | | const airportData = res.data.data || []; |
| | | const airportColumn = this.option.column.find(col => col.prop === 'airportNickname'); |
| | | const airportData = res.data.data || [] |
| | | const airportColumn = this.option.column.find(col => col.prop === 'airportNickname') |
| | | if (airportColumn) { |
| | | airportColumn.dicData = airportData.map(item => ({ |
| | | nickname: item.nickname, |
| | | workspace_id: item.workspace_id, |
| | | })); |
| | | })) |
| | | } |
| | | }).catch(error => { |
| | | console.error('加载机场列表时出错:', error); |
| | | }); |
| | | console.error('加载机场列表时出错:', error) |
| | | }) |
| | | }, |
| | | handleUpload() { |
| | | this.taskBox = true; |
| | | handleUpload () { |
| | | this.taskBox = true |
| | | }, |
| | | uploadAfter(res, done) { |
| | | this.taskBox = false; |
| | | this.refreshChange(); |
| | | done(); |
| | | uploadAfter (res, done) { |
| | | this.taskBox = false |
| | | this.refreshChange() |
| | | done() |
| | | }, |
| | | async handleRowDownload(row) { |
| | | const mediaUrl = this.domainUrl + row.object_key; |
| | | async handleRowDownload (row) { |
| | | const mediaUrl = this.domainUrl + row.object_key |
| | | try { |
| | | const response = await fetch(mediaUrl); |
| | | if (!response.ok) throw new Error('文件下载失败'); |
| | | const blob = await response.blob(); |
| | | const url = window.URL.createObjectURL(blob); |
| | | const link = document.createElement('a'); |
| | | link.href = url; |
| | | link.download = row.file_name || 'download'; |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | document.body.removeChild(link); |
| | | window.URL.revokeObjectURL(url); |
| | | this.$message({ type: 'success', message: '文件下载成功: ' + row.file_name }); |
| | | const response = await fetch(mediaUrl) |
| | | if (!response.ok) throw new Error('文件下载失败') |
| | | const blob = await response.blob() |
| | | const url = window.URL.createObjectURL(blob) |
| | | const link = document.createElement('a') |
| | | link.href = url |
| | | link.download = row.file_name || 'download' |
| | | document.body.appendChild(link) |
| | | link.click() |
| | | document.body.removeChild(link) |
| | | window.URL.revokeObjectURL(url) |
| | | this.$message({ type: 'success', message: '文件下载成功: ' + row.file_name }) |
| | | } catch (error) { |
| | | console.error('下载文件时出错:', error); |
| | | this.$message({ type: 'error', message: '下载失败: ' + error.message }); |
| | | console.error('下载文件时出错:', error) |
| | | this.$message({ type: 'error', message: '下载失败: ' + error.message }) |
| | | } |
| | | }, |
| | | handleRowDelete(row) { |
| | | handleRowDelete (row) { |
| | | this.$confirm('确定删除此文件?', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }) |
| | | .then(() => deleteAllFile(row.id)) |
| | | .then(() => { |
| | | this.onLoad(this.page); |
| | | this.$message({ type: 'success', message: '删除成功!' }); |
| | | this.onLoad(this.page) |
| | | this.$message({ type: 'success', message: '删除成功!' }) |
| | | }) |
| | | .catch(error => { |
| | | console.error('删除文件时出错:', error); |
| | | this.$message({ type: 'error', message: '删除失败,请稍后重试!' }); |
| | | }); |
| | | console.error('删除文件时出错:', error) |
| | | this.$message({ type: 'error', message: '删除失败,请稍后重试!' }) |
| | | }) |
| | | }, |
| | | rowDel(row) { |
| | | rowDel (row) { |
| | | this.$confirm('确定将选择数据及对应的文件删除?', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }) |
| | | .then(() => deleteAllFile(row.id)) |
| | | .then(() => { |
| | | this.onLoad(this.page); |
| | | this.$message({ type: 'success', message: '操作成功!' }); |
| | | }); |
| | | this.onLoad(this.page) |
| | | this.$message({ type: 'success', message: '操作成功!' }) |
| | | }) |
| | | }, |
| | | searchReset() { |
| | | const endDate = new Date(); |
| | | const startDate = new Date(); |
| | | startDate.setMonth(startDate.getMonth() - 1); |
| | | const defaultStartDate = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}-${String(startDate.getDate()).padStart(2, '0')}`; |
| | | const defaultEndDate = `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, '0')}-${String(endDate.getDate()).padStart(2, '0')}`; |
| | | this.query = { daterange: [defaultStartDate, defaultEndDate] }; |
| | | this.selectedWorkspaceId = null; |
| | | this.$refs.crud.setSearch({ daterange: this.query.daterange }); |
| | | this.onLoad(this.page, this.query); |
| | | searchReset () { |
| | | const endDate = new Date() |
| | | const startDate = new Date() |
| | | startDate.setMonth(startDate.getMonth() - 1) |
| | | const defaultStartDate = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}-${String(startDate.getDate()).padStart(2, '0')}` |
| | | const defaultEndDate = `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, '0')}-${String(endDate.getDate()).padStart(2, '0')}` |
| | | this.query = { daterange: [defaultStartDate, defaultEndDate] } |
| | | this.selectedWorkspaceId = null |
| | | this.$refs.crud.setSearch({ daterange: this.query.daterange }) |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | searchChange(params, done) { |
| | | this.query = params; |
| | | this.page.currentPage = 1; |
| | | const airportColumn = this.option.column.find(col => col.prop === 'airportNickname'); |
| | | const selectedAirport = airportColumn.dicData.find(item => item.nickname === params.airportNickname); |
| | | this.selectedWorkspaceId = selectedAirport ? selectedAirport.workspace_id : null; |
| | | this.onLoad(this.page, params); |
| | | done(); |
| | | searchChange (params, done) { |
| | | this.query = params |
| | | this.page.currentPage = 1 |
| | | const airportColumn = this.option.column.find(col => col.prop === 'airportNickname') |
| | | const selectedAirport = airportColumn.dicData.find(item => item.nickname === params.airportNickname) |
| | | this.selectedWorkspaceId = selectedAirport ? selectedAirport.workspace_id : null |
| | | this.onLoad(this.page, params) |
| | | done() |
| | | }, |
| | | selectionChange(list) { |
| | | this.selectionList = list; |
| | | selectionChange (list) { |
| | | this.selectionList = list |
| | | }, |
| | | selectionClear() { |
| | | this.selectionList = []; |
| | | this.$refs.crud.toggleSelection(); |
| | | selectionClear () { |
| | | this.selectionList = [] |
| | | this.$refs.crud.toggleSelection() |
| | | }, |
| | | currentChange(currentPage) { |
| | | this.page.currentPage = currentPage; |
| | | this.onLoad(this.page, this.query); |
| | | currentChange (currentPage) { |
| | | this.page.currentPage = currentPage |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | sizeChange(pageSize) { |
| | | this.page.pageSize = pageSize; |
| | | this.onLoad(this.page, this.query); |
| | | sizeChange (pageSize) { |
| | | this.page.pageSize = pageSize |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | refreshChange() { |
| | | this.onLoad(this.page, this.query); |
| | | refreshChange () { |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | onLoad(page, params = {}) { |
| | | this.loading = true; |
| | | const { daterange } = params; |
| | | let create_time = null; |
| | | let end_time = null; |
| | | onLoad (page, params = {}) { |
| | | this.loading = true |
| | | const { daterange } = params |
| | | let create_time = null |
| | | let end_time = null |
| | | |
| | | if (daterange && Array.isArray(daterange) && daterange.length === 2) { |
| | | const startStr = daterange[0]; |
| | | const endStr = daterange[1]; |
| | | const startDate = new Date(startStr + ' 00:00:00').getTime(); |
| | | const endDate = new Date(endStr + ' 23:59:59').getTime(); |
| | | const startStr = daterange[0] |
| | | const endStr = daterange[1] |
| | | const startDate = new Date(startStr + ' 00:00:00').getTime() |
| | | const endDate = new Date(endStr + ' 23:59:59').getTime() |
| | | if (!isNaN(startDate) && !isNaN(endDate)) { |
| | | create_time = startDate; |
| | | end_time = endDate; |
| | | create_time = startDate |
| | | end_time = endDate |
| | | } |
| | | } |
| | | |
| | | let values = { ...params, ...this.query }; |
| | | if (daterange) values.daterange = null; |
| | | let values = { ...params, ...this.query } |
| | | if (daterange) values.daterange = null |
| | | |
| | | getMedia(page.currentPage, page.pageSize, this.selectedWorkspaceId || null, create_time, end_time) |
| | | .then(res => { |
| | | const data = res.data; |
| | | const data = res.data |
| | | if (data && data.data && data.data.list) { |
| | | this.page.total = data.data.pagination.total; |
| | | this.page.total = data.data.pagination.total |
| | | this.data = data.data.list.map(item => ({ |
| | | job_name: item.job_name, |
| | | file_name: item.file_name, |
| | |
| | | payload: item.payload, |
| | | airportNickname: item.airportNickname, |
| | | id: item.id, |
| | | })); |
| | | this.domainUrl = data.data.list.length > 0 ? data.data.list[0].domain_url : 'http://localhost:2888/manage/resource'; |
| | | })) |
| | | this.domainUrl = data.data.list.length > 0 ? data.data.list[0].domain_url : 'http://localhost:2888/manage/resource' |
| | | } else { |
| | | this.data = []; |
| | | this.data = [] |
| | | } |
| | | this.loading = false; |
| | | this.selectionClear(); |
| | | this.$refs.crud.refreshTable(); |
| | | this.loading = false |
| | | this.selectionClear() |
| | | this.$refs.crud.refreshTable() |
| | | }) |
| | | .catch(error => { |
| | | this.loading = false; |
| | | console.error('加载媒体数据时出错:', error); |
| | | }); |
| | | this.loading = false |
| | | console.error('加载媒体数据时出错:', error) |
| | | }) |
| | | }, |
| | | formatCreateTime(createTime) { |
| | | if (typeof createTime !== 'number' || isNaN(createTime)) return ''; |
| | | const timestamp = createTime < 10000000000 ? createTime * 1000 : createTime; |
| | | const date = new Date(timestamp); |
| | | if (isNaN(date.getTime())) return ''; |
| | | const year = date.getFullYear(); |
| | | const month = String(date.getMonth() + 1).padStart(2, '0'); |
| | | const day = String(date.getDate()).padStart(2, '0'); |
| | | const hours = String(date.getHours()).padStart(2, '0'); |
| | | const minutes = String(date.getMinutes()).padStart(2, '0'); |
| | | const seconds = String(date.getSeconds()).padStart(2, '0'); |
| | | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; |
| | | formatCreateTime (createTime) { |
| | | if (typeof createTime !== 'number' || isNaN(createTime)) return '' |
| | | const timestamp = createTime < 10000000000 ? createTime * 1000 : createTime |
| | | const date = new Date(timestamp) |
| | | if (isNaN(date.getTime())) return '' |
| | | const year = date.getFullYear() |
| | | const month = String(date.getMonth() + 1).padStart(2, '0') |
| | | const day = String(date.getDate()).padStart(2, '0') |
| | | const hours = String(date.getHours()).padStart(2, '0') |
| | | const minutes = String(date.getMinutes()).padStart(2, '0') |
| | | const seconds = String(date.getSeconds()).padStart(2, '0') |
| | | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` |
| | | }, |
| | | handleRowView(row) { |
| | | const mediaUrl = this.domainUrl + row.object_key; |
| | | const mediaType = this.getMediaType(row.object_key); |
| | | handleRowView (row) { |
| | | const mediaUrl = this.domainUrl + row.object_key |
| | | const mediaType = this.getMediaType(row.object_key) |
| | | if (mediaType === 'image' || mediaType === 'video') { |
| | | window.open(mediaUrl, '_blank'); |
| | | window.open(mediaUrl, '_blank') |
| | | } |
| | | }, |
| | | getMediaType(objectKey) { |
| | | const extension = objectKey.split('.').pop().toLowerCase(); |
| | | if (['jpg', 'jpeg', 'png', 'gif'].includes(extension)) return 'image'; |
| | | if (['mp4', 'avi', 'mov'].includes(extension)) return 'video'; |
| | | return 'unknown'; |
| | | getMediaType (objectKey) { |
| | | const extension = objectKey.split('.').pop().toLowerCase() |
| | | if (['jpg', 'jpeg', 'png', 'gif'].includes(extension)) return 'image' |
| | | if (['mp4', 'avi', 'mov'].includes(extension)) return 'video' |
| | | return 'unknown' |
| | | }, |
| | | showVideo(url) { |
| | | this.taskBox = true; |
| | | this.taskForm = { videoUrl: url }; |
| | | showVideo (url) { |
| | | this.taskBox = true |
| | | this.taskForm = { videoUrl: url } |
| | | this.taskOption = { |
| | | submitBtn: false, |
| | | emptyBtn: false, |
| | | column: [ |
| | | { label: '视频播放', prop: 'videoUrl', type: 'video', span: 24, props: { controls: true, autoplay: false } }, |
| | | ], |
| | | }; |
| | | } |
| | | }, |
| | | validData(val, def) { |
| | | return typeof val !== 'undefined' ? val : def; |
| | | validData (val, def) { |
| | | return typeof val !== 'undefined' ? val : def |
| | | }, |
| | | async handleZipDownload() { |
| | | async handleZipDownload () { |
| | | if (this.selectionList.length === 0) { |
| | | this.$message({ type: 'warning', message: '请先选择需要下载的文件' }); |
| | | return; |
| | | this.$message({ type: 'warning', message: '请先选择需要下载的文件' }) |
| | | return |
| | | } |
| | | |
| | | this.isDownloading = true; |
| | | this.isDownloading = true |
| | | |
| | | try { |
| | | const zip = new JSZip(); |
| | | const zip = new JSZip() |
| | | const files = this.selectionList.map(item => ({ |
| | | url: this.domainUrl + item.object_key, |
| | | name: item.file_name |
| | | })); |
| | | })) |
| | | |
| | | const fetchPromises = files.map(async file => { |
| | | const response = await fetch(file.url, { cache: 'force-cache' }); |
| | | if (!response.ok) throw new Error(`下载文件 ${file.name} 失败`); |
| | | const blob = await response.blob(); |
| | | zip.file(file.name, blob); |
| | | }); |
| | | const response = await fetch(file.url, { cache: 'force-cache' }) |
| | | if (!response.ok) throw new Error(`下载文件 ${file.name} 失败`) |
| | | const blob = await response.blob() |
| | | zip.file(file.name, blob) |
| | | }) |
| | | |
| | | await Promise.all(fetchPromises); |
| | | await Promise.all(fetchPromises) |
| | | |
| | | const content = await zip.generateAsync({ |
| | | type: 'blob', |
| | | compression: 'DEFLATE', |
| | | compressionOptions: { level: 1 } |
| | | }); |
| | | }) |
| | | |
| | | const url = window.URL.createObjectURL(content); |
| | | const link = document.createElement('a'); |
| | | link.href = url; |
| | | link.download = `media_files_${new Date().toISOString().slice(0, 10)}_${new Date().getTime()}.zip`; |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | document.body.removeChild(link); |
| | | window.URL.revokeObjectURL(url); |
| | | const url = window.URL.createObjectURL(content) |
| | | const link = document.createElement('a') |
| | | link.href = url |
| | | link.download = `media_files_${new Date().toISOString().slice(0, 10)}_${new Date().getTime()}.zip` |
| | | document.body.appendChild(link) |
| | | link.click() |
| | | document.body.removeChild(link) |
| | | window.URL.revokeObjectURL(url) |
| | | |
| | | this.$message({ type: 'success', message: `成功下载 ${this.selectionList.length} 个文件` }); |
| | | this.$message({ type: 'success', message: `成功下载 ${this.selectionList.length} 个文件` }) |
| | | } catch (error) { |
| | | console.error('压缩下载失败:', error); |
| | | this.$message({ type: 'error', message: '压缩下载失败: ' + error.message }); |
| | | console.error('压缩下载失败:', error) |
| | | this.$message({ type: 'error', message: '压缩下载失败: ' + error.message }) |
| | | } finally { |
| | | this.isDownloading = false; |
| | | this.isDownloading = false |
| | | } |
| | | }, |
| | | }, |
| | | }; |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | :deep(){ |
| | | .avue-crud__body{ |
| | | .el-form{ |
| | | height: 745px; |
| | | overflow: auto; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | <style scoped lang="scss"></style> |