图片、视频加载方式
This commit is contained in:
+1
-1
@@ -18,7 +18,7 @@
|
|||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"pre-commit": "lint-staged"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
|
|||||||
+19
-1
@@ -1,3 +1,9 @@
|
|||||||
|
<!--
|
||||||
|
* @Date: 2024-05-21 21:33:04
|
||||||
|
* @LastEditors: Administrator admin@example.com
|
||||||
|
* @LastEditTime: 2024-06-17 17:59:57
|
||||||
|
* @FilePath: /txsm_webAdmin/src/App.vue
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<router-view />
|
<router-view />
|
||||||
@@ -5,17 +11,29 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import mixinSyscfg from './mixins/mixinSyscfg'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App'
|
name: 'App',
|
||||||
|
mixins: [mixinSyscfg],
|
||||||
|
async created() {
|
||||||
|
await this.getSyscfg()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.el-tooltip__popper {
|
.el-tooltip__popper {
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-table {
|
.el-table {
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
color: rgb(56, 51, 51) !important;
|
color: rgb(56, 51, 51) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tag-wrap {
|
||||||
|
// height: 200px;
|
||||||
|
overflow: scroll;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -8,13 +8,17 @@
|
|||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<quill-editor v-model="content" ref="myQuillEditor" :options="editorOption" @ready="onEditorReady($event)"></quill-editor>
|
<quill-editor
|
||||||
|
v-model="content"
|
||||||
|
ref="myQuillEditor"
|
||||||
|
:options="editorOption"
|
||||||
|
@ready="onEditorReady($event)"></quill-editor>
|
||||||
<!-- el-uploader不好手动触发上传功能 -->
|
<!-- el-uploader不好手动触发上传功能 -->
|
||||||
<uploader
|
<uploader
|
||||||
:style="{ display: 'none' }"
|
:style="{ display: 'none' }"
|
||||||
:options="{ ...options, target: '/api/web/file/uploadImg' }"
|
:options="{ ...options, target: '/api/web/file/uploadImg' }"
|
||||||
class="uploader-example"
|
class="uploader-example"
|
||||||
@file-success="imageSuccess">
|
@file-success="imageSuccess">
|
||||||
<uploader-drop>
|
<uploader-drop>
|
||||||
<uploader-btn ref="editorUploadImg" :attrs="attrsImg"></uploader-btn>
|
<uploader-btn ref="editorUploadImg" :attrs="attrsImg"></uploader-btn>
|
||||||
</uploader-drop>
|
</uploader-drop>
|
||||||
@@ -22,6 +26,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import { handleVerAutoImg } from '@/utils/index.js'
|
||||||
import 'quill/dist/quill.core.css'
|
import 'quill/dist/quill.core.css'
|
||||||
import 'quill/dist/quill.snow.css'
|
import 'quill/dist/quill.snow.css'
|
||||||
import 'quill/dist/quill.bubble.css'
|
import 'quill/dist/quill.bubble.css'
|
||||||
@@ -31,6 +36,7 @@ Link.PROTOCOL_WHITELIST = ['http', 'https', 'mailto', 'tel', 'yinseinner']
|
|||||||
import { quillEditor } from 'vue-quill-editor'
|
import { quillEditor } from 'vue-quill-editor'
|
||||||
import { ImageDrop } from 'quill-image-drop-module'
|
import { ImageDrop } from 'quill-image-drop-module'
|
||||||
import ImageResize from 'quill-image-resize-module'
|
import ImageResize from 'quill-image-resize-module'
|
||||||
|
import { data } from 'qrcode.vue'
|
||||||
Quill.register('modules/imageDrop', ImageDrop)
|
Quill.register('modules/imageDrop', ImageDrop)
|
||||||
Quill.register('modules/imageResize', ImageResize)
|
Quill.register('modules/imageResize', ImageResize)
|
||||||
|
|
||||||
@@ -49,6 +55,7 @@ export default {
|
|||||||
textNode: {
|
textNode: {
|
||||||
default: ''
|
default: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
options() {
|
options() {
|
||||||
@@ -69,7 +76,8 @@ export default {
|
|||||||
const _that = this
|
const _that = this
|
||||||
return {
|
return {
|
||||||
content: '',
|
content: '',
|
||||||
domain: this.$store.getters.getSystemConfig.webImgReq,
|
imgPath: [],
|
||||||
|
domain: this.$store.getters.getSystemConfig.webImgReq, // 不能暴露源站地址
|
||||||
attrsImg: {
|
attrsImg: {
|
||||||
accept: ['image/*']
|
accept: ['image/*']
|
||||||
},
|
},
|
||||||
@@ -105,7 +113,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// //配置富文本框图片大小调整功能
|
// //配置富文本框图片大小调整功能
|
||||||
// imageDrop: true,
|
imageDrop: true,
|
||||||
imageResize: {
|
imageResize: {
|
||||||
displayStyles: {
|
displayStyles: {
|
||||||
backgroundColor: 'black',
|
backgroundColor: 'black',
|
||||||
@@ -114,6 +122,7 @@ export default {
|
|||||||
},
|
},
|
||||||
modules: ['Resize', 'DisplaySize', 'Toolbar']
|
modules: ['Resize', 'DisplaySize', 'Toolbar']
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,33 +130,67 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {},
|
|
||||||
methods: {
|
methods: {
|
||||||
// 父组件获取数据
|
// 父组件获取数据
|
||||||
getdata() {
|
getdata() {
|
||||||
const str = this.content.replace(this.domain, '')
|
// 获取 Quill 编辑器中的所有 img 标签
|
||||||
|
const imgElements = this.$refs.myQuillEditor.quill.container.querySelectorAll('img')
|
||||||
|
// 存储自定义属性值
|
||||||
|
const customAttrValues = []
|
||||||
|
// 遍历所有 img 标签并获取自定义属性值
|
||||||
|
imgElements.forEach(img => {
|
||||||
|
const customAttrValue = img.getAttribute('data-custom') // 假设自定义属性是 data-custom
|
||||||
|
if (customAttrValue) {
|
||||||
|
customAttrValues.push(customAttrValue) // 添加到数组中
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 替换 img 标签的 src
|
||||||
|
for (let i = 0; i < imgElements.length; i++) {
|
||||||
|
const newSrc = customAttrValues[i]
|
||||||
|
const regex = new RegExp(`<img\\s+([^>]*?)src="([^"]*)"([^>]*?)>`, 'i')
|
||||||
|
|
||||||
return str
|
this.content = this.content.replace(regex, (match, beforeSrc, oldSrc, afterSrc) => {
|
||||||
|
// 使用 oldSrc 设置 data-custom 属性,同时替换 src
|
||||||
|
return `<img ${beforeSrc} src="${newSrc}" data-custom="${oldSrc}"${afterSrc}>`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return this.content
|
||||||
},
|
},
|
||||||
// 当文本框加载完成时,编译插入数据
|
// 当文本框加载完成时,编译插入数据
|
||||||
async onEditorReady(e) {
|
async onEditorReady(e) {
|
||||||
const data = this.textNode.replace('img src="', 'img src="' + this.domain)
|
this.content = this.textNode.replace(/<img\s+([^>]*?)src="([^"]*?)"[^>]*data-custom="([^"]*?)"([^>]*?)>/g, (match, before, srcValue, customValue, after) => {
|
||||||
e.container.querySelector('.ql-blank').innerHTML = data
|
// 互换 src 和 data-custom 的值
|
||||||
|
return `<img ${before}src="${customValue}" data-custom="${srcValue}"${after}>`
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
imageSuccess(rootFile, file, message) {
|
async imageSuccess(rootFile, file, message) {
|
||||||
const { code, data } = JSON.parse(message)
|
const { code, data } = JSON.parse(message)
|
||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
|
this.storageBase64 = await handleVerAutoImg(this.domain + data.path)
|
||||||
|
|
||||||
const reader = new FileReader()
|
const reader = new FileReader()
|
||||||
reader.readAsDataURL(file.file)
|
|
||||||
reader.onload = e => {
|
reader.onload = async(e) => {
|
||||||
|
const base64Data = e.target.result // 获取转换后的 Data URL
|
||||||
|
|
||||||
const myeditor = this.$refs.myQuillEditor.quill
|
const myeditor = this.$refs.myQuillEditor.quill
|
||||||
// editor方法获取当前光标位置
|
// 获取当前光标位置
|
||||||
|
const imgElement = document.createElement('img')
|
||||||
|
imgElement.src = base64Data
|
||||||
|
// 将 imgElement 插入到编辑器中
|
||||||
const index = myeditor.getSelection().index
|
const index = myeditor.getSelection().index
|
||||||
myeditor.insertEmbed(index, 'image', this.domain + data.path)
|
myeditor.insertEmbed(index, 'image', imgElement.src)
|
||||||
// 调整光标到图片之后的位置上
|
// 通过 Quill 的 API 将图片插入后,直接修改 DOM 来添加自定义属性
|
||||||
|
const imgNode = myeditor.container.querySelector(`img[src="${imgElement.src}"]`)
|
||||||
|
if (imgNode) {
|
||||||
|
imgNode.setAttribute('data-custom', data.path) // 设置自定义属性
|
||||||
|
}
|
||||||
myeditor.setSelection(index + 1)
|
myeditor.setSelection(index + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 读取 Blob 数据
|
||||||
|
reader.readAsDataURL(file.file)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
* @LastEditTime: 2020-11-24 17:04:24
|
* @LastEditTime: 2020-11-24 17:04:24
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<el-dialog append-to-body class="img_dialog" :title="title" align="center" :visible.sync="dialogVisible" width="40%" :before-close="handleClose" :close-on-click-modal="false" :modal-append-to-body='false'>
|
<el-dialog class="img_dialog" append-to-body :title="title" align="center" :visible.sync="dialogVisible" width="40%" :before-close="handleClose" :close-on-click-modal="false" :modal-append-to-body='false'>
|
||||||
<el-carousel v-if="isArry" indicator-position="outside">
|
<el-carousel v-if="isArry" indicator-position="outside">
|
||||||
<el-carousel-item v-for="item in mediaUrl" :key="item">
|
<el-carousel-item v-for="item in mediaUrl" :key="item">
|
||||||
<div class="media-box" id="img-box" > <img :src="domain+item" /></div>
|
<div class="media-box" id="img-box" > <img :src="changeImg(item)" /></div>
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
<div v-else class="media-box" id="img-box" > <img :src="mediaUrl" /></div>
|
<div v-else class="media-box" id="img-box" > <img :src="mediaUrl" /></div>
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { handleVerAutoImg } from '@/utils/index.js'
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -32,10 +33,14 @@ export default {
|
|||||||
token() {
|
token() {
|
||||||
return this.$store.state.token
|
return this.$store.state.token
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async changeImg(url) {
|
||||||
|
return await handleVerAutoImg(this.domain + url)
|
||||||
|
},
|
||||||
handleClose() {
|
handleClose() {
|
||||||
if (this.player) {
|
if (this.player) {
|
||||||
this.player.dispose()
|
this.player.dispose()
|
||||||
@@ -58,31 +63,26 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.my_data{
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.img_dialog{
|
.img_dialog{
|
||||||
::v-deep{
|
::v-deep{
|
||||||
.el-dialog__body{
|
.el-dialog__body{
|
||||||
height: auto;
|
height: auto;
|
||||||
.el-carousel__item{
|
.el-carousel__item{
|
||||||
overflow: auto !important;
|
overflow: auto !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-box {
|
.media-box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 400px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
img {
|
img {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
max-width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
#my-video {
|
#my-video {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
@@ -90,4 +90,5 @@ export default {
|
|||||||
border: none !important;
|
border: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="showImg">
|
<div class="showImg">
|
||||||
<div v-if="showNoImg">暂无</div>
|
<div v-if="showNoImg">暂无</div>
|
||||||
<el-image v-else :src="src" style="width: 100%, height: 100%" @click="checkMedia()" lazy >
|
<el-image v-else :src="src" @click="checkMedia()" lazy >
|
||||||
<div slot="placeholder" class="image-slot" :style="{width: width, height: height, lineHeight: height}">
|
<div slot="placeholder" class="image-slot" :style="{width: width, height: height, lineHeight: height}">
|
||||||
<i class="el-icon-loading"></i>加载中
|
<i class="el-icon-loading"></i>加载中
|
||||||
</div>
|
</div>
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Dialog from './components/dialog'
|
import Dialog from './components/dialog'
|
||||||
|
import { handleVerAutoImg } from '@/utils/index.js'
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -43,15 +44,12 @@ export default {
|
|||||||
},
|
},
|
||||||
props: ['width', 'height', 'urls'],
|
props: ['width', 'height', 'urls'],
|
||||||
watch: {
|
watch: {
|
||||||
urls(newval, oldval) {
|
async urls(newval, oldval) {
|
||||||
this.urls = newval
|
this.urls = newval
|
||||||
// if (this.type && this.type === 'daichong') {
|
|
||||||
// this.domain = ''
|
|
||||||
// }
|
|
||||||
this.imgsUrl = []
|
this.imgsUrl = []
|
||||||
if (this.urls) { // 判断是否存在
|
if (this.urls) { // 判断是否存在
|
||||||
if (typeof (this.urls) === 'string') { // 判断是单张图片还是数组
|
if (typeof (this.urls) === 'string') { // 判断是单张图片还是数组
|
||||||
this.src = this.domain + this.urls
|
this.src = await handleVerAutoImg(this.domain + this.urls)
|
||||||
this.showNoImg = false
|
this.showNoImg = false
|
||||||
} else {
|
} else {
|
||||||
if (this.urls.length) { // 判断是否为空数组
|
if (this.urls.length) { // 判断是否为空数组
|
||||||
@@ -60,8 +58,8 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.showChangeBtn = true
|
this.showChangeBtn = true
|
||||||
}
|
}
|
||||||
this.urls.forEach(item => {
|
this.urls.forEach(async item => {
|
||||||
this.imgsUrl.push(this.domain + item)
|
this.imgsUrl.push(await handleVerAutoImg(this.domain + this.urls))
|
||||||
})
|
})
|
||||||
this.src = this.imgsUrl[0]
|
this.src = this.imgsUrl[0]
|
||||||
this.showNoImg = false
|
this.showNoImg = false
|
||||||
@@ -75,11 +73,11 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
async mounted() {
|
||||||
this.imgsUrl = []
|
this.imgsUrl = []
|
||||||
if (this.urls) { // 判断是否存在
|
if (this.urls) { // 判断是否存在
|
||||||
if (typeof (this.urls) === 'string') { // 判断是单张图片还是数组
|
if (typeof (this.urls) === 'string') { // 判断是单张图片还是数组
|
||||||
this.src = this.domain + this.urls
|
this.src = await handleVerAutoImg(this.domain + this.urls)
|
||||||
} else {
|
} else {
|
||||||
if (this.urls.length) { // 判断是否为空数组
|
if (this.urls.length) { // 判断是否为空数组
|
||||||
if (this.urls.length === 1) { // 判断数组中是否只有一张图片
|
if (this.urls.length === 1) { // 判断数组中是否只有一张图片
|
||||||
@@ -87,8 +85,8 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.showChangeBtn = true
|
this.showChangeBtn = true
|
||||||
}
|
}
|
||||||
this.urls.forEach(item => {
|
this.urls.forEach(async item => {
|
||||||
this.imgsUrl.push(this.domain + item)
|
this.imgsUrl.push(await handleVerAutoImg(this.domain + item))
|
||||||
})
|
})
|
||||||
this.src = this.imgsUrl[0]
|
this.src = this.imgsUrl[0]
|
||||||
} else {
|
} else {
|
||||||
@@ -118,12 +116,12 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 查看媒体
|
// 查看媒体
|
||||||
checkMedia() {
|
async checkMedia() {
|
||||||
if (this.urls) { // 判断是否存在
|
if (this.urls) { // 判断是否存在
|
||||||
if (typeof (this.urls) === 'string') { // 判断是单张图片还是数组
|
if (typeof (this.urls) === 'string') { // 判断是单张图片还是数组
|
||||||
this.$refs.dialog.open(this.domain + this.urls, 'img')
|
this.$refs.dialog.open(await handleVerAutoImg(this.domain + this.urls), 'img')
|
||||||
} else {
|
} else {
|
||||||
this.$refs.dialog.open(this.urls, 'img')
|
this.$refs.dialog.open(this.imgsUrl, 'img')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,12 @@
|
|||||||
<span>视频时长:{{ this.myData.playTime + "s" }}</span>
|
<span>视频时长:{{ this.myData.playTime + "s" }}</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="media-box" id="media-box"></div> -->
|
<!-- <div class="media-box" id="media-box"></div> -->
|
||||||
<div v-if="mediaUrl" style="width: 400px; heigth: 130px; background: red;margin-top:10px">
|
<div v-if="mediaUrl" style="width: 100%; heigth: 200px; background: red">
|
||||||
<DPlayer
|
<DPlayer
|
||||||
ref="player"
|
ref="player"
|
||||||
:video="{
|
:video="{
|
||||||
url: mediaUrl,
|
url: mediaUrl,
|
||||||
type: type === 'mp4' ? '' : 'hls',
|
type: type=== 'mp4' ?'':'hls',
|
||||||
pic: '',
|
pic: '',
|
||||||
}"
|
}"
|
||||||
hotkey
|
hotkey
|
||||||
@@ -53,7 +53,7 @@ export default {
|
|||||||
title: '封面图查看',
|
title: '封面图查看',
|
||||||
params: {},
|
params: {},
|
||||||
myData: {},
|
myData: {},
|
||||||
type: undefined,
|
type: undefined,
|
||||||
domain: '/api/web/media/m3u8/' // 存放图片的域名
|
domain: '/api/web/media/m3u8/' // 存放图片的域名
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -79,6 +79,7 @@ export default {
|
|||||||
// 视频审查列表
|
// 视频审查列表
|
||||||
videoFeviewList() {
|
videoFeviewList() {
|
||||||
videoFeviewList(this.params, this.id).then((res) => {
|
videoFeviewList(this.params, this.id).then((res) => {
|
||||||
|
|
||||||
// this.myData = res.data,
|
// this.myData = res.data,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -93,18 +94,35 @@ export default {
|
|||||||
this.myData = { ...data }
|
this.myData = { ...data }
|
||||||
this.dialogVisible = true
|
this.dialogVisible = true
|
||||||
this.title = '视频查看'
|
this.title = '视频查看'
|
||||||
this.mediaUrl =
|
if (url.indexOf('mp4') !== -1) {
|
||||||
this.domain + (url.match(RegExp(/.m3u8/)) ? url : url + '.m3u8')
|
this.mediaUrl = this.$store.getters.getSystemConfig.mp4Url + url
|
||||||
if (url.indexOf('mp4') !== -1) {
|
|
||||||
this.mediaUrl = this.$store.getters.getSystemConfig.webImgReq + url
|
|
||||||
this.type = 'mp4'
|
this.type = 'mp4'
|
||||||
} else {
|
} else {
|
||||||
this.mediaUrl =
|
this.mediaUrl =
|
||||||
this.domain + (url.match(RegExp(/.m3u8/)) ? url : url + '.m3u8')
|
this.domain + (url.match(RegExp(/.m3u8/)) ? url : url + '.m3u8')
|
||||||
this.videoFeviewList()
|
this.videoFeviewList()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// + '&token=' + this.token
|
||||||
|
// this.id = id;
|
||||||
|
// this.$nextTick(function () {
|
||||||
|
// document.getElementById("media-box").innerHTML =
|
||||||
|
// '<video id="my-video" class="video-js vjs-default-skin" controls preload="auto" style="width:100%;height:100%"></video>';
|
||||||
|
// this.player = videojs(
|
||||||
|
// "my-video",
|
||||||
|
// {
|
||||||
|
// bigPlayButton: false,
|
||||||
|
// textTrackDisplay: false,
|
||||||
|
// posterImage: true,
|
||||||
|
// errorDisplay: true,
|
||||||
|
// controlBar: true,
|
||||||
|
// },
|
||||||
|
// function () {
|
||||||
|
// this.play();
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// this.player.src(this.mediaUrl);
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,28 +2,35 @@
|
|||||||
* @Author: 王涛
|
* @Author: 王涛
|
||||||
* @Mail: no
|
* @Mail: no
|
||||||
* @Date: 2020-09-29 19:56:44
|
* @Date: 2020-09-29 19:56:44
|
||||||
* @LastEditors: Please set LastEditors
|
* @LastEditors: Administrator admin@example.com
|
||||||
* @LastEditTime: 2022-06-21 20:05:54
|
* @LastEditTime: 2024-11-19 10:14:08
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<!-- 使用方法 <UploadImg @changeImgUrl='changeMobileAvatar' :img='form.mobileAvatar' :width='"100px"' :height='"100px"'></UploadImg>
|
<!-- 使用方法 <UploadImg @changeImgUrl='changeMobileAvatar' :img='form.mobileAvatar' :width='"100px"' :height='"100px"'></UploadImg>
|
||||||
changeMobileAvatar(data) {
|
changeMobileAvatar(data) {
|
||||||
this.form.mobileAvatar = data
|
this.form.mobileAvatar = data
|
||||||
}, -->
|
}, -->
|
||||||
<el-upload class="avatar-uploader" action="/api/web/file/uploadImg" :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
|
<el-upload
|
||||||
|
class="avatar-uploader"
|
||||||
|
action="/api/web/file/uploadImg"
|
||||||
|
:show-file-list="false"
|
||||||
|
:on-success="handleAvatarSuccess"
|
||||||
|
:before-upload="beforeAvatarUpload">
|
||||||
<div ref="uploader">
|
<div ref="uploader">
|
||||||
<img v-if="imageUrl" :src="domain + imageUrl" class="avatar" />
|
<img v-if="newImg" :src="newImg" class="avatar" />
|
||||||
<i v-if="imageUrl" @click.stop="handleRemove" class="el-icon-delete"></i>
|
<i v-if="imageUrl" @click.stop="handleRemove" class="el-icon-delete"></i>
|
||||||
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
||||||
</div>
|
</div>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import { handleVerAutoImg } from '@/utils/index.js'
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
domain: this.$store.getters.getSystemConfig.webImgReq,
|
domain: this.$store.getters.getSystemConfig.webImgReq,
|
||||||
imageUrl: ''
|
imageUrl: '',
|
||||||
|
newImg: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
@@ -38,11 +45,23 @@ export default {
|
|||||||
height: {
|
height: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '180px'
|
default: '180px'
|
||||||
|
},
|
||||||
|
index: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
showIndex: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
img: function(val, oldval) {
|
img: function(val, oldval) {
|
||||||
this.imageUrl = val
|
this.imageUrl = val
|
||||||
|
},
|
||||||
|
imageUrl: async function(val, oldval) {
|
||||||
|
const a = await handleVerAutoImg(this.domain + val)
|
||||||
|
this.newImg = a
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -56,6 +75,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async changeImg(url) {
|
||||||
|
|
||||||
|
},
|
||||||
handleAvatarSuccess(res, file) {
|
handleAvatarSuccess(res, file) {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
this.$message({
|
this.$message({
|
||||||
@@ -74,11 +96,19 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
changeImgUrl() {
|
changeImgUrl() {
|
||||||
this.$emit('changeImgUrl', this.imageUrl)
|
if (this.showIndex) {
|
||||||
|
this.$emit('changeImgUrl', { url: this.imageUrl, index: this.index })
|
||||||
|
} else {
|
||||||
|
this.$emit('changeImgUrl', this.imageUrl)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
handleRemove(f) {
|
handleRemove(f) {
|
||||||
this.imageUrl = ''
|
this.imageUrl = ''
|
||||||
this.$emit('onRemove', f)
|
if (this.showIndex) {
|
||||||
|
this.$emit('onRemove', { key: f, index: this.index })
|
||||||
|
} else {
|
||||||
|
this.$emit('onRemove', f)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// 上传前进行压缩
|
// 上传前进行压缩
|
||||||
beforeAvatarUpload(file) {
|
beforeAvatarUpload(file) {
|
||||||
@@ -100,7 +130,7 @@ export default {
|
|||||||
// message: '上传图片大小不能超过 2MB!!'
|
// message: '上传图片大小不能超过 2MB!!'
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
return isJPG
|
return isJPG
|
||||||
},
|
},
|
||||||
|
|
||||||
// 图片等比压缩
|
// 图片等比压缩
|
||||||
@@ -142,19 +172,21 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.avatar-uploader .el-upload {
|
.avatar-uploader {
|
||||||
border: 1px dashed #d9d9d9;
|
.el-upload {
|
||||||
border-radius: 6px;
|
border: 1px dashed #d9d9d9;
|
||||||
cursor: pointer;
|
border-radius: 6px;
|
||||||
position: relative;
|
cursor: pointer;
|
||||||
overflow: hidden;
|
position: relative;
|
||||||
}
|
overflow: hidden;
|
||||||
.avatar-uploader .el-upload:hover {
|
}
|
||||||
border-color: #409eff;
|
.el-upload:hover {
|
||||||
|
border-color: #409eff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.avatar-uploader-icon {
|
.avatar-uploader-icon {
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
color: #8c939d;
|
color: #d9d9d9;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
line-height: 100%;
|
line-height: 100%;
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
<div>
|
<div>
|
||||||
<draggable v-model="locaImg" class="list-group" tag="ul" v-bind="dragOptions" @start="drag = true" @end="drag = false">
|
<draggable v-model="locaImg" class="list-group" tag="ul" v-bind="dragOptions" @start="drag = true" @end="drag = false">
|
||||||
<div v-for="(img,index) in locaImg" :key="index" class="image-list" style="float: left;">
|
<div v-for="(img,index) in locaImg" :key="index" class="image-list" style="float: left;">
|
||||||
<img class="el-upload-list__item-thumbnail image-detail" :src="domain+img" alt="">
|
<img class="el-upload-list__item-thumbnail image-detail" :src="imgSrc[index]" alt="">
|
||||||
<!-- 遮罩层 -->
|
<!-- 遮罩层 -->
|
||||||
<a href="#">
|
<a href="#">
|
||||||
<div class="image-mask">
|
<div class="image-mask">
|
||||||
<span class="add" @click="handlePictureCardPreview(domain+img)">
|
<span class="add" @click="handlePictureCardPreview(imgSrc[index])">
|
||||||
<i class="el-icon-view"></i>
|
<i class="el-icon-view"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="delete" @click="removeImage(index)">
|
<span class="delete" @click="removeImage(index)">
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import draggable from 'vuedraggable'
|
import draggable from 'vuedraggable'
|
||||||
|
import { handleVerAutoImg } from '@/utils/index.js'
|
||||||
export default {
|
export default {
|
||||||
components: { draggable },
|
components: { draggable },
|
||||||
data() {
|
data() {
|
||||||
@@ -46,7 +47,8 @@ export default {
|
|||||||
// { name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100' }
|
// { name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100' }
|
||||||
],
|
],
|
||||||
drag: false, // 拖拽效果是否开启
|
drag: false, // 拖拽效果是否开启
|
||||||
locaImg: []
|
locaImg: [],
|
||||||
|
imgSrc: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
@@ -57,6 +59,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
dragOptions() {
|
dragOptions() {
|
||||||
return {
|
return {
|
||||||
@@ -66,6 +69,7 @@ export default {
|
|||||||
ghostClass: 'ghost'
|
ghostClass: 'ghost'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
// 监听拖动事件改变时,传出新的图片数组
|
// 监听拖动事件改变时,传出新的图片数组
|
||||||
@@ -80,15 +84,23 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
async mounted() {
|
||||||
this.locaImg = []
|
this.locaImg = []
|
||||||
if (this.img) {
|
if (this.img) {
|
||||||
this.img.filter((item) => {
|
this.img.filter((item) => {
|
||||||
this.locaImg.push(item)
|
this.locaImg.push(item)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 在组件挂载时加载图像 URL
|
||||||
|
this.imgSrc = await Promise.all(this.locaImg.map(img => this.changeImg(img)))
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async changeImg(img) {
|
||||||
|
// 这里应该替换为真实的异步代码
|
||||||
|
const a = await handleVerAutoImg(this.domain + img)
|
||||||
|
return a
|
||||||
|
},
|
||||||
|
|
||||||
handleChange(file, fileList) {
|
handleChange(file, fileList) {
|
||||||
if (file.status === 'success') {
|
if (file.status === 'success') {
|
||||||
this.locaImg.push(file.response.data.path)
|
this.locaImg.push(file.response.data.path)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div v-on:paste="handlePaste" v-drag="handleDrag" >
|
<div v-on:paste="handlePaste" v-drag="handleDrag" >
|
||||||
<img v-if='imageUrl' ref="preview" :src="domain+imageUrl" alt="" style="width:300px;height:300px;">
|
<img v-if='newImg' ref="preview" :src="newImg" alt="" style="width:300px;height:300px;">
|
||||||
<div v-else style="width:300px;height:300px;border:1px solid;padding:20px;">
|
<div v-else style="width:300px;height:300px;border:1px solid;padding:20px;">
|
||||||
<div style="text-indent:2em;">将图片按<span style="color:red">cmd+C复制</span>到粘贴板,<span style="color:red">cmd+V粘贴</span>至此处;</div>
|
<div style="text-indent:2em;">将图片按<span style="color:red">cmd+C复制</span>到粘贴板,<span style="color:red">cmd+V粘贴</span>至此处;</div>
|
||||||
<div style="text-indent:2em;">或者将图片拖拽至此处</div>
|
<div style="text-indent:2em;">或者将图片拖拽至此处</div>
|
||||||
@@ -18,6 +18,8 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { mediaUploadImg } from '@/api/components/UploadImgPaste'
|
import { mediaUploadImg } from '@/api/components/UploadImgPaste'
|
||||||
|
import { handleVerAutoImg } from '@/utils/index.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -34,6 +36,10 @@ export default {
|
|||||||
watch: {
|
watch: {
|
||||||
img: function(val) {
|
img: function(val) {
|
||||||
this.imageUrl = val
|
this.imageUrl = val
|
||||||
|
},
|
||||||
|
imageUrl: async function(val, oldval) {
|
||||||
|
const a = await handleVerAutoImg(this.domain + val)
|
||||||
|
this.newImg = a
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -44,6 +50,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
handleDrag(event) {
|
handleDrag(event) {
|
||||||
const items = Array.from(event.dataTransfer.items)
|
const items = Array.from(event.dataTransfer.items)
|
||||||
let file = null
|
let file = null
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { getSyscfg } from '@/api/system/systemConfig'
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
async getSyscfg() {
|
||||||
|
const tk = getToken()
|
||||||
|
if (!tk) return
|
||||||
|
try {
|
||||||
|
const res = await getSyscfg({})
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.form = res.data
|
||||||
|
this.$store.dispatch('system/setConfig', res.data)
|
||||||
|
} else {
|
||||||
|
this.$message.error('请求系统配置失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('get syscfg error:::', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
* @Author: 王涛
|
* @Author: 王涛
|
||||||
* @Mail: no
|
* @Mail: no
|
||||||
* @Date: 2020-10-10 14:27:58
|
* @Date: 2020-10-10 14:27:58
|
||||||
* @LastEditors: Please set LastEditors
|
* @LastEditors: 江涛
|
||||||
* @LastEditTime: 2022-03-14 15:29:54
|
* @LastEditTime: 2021-03-24 19:34:23
|
||||||
*/
|
*/
|
||||||
const state = {
|
const state = {
|
||||||
config: {
|
config: {
|
||||||
@@ -15,7 +15,7 @@ const state = {
|
|||||||
driverGroup: undefined, // 开车群
|
driverGroup: undefined, // 开车群
|
||||||
headerM3U8: undefined, // 片头m3u8
|
headerM3U8: undefined, // 片头m3u8
|
||||||
id: 0,
|
id: 0,
|
||||||
webImgReq: 'http://resourceyuan.bbaazz.me/', // 图片请求域名(web使用)
|
webImgReq: '', // 图片请求域名(web使用)
|
||||||
imgReq: undefined, // 图片请求域名(app使用)
|
imgReq: undefined, // 图片请求域名(app使用)
|
||||||
imgUpload: undefined, // 图片上传地址
|
imgUpload: undefined, // 图片上传地址
|
||||||
inviteAddr: undefined, // 用户邀请地址
|
inviteAddr: undefined, // 用户邀请地址
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
// import { Buffer } from 'buffer/'
|
||||||
|
// 判断是否加解密,如果字节前几位对应上,则不需要解密
|
||||||
|
const encryptMagicNumber = new Uint8Array([
|
||||||
|
0x88,
|
||||||
|
0xA8,
|
||||||
|
0x30,
|
||||||
|
0xCB,
|
||||||
|
0x10,
|
||||||
|
0x76
|
||||||
|
])
|
||||||
|
// 解密密钥
|
||||||
|
// const _decryptKey = Buffer.from('2019ysapp7527') // 加密key
|
||||||
|
// 避免vite单独引入buffer库 提前进行编码
|
||||||
|
const _decryptKey = [50, 48, 49, 57, 121, 115, 97, 112, 112, 55, 53, 50, 55]// 加密key
|
||||||
|
|
||||||
|
const _encryptedLen = 100 // 加密图片的数据长度
|
||||||
|
|
||||||
|
// / 加密密钥(????,不解就去找游总解答)
|
||||||
|
const ENCRYPT_KEY = 0xA3
|
||||||
|
// 三种图片 type类型,根据前几子节可以判断出类型,这是固定的。如需要增加其他类型则自己上网找固定对应的字节。
|
||||||
|
const _featuresList = [
|
||||||
|
new Uint8Array([0xFF, 0xD8, 0xFF]), // jpg,jpeg
|
||||||
|
new Uint8Array([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]), // png
|
||||||
|
new Uint8Array([0x47, 0x49, 0x46]) // gif
|
||||||
|
]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解密入口
|
||||||
|
*/
|
||||||
|
export function decryptImage(imgBytes) {
|
||||||
|
// 判断是否为空,如果传入的字节为空则不处理
|
||||||
|
if (imgBytes === null || imgBytes.length === 0) { return }
|
||||||
|
|
||||||
|
// 增加一个变量来判断是否存在
|
||||||
|
|
||||||
|
let isAll = false
|
||||||
|
// 循环魔法密钥,确定这是需要解密的图片是全部长度,而不是前100字节
|
||||||
|
for (let i = 0; i < encryptMagicNumber.length; i++) {
|
||||||
|
if (encryptMagicNumber[i] !== imgBytes[i]) { continue }
|
||||||
|
|
||||||
|
isAll = true
|
||||||
|
}
|
||||||
|
if (isAll) {
|
||||||
|
imgBytes = xorBaseAllLength(imgBytes)
|
||||||
|
} else {
|
||||||
|
// 是需要解密的
|
||||||
|
|
||||||
|
if (isEncryptedImage(imgBytes)) {
|
||||||
|
// 解密结果
|
||||||
|
imgBytes = xorBaseLength(imgBytes, _decryptKey, _encryptedLen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return imgBytes
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回一个判断值,true则代表 是png gif jpg三种图片中的一种,则需要解密
|
||||||
|
*/
|
||||||
|
function isEncryptedImage(imgBytes) {
|
||||||
|
let isDecrypted = false
|
||||||
|
const _featuresLen = _featuresList.length
|
||||||
|
for (let i = 0; i < _featuresLen; i++) {
|
||||||
|
// 每次进入则初始化变量的值为假
|
||||||
|
isDecrypted = false
|
||||||
|
for (let j = 0; j < _featuresList[i].length; j++) {
|
||||||
|
if (_featuresList[i][j] !== imgBytes[j]) {
|
||||||
|
isDecrypted = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isDecrypted) { continue } else { break }
|
||||||
|
}
|
||||||
|
return isDecrypted
|
||||||
|
}
|
||||||
|
// 解密算法
|
||||||
|
function xorBaseLength(src, key, length) {
|
||||||
|
const srcLen = src.length
|
||||||
|
const keyLen = key.length
|
||||||
|
if (length > srcLen || length <= 0) { length = srcLen }
|
||||||
|
|
||||||
|
for (let i = 0; i < length; i += keyLen) {
|
||||||
|
for (let j = 0; j < keyLen && i + j < length; j++) { src[i + j] ^= key[j] }
|
||||||
|
}
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全部长度解密,解密算法
|
||||||
|
function xorBaseAllLength(src) {
|
||||||
|
let index = -1
|
||||||
|
// 这里map数组内 所有的字节做位异或运数,返回的是解密后的数组
|
||||||
|
const dest = src.map((it) => {
|
||||||
|
index++
|
||||||
|
if (
|
||||||
|
index < encryptMagicNumber.length &&
|
||||||
|
it === encryptMagicNumber[index]
|
||||||
|
) { return null }
|
||||||
|
|
||||||
|
return it ^ ENCRYPT_KEY
|
||||||
|
})
|
||||||
|
return dest
|
||||||
|
}
|
||||||
|
|
||||||
+86
-1
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Created by PanJiaChen on 16/11/18.
|
* Created by PanJiaChen on 16/11/18.
|
||||||
*/
|
*/
|
||||||
|
import { decryptImage } from './imgCode.js'
|
||||||
/**
|
/**
|
||||||
* Parse the time to string
|
* Parse the time to string
|
||||||
* @param {(Object|string|number)} time
|
* @param {(Object|string|number)} time
|
||||||
@@ -227,3 +227,88 @@ export function getQueryString(name) {
|
|||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
export async function handleVerAutoImg(imageUrl) {
|
||||||
|
// 参数校验
|
||||||
|
if (!imageUrl || typeof imageUrl !== 'string') {
|
||||||
|
console.warn('无效的图片URL:', imageUrl)
|
||||||
|
return imageUrl // 返回原始URL
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查URL是否已经是Blob URL
|
||||||
|
if (imageUrl.startsWith('blob:')) {
|
||||||
|
return imageUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const controller = new AbortController()
|
||||||
|
const timeoutId = setTimeout(() => controller.abort(), 10000) // 10秒超时
|
||||||
|
|
||||||
|
const response = await fetch(imageUrl, {
|
||||||
|
signal: controller.signal,
|
||||||
|
headers: {
|
||||||
|
'Accept': 'image/*'
|
||||||
|
}
|
||||||
|
}).finally(() => clearTimeout(timeoutId))
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
console.warn(`图片加载失败: ${response.status} ${response.statusText}`)
|
||||||
|
return imageUrl // 返回原始URL
|
||||||
|
}
|
||||||
|
|
||||||
|
const arrayBuffer = await response.arrayBuffer()
|
||||||
|
const bytes = new Uint8Array(arrayBuffer)
|
||||||
|
|
||||||
|
// 基本验证:检查是否为有效的图片数据
|
||||||
|
if (bytes.length === 0) {
|
||||||
|
// console.warn('图片数据为空')
|
||||||
|
return imageUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 尝试解密图片数据
|
||||||
|
const decryptedData = decryptImage(bytes)
|
||||||
|
|
||||||
|
// 验证解密后的数据
|
||||||
|
if (!decryptedData || decryptedData.length === 0) {
|
||||||
|
// console.warn('图片解密结果无效')
|
||||||
|
return imageUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建Blob URL前检查数据有效性
|
||||||
|
const blob = new Blob([decryptedData], { type: 'image/jpeg' })
|
||||||
|
if (blob.size === 0) {
|
||||||
|
// console.warn('解密后的图片数据为空')
|
||||||
|
return imageUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
const blobUrl = URL.createObjectURL(blob)
|
||||||
|
|
||||||
|
// 添加清理逻辑
|
||||||
|
window.addEventListener('unload', () => {
|
||||||
|
try {
|
||||||
|
URL.revokeObjectURL(blobUrl)
|
||||||
|
} catch (e) {
|
||||||
|
// 忽略清理错误
|
||||||
|
console.log(e, 'e')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return blobUrl
|
||||||
|
} catch (decryptError) {
|
||||||
|
console.warn('图片解密失败,使用原始URL:', decryptError)
|
||||||
|
return imageUrl
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// 处理特定类型的错误
|
||||||
|
if (error.name === 'AbortError') {
|
||||||
|
// console.warn('图片加载超时')
|
||||||
|
} else if (error instanceof TypeError) {
|
||||||
|
// console.warn('网络请求失败')
|
||||||
|
} else {
|
||||||
|
// console.warn('图片处理失败:', error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回原始URL而不是抛出错误
|
||||||
|
return imageUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,25 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog :title="title" :visible.sync="Visible" width="780px" center class="ac-dialog" :close-on-click-modal="false"
|
<el-dialog
|
||||||
|
:title="title"
|
||||||
|
:visible.sync="Visible"
|
||||||
|
width="780px"
|
||||||
|
center
|
||||||
|
class="ac-dialog"
|
||||||
|
:close-on-click-modal="false"
|
||||||
@close="close">
|
@close="close">
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col >
|
<el-col >
|
||||||
<h3>AI生成的视频URl</h3>
|
<h3>AI生成的视频URl</h3>
|
||||||
<div v-if="form.vidUrl" style="width: 380px; height: 240px; overflow: hidden">
|
<div v-if="form.vidUrl" style="width: 380px; height: 240px; overflow: hidden">
|
||||||
<DPlayer ref="player" v-if="form.vidUrl.indexOf('mp4') === -1" :video="{
|
<DPlayer
|
||||||
|
ref="player"
|
||||||
|
v-if="form.vidUrl.indexOf('mp4') === -1"
|
||||||
|
:video="{
|
||||||
url: '/api/web/media/m3u8/' + filterM3u8(form.vidUrl),
|
url: '/api/web/media/m3u8/' + filterM3u8(form.vidUrl),
|
||||||
type: 'hls',
|
type: 'hls',
|
||||||
pic: '',
|
pic: '',
|
||||||
}" hotkey ></DPlayer>
|
}"
|
||||||
<DPlayer ref="player" v-else :video="{
|
hotkey ></DPlayer>
|
||||||
url: this.$store.getters.getSystemConfig.webImgReq + form.vidUrl,
|
<DPlayer
|
||||||
|
ref="player"
|
||||||
|
v-else
|
||||||
|
:video="{
|
||||||
|
url: this.$store.getters.getSystemConfig.mp4Url + form.vidUrl,
|
||||||
type: 'mp4',
|
type: 'mp4',
|
||||||
pic: '',
|
pic: '',
|
||||||
}" hotkey ></DPlayer>
|
}"
|
||||||
|
hotkey ></DPlayer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-form :inline="true" :model="form" :rules="rules" ref="form" class="demo-form-inline" label-width="120px"
|
<el-form
|
||||||
|
:inline="true"
|
||||||
|
:model="form"
|
||||||
|
:rules="rules"
|
||||||
|
ref="form"
|
||||||
|
class="demo-form-inline"
|
||||||
|
label-width="120px"
|
||||||
label-position="right">
|
label-position="right">
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
|
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
@@ -43,8 +63,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="Visible = false"> 取 消 </el-button>
|
<el-button @click="Visible = false"> 取 消 </el-button>
|
||||||
<el-button type="primary" @click="submit('form')"> 确 定 </el-button>
|
<el-button type="primary" @click="submit('form')"> 确 定 </el-button>
|
||||||
@@ -76,15 +95,15 @@ export default {
|
|||||||
formData: {},
|
formData: {},
|
||||||
// 表单数据
|
// 表单数据
|
||||||
form: {
|
form: {
|
||||||
"byWay": undefined,
|
'byWay': undefined,
|
||||||
"id": undefined,
|
'id': undefined,
|
||||||
"modifyImgs": undefined,
|
'modifyImgs': undefined,
|
||||||
"vidUrl": undefined,
|
'vidUrl': undefined,
|
||||||
"reason": undefined,
|
'reason': undefined,
|
||||||
"status": 0,
|
'status': 0,
|
||||||
"updatedAt": undefined
|
'updatedAt': undefined
|
||||||
},
|
},
|
||||||
rules: {},
|
rules: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -95,22 +114,20 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
//TODO:新增应用列表数据
|
// TODO:新增应用列表数据
|
||||||
|
|
||||||
filterM3u8(v) {
|
filterM3u8(v) {
|
||||||
return /\.m3u8/g.test(v) ? v : v + '.m3u8'
|
return /\.m3u8/g.test(v) ? v : v + '.m3u8'
|
||||||
},
|
},
|
||||||
//TODO:编辑应用列表数据
|
// TODO:编辑应用列表数据
|
||||||
update(data) {
|
update(data) {
|
||||||
|
|
||||||
aiorderFacechangeUpdate(data).then((res) => {
|
aiorderFacechangeUpdate(data).then((res) => {
|
||||||
if (res && res.code === 200) {
|
if (res && res.code === 200) {
|
||||||
this.$message.success(res.data ? res.data : '更新成功')
|
this.$message.success(res.data ? res.data : '更新成功')
|
||||||
} else {
|
} else {
|
||||||
this.$message.error(res.data ? res.data : '更新失败')
|
this.$message.error(res.data ? res.data : '更新失败')
|
||||||
}
|
}
|
||||||
this.Visible = false
|
this.Visible = false
|
||||||
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 提交按钮
|
// 提交按钮
|
||||||
@@ -145,16 +162,16 @@ export default {
|
|||||||
changeCoverImgUrl(data) {
|
changeCoverImgUrl(data) {
|
||||||
this.form.modifyImgs = data
|
this.form.modifyImgs = data
|
||||||
},
|
},
|
||||||
|
|
||||||
// 关闭编辑
|
// 关闭编辑
|
||||||
close() {
|
close() {
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
},
|
},
|
||||||
|
|
||||||
onClear(data) {
|
onClear(data) {
|
||||||
this.form[data] = undefined
|
this.form[data] = undefined
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +1,46 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog :title="title" :visible.sync="Visible" width="780px" center class="ac-dialog" :close-on-click-modal="false"
|
<el-dialog
|
||||||
|
:title="title"
|
||||||
|
:visible.sync="Visible"
|
||||||
|
width="780px"
|
||||||
|
center
|
||||||
|
class="ac-dialog"
|
||||||
|
:close-on-click-modal="false"
|
||||||
@close="close">
|
@close="close">
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col>
|
<el-col>
|
||||||
<h3>AI生成的视频URl</h3>
|
<h3>AI生成的视频URl</h3>
|
||||||
<div v-if="form.modifyVideoUrl" style="width: 380px; height: 240px; overflow: hidden">
|
<div v-if="form.modifyVideoUrl" style="width: 380px; height: 240px; overflow: hidden">
|
||||||
|
|
||||||
<DPlayer ref="player" v-if="form.modifyVideoUrl.indexOf('mp4') === -1" :video="{
|
<DPlayer
|
||||||
|
ref="player"
|
||||||
|
v-if="form.modifyVideoUrl.indexOf('mp4') === -1"
|
||||||
|
:video="{
|
||||||
url: '/api/web/media/m3u8/' + filterM3u8(form.modifyVideoUrl),
|
url: '/api/web/media/m3u8/' + filterM3u8(form.modifyVideoUrl),
|
||||||
type: 'hls',
|
type: 'hls',
|
||||||
pic: '',
|
pic: '',
|
||||||
}" hotkey ></DPlayer>
|
}"
|
||||||
<DPlayer ref="player" v-else :video="{
|
hotkey ></DPlayer>
|
||||||
url: this.$store.getters.getSystemConfig.webImgReq + form.modifyVideoUrl,
|
<DPlayer
|
||||||
|
ref="player"
|
||||||
|
v-else
|
||||||
|
:video="{
|
||||||
|
url: this.$store.getters.getSystemConfig.mp4Url + form.modifyVideoUrl,
|
||||||
type: 'mp4',
|
type: 'mp4',
|
||||||
pic: '',
|
pic: '',
|
||||||
}" hotkey ></DPlayer>
|
}"
|
||||||
|
hotkey ></DPlayer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-form :inline="true" :model="form" :rules="rules" ref="form" class="demo-form-inline" label-width="120px"
|
<el-form
|
||||||
|
:inline="true"
|
||||||
|
:model="form"
|
||||||
|
:rules="rules"
|
||||||
|
ref="form"
|
||||||
|
class="demo-form-inline"
|
||||||
|
label-width="120px"
|
||||||
label-position="right">
|
label-position="right">
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
|
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
@@ -31,7 +51,10 @@
|
|||||||
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
|
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
<el-form-item label="换脸方式">
|
<el-form-item label="换脸方式">
|
||||||
<el-select placeholder="请选择换脸方式" clearable v-model="form.byWay">
|
<el-select placeholder="请选择换脸方式" clearable v-model="form.byWay">
|
||||||
<el-option :key="item.value" :label="item.label" :value="item.value"
|
<el-option
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
v-for="item in aiOrderFaceChangeList" />
|
v-for="item in aiOrderFaceChangeList" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -51,7 +74,6 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="Visible = false"> 取 消 </el-button>
|
<el-button @click="Visible = false"> 取 消 </el-button>
|
||||||
<el-button type="primary" @click="submit('form')"> 确 定 </el-button>
|
<el-button type="primary" @click="submit('form')"> 确 定 </el-button>
|
||||||
@@ -83,15 +105,15 @@ export default {
|
|||||||
formData: {},
|
formData: {},
|
||||||
// 表单数据
|
// 表单数据
|
||||||
form: {
|
form: {
|
||||||
"byWay": undefined,
|
'byWay': undefined,
|
||||||
"id": undefined,
|
'id': undefined,
|
||||||
"modifyImgs": undefined,
|
'modifyImgs': undefined,
|
||||||
"modifyVideoUrl": undefined,
|
'modifyVideoUrl': undefined,
|
||||||
"reason": undefined,
|
'reason': undefined,
|
||||||
"status": 0,
|
'status': 0,
|
||||||
"updatedAt": undefined
|
'updatedAt': undefined
|
||||||
},
|
},
|
||||||
rules: {},
|
rules: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -102,18 +124,15 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
//TODO:新增应用列表数据
|
// TODO:新增应用列表数据
|
||||||
|
|
||||||
filterM3u8(v) {
|
filterM3u8(v) {
|
||||||
return /\.m3u8/g.test(v) ? v : v + '.m3u8'
|
return /\.m3u8/g.test(v) ? v : v + '.m3u8'
|
||||||
},
|
},
|
||||||
//TODO:编辑应用列表数据
|
// TODO:编辑应用列表数据
|
||||||
update(data) {
|
update(data) {
|
||||||
|
|
||||||
aiorderStripUpdate(data).then((res) => {
|
aiorderStripUpdate(data).then((res) => {
|
||||||
|
if (res && res.code === 200) {
|
||||||
|
|
||||||
if (res && res.code === 200) {
|
|
||||||
this.$message.success(res.data ? res.data : '更新成功')
|
this.$message.success(res.data ? res.data : '更新成功')
|
||||||
} else {
|
} else {
|
||||||
this.$message.error(res.data ? res.data : '更新失败')
|
this.$message.error(res.data ? res.data : '更新失败')
|
||||||
@@ -161,8 +180,8 @@ export default {
|
|||||||
|
|
||||||
onClear(data) {
|
onClear(data) {
|
||||||
this.form[data] = undefined
|
this.form[data] = undefined
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,159 +1,129 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog :title="title" :visible.sync="Visible" width="1800px" center class="ac-dialog" :close-on-click-modal="false" @close="close">
|
<el-dialog
|
||||||
|
:title="title"
|
||||||
|
:visible.sync="Visible"
|
||||||
|
width="1800px"
|
||||||
|
center
|
||||||
|
class="ac-dialog"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
@close="close">
|
||||||
<el-form :inline="true" :model="form" class="demo-form-inline" label-width="120px" label-position="right">
|
<el-form :inline="true" :model="form" class="demo-form-inline" label-width="120px" label-position="right">
|
||||||
<el-row :gutter="24">
|
<div>
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
<el-form-item label="标题">
|
||||||
<el-form-item label="标题">
|
<el-input v-model="form.title" style="width: 315px" />
|
||||||
<el-input v-model="form.title" style="width: 315px" />
|
</el-form-item>
|
||||||
</el-form-item>
|
</div>
|
||||||
</el-col>
|
<div>
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
<el-form-item label="封面">
|
||||||
<el-form-item label="封面类型">
|
<UploadImg @changeImgUrl="changeCoverImgUrl" :img="form.coverImg" @onRemove="handleRemove('coverImg')">
|
||||||
<el-select style="width: 180px" placeholder="请选择封面类型" v-model="form.coverType">
|
</UploadImg>
|
||||||
<el-option :key="item.value" :label="item.label" :value="item.value" v-for="item in coverTypeList" />
|
</el-form-item>
|
||||||
</el-select>
|
</div>
|
||||||
</el-form-item>
|
<el-form-item label="影片类型">
|
||||||
</el-col>
|
<el-select clearable placeholder="影片类型" v-model="form.type" style="width: 180px">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
<el-option label="长视频" value="longvideo" />
|
||||||
<el-form-item label="视频归类">
|
<el-option label="短视频" value="shortvideo" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="视频归类">
|
||||||
<el-select placeholder="请选择视频归类" v-model="videoType" style="width: 180px">
|
<el-select placeholder="请选择视频归类" v-model="videoType" style="width: 180px">
|
||||||
<el-option :key="item.value" :label="item.label" :value="item.value" v-for="item in formVideoTypeList" />
|
<el-option :key="item.value" :label="item.label" :value="item.value" v-for="item in formVideoTypeList" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
<div>
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
<el-form-item label="APP">
|
||||||
<el-form-item label="封面">
|
<el-select multiple placeholder="APP" v-model="form.appids" style="width: 180px">
|
||||||
<UploadImg @changeImgUrl="changeCoverImgUrl" :img="form.coverImg"></UploadImg>
|
<el-option label="麻豆APP" :value="1" />
|
||||||
</el-form-item>
|
<el-option label="麻豆官网" :value="2" />
|
||||||
</el-col>
|
<el-option label="逼喱逼喱" :value="3" />
|
||||||
<el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
|
</el-select>
|
||||||
<el-form-item label="番号">
|
</el-form-item>
|
||||||
<el-input v-model="form.bango" style="width: 315px" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
|
|
||||||
<el-form-item label="演员">
|
|
||||||
<el-input v-model="form.actors" placeholder="可填多人,中间用',/。/,'等符号分割" style="width:315px" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
|
|
||||||
<el-form-item label="视频归属">
|
|
||||||
<el-input v-model="form.mediaSet" style="width: 315px" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row :gutter="24">
|
|
||||||
<el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
|
|
||||||
<el-form-item label="一级标签:">
|
|
||||||
<el-input v-model="form.firstTag" placeholder="请输入一级标签,中间用',/。/,'等符号分割" style="width:315px" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
|
|
||||||
<el-form-item label="二级标签">
|
|
||||||
<el-input v-model="form.secondTags" placeholder="请输入二级标签,中间用',/。/,'等符号分割" style="width:315px" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row :gutter="24">
|
|
||||||
<el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
|
|
||||||
<el-form-item label="APP">
|
|
||||||
<el-select multiple placeholder="APP" v-model="form.appids" style="width: 180px">
|
|
||||||
<el-option :key="item.value" :label="item.label" :value="item.value" v-for="item in appidsList" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
|
|
||||||
<el-form-item label="视频类型">
|
|
||||||
<el-select placeholder="请选择视频类型" v-model="form.formatType" style="width: 180px">
|
|
||||||
<el-option :key="item.value" :label="item.label" :value="item.value" v-for="item in formatTypeList" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
|
|
||||||
<el-form-item label="内容类型">
|
|
||||||
<el-select placeholder="请选择内容类型" v-model="form.contentType" style="width: 180px">
|
|
||||||
<el-option :key="item.value" :label="item.label" :value="item.value" v-for="item in contentTypeList" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :lg="8" :md="8" :sm="8" :xl="8" :xs="8">
|
|
||||||
<el-form-item label="发布者">
|
|
||||||
<el-input v-model="form.publish" placeholder="请输入发布者" style="width: 180px" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :lg="8" :md="8" :sm="8" :xl="8" :xs="8">
|
|
||||||
<el-form-item label="所有者">
|
|
||||||
<el-input v-model="form.studio" placeholder="请输入所有者" style="width: 180px" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :lg="8" :md="8" :sm="8" :xl="8" :xs="8">
|
|
||||||
<el-form-item label="上架时间">
|
|
||||||
<el-date-picker style="width: 180px" v-model="form.addedTime" type="date" placeholder="选择日期" value-format="yyyy-MM-ddTHH:mm:ssZ">
|
|
||||||
</el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row :gutter="24">
|
|
||||||
|
|
||||||
<el-col :lg="12" :md="12" :sm="12" :xl="12" :xs="12">
|
|
||||||
<el-form-item label="正片地址">
|
|
||||||
<el-input v-model="form.fieldNameFs" style="width: 515px" disabled="disabled" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :lg="12" :md="12" :sm="12" :xl="12" :xs="12">
|
|
||||||
<el-form-item label="预览地址">
|
|
||||||
<el-input v-model="form.preFileName" style="width: 515px">
|
|
||||||
<el-button slot="append" @click="innerVisible = true">自定义设置预览</el-button>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :lg="24" :md="24" :sm="24" :xl="24" :xs="24">
|
|
||||||
<el-form-item label="详细描述">
|
|
||||||
<el-input v-model="form.desc" type="textarea" style="width: 515px" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
<div style="position: absolute;top: 50px;right: 50px">
|
|
||||||
<div style="float:left">
|
|
||||||
<h3>预览</h3>
|
|
||||||
<div v-if="form.preFileName" style="width: 380px; height: 240px; overflow: hidden">
|
|
||||||
<DPlayer ref="player" v-if="form.preFileName.indexOf('mp4') === -1" :video="{
|
|
||||||
url: '/api/web/media/m3u8/' + filterM3u8(form.preFileName),
|
|
||||||
type: 'hls',
|
|
||||||
pic: '',
|
|
||||||
}" hotkey></DPlayer>
|
|
||||||
<DPlayer ref="player" v-else :video="{
|
|
||||||
url: this.$store.getters.getSystemConfig.webImgReq + form.preFileName,
|
|
||||||
type: 'mp4',
|
|
||||||
pic: '',
|
|
||||||
}" hotkey></DPlayer>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div style="float:left">
|
<div>
|
||||||
<h3>正片</h3>
|
<el-form-item label="上架时间">
|
||||||
<div v-if="form.fieldNameFs" style="width: 380px; height: 240px; overflow: hidden">
|
<el-date-picker
|
||||||
<DPlayer ref="player" v-if="form.fieldNameFs.indexOf('mp4') === -1" :video="{
|
style="width: 180px"
|
||||||
url: '/api/web/media/m3u8/' + filterM3u8(form.fieldNameFs),
|
v-model="form.addedTime"
|
||||||
type: 'hls',
|
type="date"
|
||||||
pic: '',
|
placeholder="选择日期"
|
||||||
}" hotkey></DPlayer>
|
value-format="yyyy-MM-ddTHH:mm:ssZ">
|
||||||
<DPlayer ref="player" v-else :video="{
|
</el-date-picker>
|
||||||
url: this.$store.getters.getSystemConfig.webImgReq + form.fieldNameFs,
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-form-item label="正片地址">
|
||||||
|
<el-input v-model="form.fieldNameFs" style="width: 515px" disabled="disabled" />
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-form-item label="预览地址">
|
||||||
|
<el-input v-model="form.preFileName" style="width: 515px">
|
||||||
|
<el-button slot="append" @click="innerVisible = true">自定义设置预览</el-button>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<el-form-item label="详细描述">
|
||||||
|
<el-input v-model="form.desc" type="textarea" style="width: 515px" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div style="position: absolute; top: 50px; right: 10px">
|
||||||
|
<h3>正片</h3>
|
||||||
|
<div v-if="form.fieldNameFs" style="width: 380px; height: 240px; overflow: hidden">
|
||||||
|
<DPlayer
|
||||||
|
ref="player"
|
||||||
|
v-if="form.fieldNameFs.indexOf('mp4') === -1"
|
||||||
|
:video="{
|
||||||
|
url: '/api/web/media/m3u8/' + filterM3u8(form.fieldNameFs),
|
||||||
|
type: 'hls',
|
||||||
|
pic: '',
|
||||||
|
}"
|
||||||
|
hotkey></DPlayer>
|
||||||
|
<DPlayer
|
||||||
|
ref="player"
|
||||||
|
v-else
|
||||||
|
:video="{
|
||||||
|
url: this.$store.getters.getSystemConfig.mp4Url + form.fieldNameFs,
|
||||||
type: 'mp4',
|
type: 'mp4',
|
||||||
pic: '',
|
pic: '',
|
||||||
}" hotkey></DPlayer>
|
}"
|
||||||
</div>
|
hotkey></DPlayer>
|
||||||
<UploadVideo v-if="videoType" @changeVideoUrl="changeVideoUrl" :type="videoType" @repeatVideo="repeatVideo"
|
</div>
|
||||||
|
<UploadVideo
|
||||||
|
v-if="videoType"
|
||||||
|
@changeVideoUrl="changeVideoUrl"
|
||||||
|
:type="videoType"
|
||||||
|
@repeatVideo="repeatVideo"
|
||||||
style="max-width: 520px"></UploadVideo>
|
style="max-width: 520px"></UploadVideo>
|
||||||
<div v-else class="check_upload" @click.prevent="checkUpload">
|
<div v-else class="check_upload" @click.prevent="checkUpload">
|
||||||
<div>
|
<div>
|
||||||
选择文件
|
选择文件
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="position: absolute; top: 50px; right: 410px">
|
||||||
|
<h3>预览</h3>
|
||||||
|
<div v-if="form.preFileName" style="width: 380px; height: 240px; overflow: hidden">
|
||||||
|
<DPlayer
|
||||||
|
ref="player"
|
||||||
|
v-if="form.preFileName.indexOf('mp4') === -1"
|
||||||
|
:video="{
|
||||||
|
url: '/api/web/media/m3u8/' + filterM3u8(form.preFileName),
|
||||||
|
type: 'hls',
|
||||||
|
pic: '',
|
||||||
|
}"
|
||||||
|
hotkey></DPlayer>
|
||||||
|
<DPlayer
|
||||||
|
ref="player"
|
||||||
|
v-else
|
||||||
|
:video="{
|
||||||
|
url: this.$store.getters.getSystemConfig.mp4Url + form.preFileName,
|
||||||
|
type: 'mp4',
|
||||||
|
pic: '',
|
||||||
|
}"
|
||||||
|
hotkey></DPlayer>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click.native.prevent="Visible = false"> 取 消 </el-button>
|
<el-button @click.native.prevent="Visible = false"> 取 消 </el-button>
|
||||||
@@ -169,7 +139,6 @@
|
|||||||
时:
|
时:
|
||||||
<el-input-number :min="0" :max="24" size="mini" v-model="previewTimeData.h"></el-input-number>
|
<el-input-number :min="0" :max="24" size="mini" v-model="previewTimeData.h"></el-input-number>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
分:
|
分:
|
||||||
<el-input-number :min="0" :max="59" size="mini" v-model="previewTimeData.m"></el-input-number>
|
<el-input-number :min="0" :max="59" size="mini" v-model="previewTimeData.m"></el-input-number>
|
||||||
@@ -193,68 +162,68 @@
|
|||||||
<script>
|
<script>
|
||||||
import DPlayer from '@/components/VueDplayerHls/index'
|
import DPlayer from '@/components/VueDplayerHls/index'
|
||||||
import UploadImg from '@/components/UploadImg/index'
|
import UploadImg from '@/components/UploadImg/index'
|
||||||
import UploadVideo from '@/components/UploadVideoLibrary/index'
|
import UploadVideo from '@/components/UploadVideo/index'
|
||||||
import 'videojs-contrib-hls'
|
import 'videojs-contrib-hls'
|
||||||
import { mediaUpdate, updatePreTime } from '@/api/mediaLibrary/videoList'
|
import { mediaUpdate, updatePreTime } from '@/api/mediaLibrary/videoList'
|
||||||
import { stringToArry, arryToString, current } from '@/filters/index'
|
import { stringToArry, arryToString } from '@/filters/index'
|
||||||
import {
|
import { StatusList, formVideoTypeList } from '@/filters/mediaLibrary/videoList'
|
||||||
coverTypeList,
|
import { current } from '@/filters/index'
|
||||||
appidsList,
|
|
||||||
formatTypeList,
|
|
||||||
formVideoTypeList
|
|
||||||
} from '@/filters/mediaLibrary/videoList'
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AddOrEdit',
|
name: 'AddOrEdit',
|
||||||
props: ['data','contentTypeList'],
|
props: ['data'],
|
||||||
components: {
|
components: {
|
||||||
UploadImg,
|
UploadImg,
|
||||||
UploadVideo,
|
UploadVideo,
|
||||||
DPlayer,
|
DPlayer
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
totalTime() {
|
totalTime() {
|
||||||
return this.data.data.videoTime
|
return this.data.data.videoTime
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
coverTypeList: coverTypeList(),
|
|
||||||
appidsList: appidsList(),
|
|
||||||
formatTypeList: formatTypeList(),
|
|
||||||
formVideoTypeList: formVideoTypeList(),
|
|
||||||
type: undefined,
|
|
||||||
videoType: undefined,
|
|
||||||
innerVisible: false,
|
innerVisible: false,
|
||||||
Visible: true,
|
Visible: true,
|
||||||
title: '',
|
title: '',
|
||||||
defaltTime: current() + 'T12:00:00.000Z',
|
defaltTime: current() + 'T12:00:00.000Z',
|
||||||
taskId: '',
|
taskId: '',
|
||||||
|
StatusList: StatusList(),
|
||||||
|
formVideoTypeList: formVideoTypeList(),
|
||||||
tags: null,
|
tags: null,
|
||||||
fieldNameFs: '', // 正片地址全称
|
fieldNameFs: '', // 正片地址全称
|
||||||
form: {
|
secondTags: [],
|
||||||
formatType: undefined, // 视频类型 1:长视频 2:短视频 3:预览
|
FirstTagList: [],
|
||||||
mediaSet: undefined, // 视频归属
|
|
||||||
contentType: undefined, // 内容类型 1:av(日本) 2:国产(短视频) 3:动漫
|
|
||||||
coverType: undefined, // 封面类型 1:竖版 2:横版 3:系统
|
|
||||||
|
|
||||||
title: undefined, // 'string',标题
|
form: {
|
||||||
addedTime: undefined, // 'string',上架时间
|
|
||||||
publish: undefined, // 'string',视频发布者
|
|
||||||
firstTag: undefined, // 'string',一级标签
|
|
||||||
secondTags: undefined, // [],二级标签标签
|
|
||||||
bango: undefined, // 'string',番号
|
|
||||||
appids: [],
|
appids: [],
|
||||||
desc: undefined, // 'string',详细描述
|
|
||||||
preFileName: undefined, // 'string',预览文件
|
|
||||||
coverImg: undefined, // 封面
|
|
||||||
actors: undefined, // [],演员
|
actors: undefined, // [],演员
|
||||||
|
addedTime: undefined, // 'string',上架时间
|
||||||
|
bango: undefined, // 'string',番号
|
||||||
|
checkSum: undefined, // 'string',md5校验码
|
||||||
|
country: undefined, // 'string',国家
|
||||||
|
coverImg: undefined, // 封面
|
||||||
|
desc: undefined, // 'string',详细描述
|
||||||
|
directors: undefined, // [],导演
|
||||||
|
firstTag: undefined, // 'string',一级标签
|
||||||
|
preFileName: undefined, // 'string',预览文件
|
||||||
|
preview: undefined, // 0,预览普通视频
|
||||||
|
publish: undefined, // 'string',视频发布者
|
||||||
|
secondTags: undefined, // [],二级标签标签
|
||||||
|
size: undefined, // 0,文件大小
|
||||||
|
status: undefined, // 'string',当前状态
|
||||||
studio: undefined, // 'string',工作室/所有者
|
studio: undefined, // 'string',工作室/所有者
|
||||||
|
title: undefined, // 'string',标题
|
||||||
|
type: undefined, // 'string',长视频/短视频
|
||||||
|
videoTime: undefined // 0,影片长度
|
||||||
},
|
},
|
||||||
previewTimeData: {
|
previewTimeData: {
|
||||||
h: 0,
|
h: 0,
|
||||||
m: 0,
|
m: 0,
|
||||||
s: 0,
|
s: 0
|
||||||
},
|
},
|
||||||
|
type: undefined,
|
||||||
|
videoType: undefined
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -263,8 +232,7 @@ export default {
|
|||||||
if (this.title === '编辑') {
|
if (this.title === '编辑') {
|
||||||
this.form = { ...this.data.data }
|
this.form = { ...this.data.data }
|
||||||
this.form.actors = arryToString(this.form.actors)
|
this.form.actors = arryToString(this.form.actors)
|
||||||
this.form.secondTags = arryToString(this.form.secondTags)
|
this.form.directors = arryToString(this.form.directors)
|
||||||
this.form.mediaSet = arryToString(this.form.mediaSet)
|
|
||||||
if (this.form.fieldNameFs) {
|
if (this.form.fieldNameFs) {
|
||||||
this.open()
|
this.open()
|
||||||
}
|
}
|
||||||
@@ -273,16 +241,44 @@ export default {
|
|||||||
this.player.dispose()
|
this.player.dispose()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
checkUpload() {
|
checkUpload() {
|
||||||
if (!this.type) {
|
if (!this.videoType) {
|
||||||
return this.$message({
|
return this.$message({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: '请选择视频归类!!'
|
message: '请选择视频归类!!'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//TODO:编辑影片列表数据
|
// TODO:新增视频时绑定煤资库ID
|
||||||
|
async subimitPTime() {
|
||||||
|
let s = 0
|
||||||
|
if (this.previewTimeData.h) {
|
||||||
|
s += this.previewTimeData.h * 60 * 60
|
||||||
|
}
|
||||||
|
if (this.previewTimeData.m) {
|
||||||
|
s += this.previewTimeData.m * 60
|
||||||
|
}
|
||||||
|
s += this.previewTimeData.s
|
||||||
|
if (s > 0 && s + 15 <= this.data.data.videoTime - 15) {
|
||||||
|
const data = {
|
||||||
|
id: this.data.data.id,
|
||||||
|
preFileTime: s
|
||||||
|
}
|
||||||
|
updatePreTime(data).then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.$message.success('预览时长设置成功')
|
||||||
|
this.innerVisible = false
|
||||||
|
} else {
|
||||||
|
this.$message.error('预览时长设置失败')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$message.error('预览时长设置不能为零或不能超过播放时长')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// TODO:提交视频列表数据
|
||||||
update(data) {
|
update(data) {
|
||||||
mediaUpdate(data).then((res) => {
|
mediaUpdate(data).then((res) => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
@@ -296,6 +292,9 @@ export default {
|
|||||||
filterM3u8(v) {
|
filterM3u8(v) {
|
||||||
return /\.m3u8/g.test(v) ? v : v + '.m3u8'
|
return /\.m3u8/g.test(v) ? v : v + '.m3u8'
|
||||||
},
|
},
|
||||||
|
handleRemove(key) {
|
||||||
|
this.form[key] = ''
|
||||||
|
},
|
||||||
// 清空某一项筛选列表
|
// 清空某一项筛选列表
|
||||||
onClear(key) {
|
onClear(key) {
|
||||||
this.form.param[key] = []
|
this.form.param[key] = []
|
||||||
@@ -304,57 +303,52 @@ export default {
|
|||||||
this.previewTimeData = {
|
this.previewTimeData = {
|
||||||
h: 0,
|
h: 0,
|
||||||
m: 0,
|
m: 0,
|
||||||
s: 0,
|
s: 0
|
||||||
}
|
}
|
||||||
this.innerVisible = false
|
this.innerVisible = false
|
||||||
},
|
},
|
||||||
async subimitPTime() {
|
|
||||||
let s = 0
|
|
||||||
if (this.previewTimeData.h) {
|
|
||||||
s += this.previewTimeData.h * 60 * 60
|
|
||||||
}
|
|
||||||
if (this.previewTimeData.m) {
|
|
||||||
s += this.previewTimeData.m * 60
|
|
||||||
}
|
|
||||||
s += this.previewTimeData.s
|
|
||||||
if (s > 0 && s + 15 <= this.data.data.videoTime - 15) {
|
|
||||||
const res = await updatePreTime({
|
|
||||||
id: this.data.data.id,
|
|
||||||
preFileTime: s,
|
|
||||||
})
|
|
||||||
if (res.code === 200) {
|
|
||||||
this.$message.success('预览时长设置成功')
|
|
||||||
this.innerVisible = false
|
|
||||||
} else {
|
|
||||||
this.$message.error('预览时长设置失败')
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.$message.error('预览时长设置不能为零或不能超过播放时长')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 提交按钮
|
// 提交按钮
|
||||||
submit() {
|
submit() {
|
||||||
const data = { ...this.form }
|
const data = { ...this.form }
|
||||||
data.actors = data.actors ? stringToArry(data.actors) : []
|
data.actors = data.actors ? stringToArry(data.actors) : []
|
||||||
data.secondTags = data.secondTags ? stringToArry(data.secondTags) : []
|
data.directors = data.directors ? stringToArry(data.directors) : []
|
||||||
data.mediaSet = data.mediaSet ? stringToArry(data.mediaSet) : []
|
const YY = new Date().getUTCFullYear()
|
||||||
data.addedTime = data.addedTime
|
const MM =
|
||||||
? data.addedTime === '0001-01-01T00:00:00Z'
|
new Date().getMonth() + 1 < 10
|
||||||
? this.defaltTime
|
? `0${new Date().getMonth() + 1}`
|
||||||
: data.addedTime
|
: new Date().getMonth() + 1
|
||||||
: this.defaltTime
|
const DD =
|
||||||
|
new Date().getUTCDate() < 10
|
||||||
|
? `0${new Date().getUTCDate()}`
|
||||||
|
: new Date().getUTCDate()
|
||||||
|
const HH =
|
||||||
|
new Date().getUTCHours() < 10
|
||||||
|
? `0${new Date().getUTCHours()}`
|
||||||
|
: new Date().getUTCHours()
|
||||||
|
const MU =
|
||||||
|
new Date().getUTCMinutes() < 10
|
||||||
|
? `0${new Date().getUTCMinutes()}`
|
||||||
|
: new Date().getUTCMinutes()
|
||||||
|
const SS =
|
||||||
|
new Date().getUTCSeconds() < 10
|
||||||
|
? `0${new Date().getUTCSeconds()}`
|
||||||
|
: new Date().getUTCSeconds()
|
||||||
|
const MS =
|
||||||
|
new Date().getUTCMilliseconds() < 10
|
||||||
|
? `0${new Date().getUTCMilliseconds()}`
|
||||||
|
: new Date().getUTCMilliseconds()
|
||||||
|
data.addedTime =
|
||||||
|
data.addedTime || `${YY}-${MM}-${DD}T${HH}:${MU}:${SS}.${MS}Z`
|
||||||
this.update(data)
|
this.update(data)
|
||||||
},
|
},
|
||||||
|
|
||||||
// 上传视频返回地址
|
// 上传视频返回地址
|
||||||
changeVideoUrl(data) {
|
changeVideoUrl(data) {
|
||||||
this.form.id = data.id
|
this.form.id = data.id
|
||||||
// this.$set(this.form, 'fieldNameFs', data.videoUri)
|
|
||||||
this.fieldNameFs = data.videoUri
|
this.fieldNameFs = data.videoUri
|
||||||
// this.form.fieldNameFs = data.videoUri
|
this.form.videoTime = parseInt(data.duration)
|
||||||
// this.form.videoTime = parseInt(data.duration)
|
this.form.size = data.size
|
||||||
// this.form.size = data.size
|
|
||||||
// this.open()
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 重复上传视频
|
// 重复上传视频
|
||||||
@@ -368,36 +362,23 @@ export default {
|
|||||||
this.form.coverImg = data
|
this.form.coverImg = data
|
||||||
},
|
},
|
||||||
// / 监听视频播放的回调函数
|
// / 监听视频播放的回调函数
|
||||||
onPlayerPlay() {},
|
onPlayerPlay() { },
|
||||||
// / 监听暂停播放的回调函数
|
// / 监听暂停播放的回调函数
|
||||||
onPlayerPause() {},
|
onPlayerPause() { },
|
||||||
// / 监听当前视频数据加载完成
|
// / 监听当前视频数据加载完成
|
||||||
onPlayerLoadeddata() {},
|
onPlayerLoadeddata() { },
|
||||||
// / 监听当前视频数据加载失败
|
// / 监听当前视频数据加载失败
|
||||||
onPlayerError() {},
|
onPlayerError() { },
|
||||||
// / 监听当前视频数据加载ing
|
// / 监听当前视频数据加载ing
|
||||||
onPlayerWaiting() {},
|
onPlayerWaiting() { },
|
||||||
// / 监听当前视频播放完成
|
// / 监听当前视频播放完成
|
||||||
onPlayerEnded() {},
|
onPlayerEnded() { },
|
||||||
open() {
|
open() {
|
||||||
this.mediaUrl =
|
this.mediaUrl =
|
||||||
'api/web/media/m3u8/' +
|
'api/web/media/m3u8' +
|
||||||
(this.form.fieldNameFs.match(RegExp(/.m3u8/))
|
(this.form.fieldNameFs.match(RegExp(/.m3u8/))
|
||||||
? this.form.fieldNameFs
|
? this.form.fieldNameFs
|
||||||
: this.form.fieldNameFs + '.m3u8')
|
: this.form.fieldNameFs + '.m3u8')
|
||||||
// this.$nextTick(function () {
|
|
||||||
// document.getElementById("media-box").innerHTML =
|
|
||||||
// '<video id="my-video" class="video-js vjs-default-skin" controls preload="auto" style="width:100%;height:100%; " playsinline="true"></video>';
|
|
||||||
// this.player = videojs("my-video", {
|
|
||||||
// bigPlayButton: false,
|
|
||||||
// textTrackDisplay: false,
|
|
||||||
// posterImage: true,
|
|
||||||
// errorDisplay: true,
|
|
||||||
// controlBar: true,
|
|
||||||
// playbackRates: [0.5, 1, 1.5, 2, 3, 5, 10],
|
|
||||||
// });
|
|
||||||
// this.player.src(this.mediaUrl);
|
|
||||||
// });
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 关闭编辑
|
// 关闭编辑
|
||||||
@@ -406,8 +387,8 @@ export default {
|
|||||||
this.player.dispose()
|
this.player.dispose()
|
||||||
}
|
}
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@@ -423,10 +404,12 @@ export default {
|
|||||||
max-height: calc(100% - 30px);
|
max-height: calc(100% - 30px);
|
||||||
max-width: calc(100% - 30px);
|
max-width: calc(100% - 30px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-dialog .el-dialog__body {
|
.el-dialog .el-dialog__body {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.videoBox {
|
.videoBox {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -436,15 +419,18 @@ export default {
|
|||||||
.el-textarea.is-disabled.ti .el-textarea__inner {
|
.el-textarea.is-disabled.ti .el-textarea__inner {
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-box {
|
.media-box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 400px;
|
height: 400px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#my-video {
|
#my-video {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
|
|||||||
@@ -0,0 +1,469 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
:title="title"
|
||||||
|
:visible.sync="Visible"
|
||||||
|
width="1800px"
|
||||||
|
center
|
||||||
|
class="ac-dialog"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
@close="close">
|
||||||
|
<el-form :inline="true" :model="form" class="demo-form-inline" label-width="120px" label-position="right">
|
||||||
|
<div>
|
||||||
|
<el-form-item label="标题">
|
||||||
|
<el-input v-model="form.title" style="width: 315px" />
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-form-item label="封面">
|
||||||
|
<UploadImg @changeImgUrl="changeCoverImgUrl" :img="form.coverImg" @onRemove="handleRemove('coverImg')">
|
||||||
|
</UploadImg>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<el-form-item label="影片类型">
|
||||||
|
<el-select clearable placeholder="影片类型" v-model="form.type" style="width: 180px">
|
||||||
|
<el-option label="长视频" value="longvideo" />
|
||||||
|
<el-option label="短视频" value="shortvideo" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="视频归类">
|
||||||
|
<el-select placeholder="请选择视频归类" v-model="videoType" style="width: 180px">
|
||||||
|
<el-option :key="item.value" :label="item.label" :value="item.value" v-for="item in formVideoTypeList" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<div>
|
||||||
|
<el-form-item label="APP">
|
||||||
|
<el-select placeholder="APP" v-model="form.appids" style="width: 180px">
|
||||||
|
<el-option label="麻豆APP" :value="1" />
|
||||||
|
<el-option label="麻豆官网" :value="2" />
|
||||||
|
<el-option label="逼喱逼喱" :value="3" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-form-item label="上架时间">
|
||||||
|
<el-date-picker
|
||||||
|
style="width: 180px"
|
||||||
|
v-model="form.addedTime"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择日期"
|
||||||
|
value-format="yyyy-MM-ddTHH:mm:ssZ">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-form-item label="正片地址">
|
||||||
|
<el-input v-model="form.fieldNameFs" style="width: 515px" disabled="disabled" />
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-form-item label="预览地址">
|
||||||
|
<el-input v-model="form.preFileName" style="width: 515px">
|
||||||
|
<el-button slot="append" @click="innerVisible = true">自定义设置预览</el-button>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<el-form-item label="详细描述">
|
||||||
|
<el-input v-model="form.desc" type="textarea" style="width: 515px" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div style="position: absolute; top: 50px; right: 10px">
|
||||||
|
<h3>正片</h3>
|
||||||
|
<div v-if="form.fieldNameFs" style="width: 380px; height: 240px; overflow: hidden">
|
||||||
|
<DPlayer
|
||||||
|
ref="player"
|
||||||
|
v-if="form.fieldNameFs.indexOf('mp4') === -1"
|
||||||
|
:video="{
|
||||||
|
url: '/api/web/media/m3u8/' + filterM3u8(form.fieldNameFs),
|
||||||
|
type: 'hls',
|
||||||
|
pic: ''
|
||||||
|
}"
|
||||||
|
hotkey></DPlayer>
|
||||||
|
<DPlayer
|
||||||
|
ref="player"
|
||||||
|
v-else
|
||||||
|
:video="{
|
||||||
|
url:
|
||||||
|
this.$store.getters.getSystemConfig.mp4Url + form.fieldNameFs,
|
||||||
|
type: 'mp4',
|
||||||
|
pic: ''
|
||||||
|
}"
|
||||||
|
hotkey></DPlayer>
|
||||||
|
</div>
|
||||||
|
<UploadVideo
|
||||||
|
v-if="videoType"
|
||||||
|
@changeVideoUrl="changeVideoUrl"
|
||||||
|
:appId="form.appids ? form.appids : 888"
|
||||||
|
:type="videoType"
|
||||||
|
@repeatVideo="repeatVideo"
|
||||||
|
style="max-width: 520px"></UploadVideo>
|
||||||
|
<div v-else class="check_upload" @click.prevent="checkUpload">
|
||||||
|
<div>
|
||||||
|
选择文件
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="position: absolute; top: 50px; right: 410px">
|
||||||
|
<h3>预览</h3>
|
||||||
|
<div v-if="form.preFileName" style="width: 380px; height: 240px; overflow: hidden">
|
||||||
|
<DPlayer
|
||||||
|
ref="player"
|
||||||
|
v-if="form.preFileName.indexOf('mp4') === -1"
|
||||||
|
:video="{
|
||||||
|
url: '/api/web/media/m3u8/' + filterM3u8(form.preFileName),
|
||||||
|
type: 'hls',
|
||||||
|
pic: ''
|
||||||
|
}"
|
||||||
|
hotkey></DPlayer>
|
||||||
|
<DPlayer
|
||||||
|
ref="player"
|
||||||
|
v-else
|
||||||
|
:video="{
|
||||||
|
url:
|
||||||
|
this.$store.getters.getSystemConfig.mp4Url + form.preFileName,
|
||||||
|
type: 'mp4',
|
||||||
|
pic: ''
|
||||||
|
}"
|
||||||
|
hotkey></DPlayer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click.native.prevent="Visible = false"> 取 消 </el-button>
|
||||||
|
<el-button type="primary" @click.native.prevent="submit('ruleForm')">
|
||||||
|
确 定
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<el-dialog width="30%" title="设置预览时长" :visible.sync="innerVisible" append-to-body>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24" style="text-align: center">
|
||||||
|
<div><span>总时长:</span>{{ totalTime }}s</div>
|
||||||
|
<div>
|
||||||
|
时:
|
||||||
|
<el-input-number :min="0" :max="24" size="mini" v-model="previewTimeData.h"></el-input-number>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
分:
|
||||||
|
<el-input-number :min="0" :max="59" size="mini" v-model="previewTimeData.m"></el-input-number>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
秒:
|
||||||
|
<el-input-number :min="0" :max="59" size="mini" v-model="previewTimeData.s"></el-input-number>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24" style="text-align: center; margin: 10px 0">
|
||||||
|
<el-button-group>
|
||||||
|
<el-button type="info" @click.native.prevent="restTime">取消</el-button>
|
||||||
|
<el-button type="primary" @click.native.prevent="subimitPTime">确定
|
||||||
|
</el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-dialog>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import DPlayer from '@/components/VueDplayerHls/index'
|
||||||
|
import UploadImg from '@/components/UploadImg/index'
|
||||||
|
import UploadVideo from '@/components/UploadVideoLibraryV2/index'
|
||||||
|
import 'videojs-contrib-hls'
|
||||||
|
import { mediaUpdateV2, updatePreTime } from '@/api/mediaLibrary/videoList'
|
||||||
|
import { stringToArry, arryToString } from '@/filters/index'
|
||||||
|
import {
|
||||||
|
StatusList,
|
||||||
|
formVideoTypeList
|
||||||
|
} from '@/filters/mediaLibrary/videoList'
|
||||||
|
import { current } from '@/filters/index'
|
||||||
|
export default {
|
||||||
|
name: 'AddOrEdit',
|
||||||
|
props: ['data'],
|
||||||
|
components: {
|
||||||
|
UploadImg,
|
||||||
|
UploadVideo,
|
||||||
|
DPlayer
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
totalTime() {
|
||||||
|
return this.data.data.videoTime
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
innerVisible: false,
|
||||||
|
Visible: true,
|
||||||
|
title: '',
|
||||||
|
defaltTime: current() + 'T12:00:00.000Z',
|
||||||
|
taskId: '',
|
||||||
|
StatusList: StatusList(),
|
||||||
|
formVideoTypeList: formVideoTypeList(),
|
||||||
|
tags: null,
|
||||||
|
fieldNameFs: '', // 正片地址全称
|
||||||
|
secondTags: [],
|
||||||
|
FirstTagList: [],
|
||||||
|
|
||||||
|
form: {
|
||||||
|
appids: undefined,
|
||||||
|
actors: undefined, // [],演员
|
||||||
|
addedTime: undefined, // 'string',上架时间
|
||||||
|
bango: undefined, // 'string',番号
|
||||||
|
checkSum: undefined, // 'string',md5校验码
|
||||||
|
country: undefined, // 'string',国家
|
||||||
|
coverImg: undefined, // 封面
|
||||||
|
desc: undefined, // 'string',详细描述
|
||||||
|
directors: undefined, // [],导演
|
||||||
|
firstTag: undefined, // 'string',一级标签
|
||||||
|
preFileName: undefined, // 'string',预览文件
|
||||||
|
preview: undefined, // 0,预览普通视频
|
||||||
|
publish: undefined, // 'string',视频发布者
|
||||||
|
secondTags: undefined, // [],二级标签标签
|
||||||
|
size: undefined, // 0,文件大小
|
||||||
|
status: undefined, // 'string',当前状态
|
||||||
|
studio: undefined, // 'string',工作室/所有者
|
||||||
|
title: undefined, // 'string',标题
|
||||||
|
type: undefined, // 'string',长视频/短视频
|
||||||
|
videoTime: undefined // 0,影片长度
|
||||||
|
},
|
||||||
|
previewTimeData: {
|
||||||
|
h: 0,
|
||||||
|
m: 0,
|
||||||
|
s: 0
|
||||||
|
},
|
||||||
|
type: undefined,
|
||||||
|
videoType: undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.title = this.data.title
|
||||||
|
if (this.title === '编辑') {
|
||||||
|
this.form = { ...this.data.data }
|
||||||
|
this.form.actors = arryToString(this.form.actors)
|
||||||
|
this.form.directors = arryToString(this.form.directors)
|
||||||
|
if (this.form.fieldNameFs) {
|
||||||
|
this.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.player) {
|
||||||
|
this.player.dispose()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
checkUpload() {
|
||||||
|
if (!this.videoType) {
|
||||||
|
return this.$message({
|
||||||
|
type: 'error',
|
||||||
|
message: '请选择视频归类!!'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// TODO:新增视频时绑定煤资库ID
|
||||||
|
async subimitPTime() {
|
||||||
|
let s = 0
|
||||||
|
if (this.previewTimeData.h) {
|
||||||
|
s += this.previewTimeData.h * 60 * 60
|
||||||
|
}
|
||||||
|
if (this.previewTimeData.m) {
|
||||||
|
s += this.previewTimeData.m * 60
|
||||||
|
}
|
||||||
|
s += this.previewTimeData.s
|
||||||
|
if (s > 0 && s + 15 <= this.data.data.videoTime - 15) {
|
||||||
|
const data = {
|
||||||
|
id: this.data.data.id,
|
||||||
|
preFileTime: s
|
||||||
|
}
|
||||||
|
updatePreTime(data).then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.$message.success('预览时长设置成功')
|
||||||
|
this.innerVisible = false
|
||||||
|
} else {
|
||||||
|
this.$message.error('预览时长设置失败')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$message.error('预览时长设置不能为零或不能超过播放时长')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// TODO:提交视频列表数据
|
||||||
|
update(data) {
|
||||||
|
mediaUpdateV2(data).then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.$message.success('更新成功')
|
||||||
|
this.close()
|
||||||
|
} else {
|
||||||
|
this.$message.error('更新失败')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
filterM3u8(v) {
|
||||||
|
return /\.m3u8/g.test(v) ? v : v + '.m3u8'
|
||||||
|
},
|
||||||
|
handleRemove(key) {
|
||||||
|
this.form[key] = ''
|
||||||
|
},
|
||||||
|
// 清空某一项筛选列表
|
||||||
|
onClear(key) {
|
||||||
|
this.form.param[key] = []
|
||||||
|
},
|
||||||
|
restTime() {
|
||||||
|
this.previewTimeData = {
|
||||||
|
h: 0,
|
||||||
|
m: 0,
|
||||||
|
s: 0
|
||||||
|
}
|
||||||
|
this.innerVisible = false
|
||||||
|
},
|
||||||
|
|
||||||
|
// 提交按钮
|
||||||
|
submit() {
|
||||||
|
const data = { ...this.form }
|
||||||
|
data.appids = data.appids ? [data.appids] : []
|
||||||
|
data.actors = data.actors ? stringToArry(data.actors) : []
|
||||||
|
data.directors = data.directors ? stringToArry(data.directors) : []
|
||||||
|
const YY = new Date().getUTCFullYear()
|
||||||
|
const MM =
|
||||||
|
new Date().getMonth() + 1 < 10
|
||||||
|
? `0${new Date().getMonth() + 1}`
|
||||||
|
: new Date().getMonth() + 1
|
||||||
|
const DD =
|
||||||
|
new Date().getUTCDate() < 10
|
||||||
|
? `0${new Date().getUTCDate()}`
|
||||||
|
: new Date().getUTCDate()
|
||||||
|
const HH =
|
||||||
|
new Date().getUTCHours() < 10
|
||||||
|
? `0${new Date().getUTCHours()}`
|
||||||
|
: new Date().getUTCHours()
|
||||||
|
const MU =
|
||||||
|
new Date().getUTCMinutes() < 10
|
||||||
|
? `0${new Date().getUTCMinutes()}`
|
||||||
|
: new Date().getUTCMinutes()
|
||||||
|
const SS =
|
||||||
|
new Date().getUTCSeconds() < 10
|
||||||
|
? `0${new Date().getUTCSeconds()}`
|
||||||
|
: new Date().getUTCSeconds()
|
||||||
|
const MS =
|
||||||
|
new Date().getUTCMilliseconds() < 10
|
||||||
|
? `0${new Date().getUTCMilliseconds()}`
|
||||||
|
: new Date().getUTCMilliseconds()
|
||||||
|
data.addedTime =
|
||||||
|
data.addedTime || `${YY}-${MM}-${DD}T${HH}:${MU}:${SS}.${MS}Z`
|
||||||
|
this.update(data)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 上传视频返回地址
|
||||||
|
changeVideoUrl(data) {
|
||||||
|
console.log(data)
|
||||||
|
this.form.id = data.id
|
||||||
|
this.form.fieldNameFs = data.videoUri
|
||||||
|
this.form.videoTime = parseInt(data.duration)
|
||||||
|
this.form.size = data.size
|
||||||
|
},
|
||||||
|
|
||||||
|
// 重复上传视频
|
||||||
|
repeatVideo(data) {
|
||||||
|
this.taskId = data.taskId
|
||||||
|
this.getData()
|
||||||
|
},
|
||||||
|
|
||||||
|
// 上传图片返回地址
|
||||||
|
changeCoverImgUrl(data) {
|
||||||
|
this.form.coverImg = data
|
||||||
|
},
|
||||||
|
// / 监听视频播放的回调函数
|
||||||
|
onPlayerPlay() { },
|
||||||
|
// / 监听暂停播放的回调函数
|
||||||
|
onPlayerPause() { },
|
||||||
|
// / 监听当前视频数据加载完成
|
||||||
|
onPlayerLoadeddata() { },
|
||||||
|
// / 监听当前视频数据加载失败
|
||||||
|
onPlayerError() { },
|
||||||
|
// / 监听当前视频数据加载ing
|
||||||
|
onPlayerWaiting() { },
|
||||||
|
// / 监听当前视频播放完成
|
||||||
|
onPlayerEnded() { },
|
||||||
|
open() {
|
||||||
|
this.mediaUrl =
|
||||||
|
'api/web/media/m3u8' +
|
||||||
|
(this.form.fieldNameFs.match(RegExp(/.m3u8/))
|
||||||
|
? this.form.fieldNameFs
|
||||||
|
: this.form.fieldNameFs + '.m3u8')
|
||||||
|
},
|
||||||
|
|
||||||
|
// 关闭编辑
|
||||||
|
close() {
|
||||||
|
if (this.player) {
|
||||||
|
this.player.dispose()
|
||||||
|
}
|
||||||
|
this.$emit('close')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.el-dialog {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin: 0 !important;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
/*height:600px;*/
|
||||||
|
max-height: calc(100% - 30px);
|
||||||
|
max-width: calc(100% - 30px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-dialog .el-dialog__body {
|
||||||
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.videoBox {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-textarea.is-disabled.ti .el-textarea__inner {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-box {
|
||||||
|
width: 100%;
|
||||||
|
height: 400px;
|
||||||
|
text-align: center;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#my-video {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.check_upload {
|
||||||
|
position: relative;
|
||||||
|
padding: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px dashed #ccc;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
|
||||||
|
div {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-size: 100%;
|
||||||
|
line-height: 1.4;
|
||||||
|
color: #666;
|
||||||
|
border: 1px solid #666;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 2px;
|
||||||
|
background: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user