|
|
@@ -33,10 +33,14 @@
|
|
|
<el-col :span="1.5">
|
|
|
<el-button type="success" plain icon="el-icon-document-copy" size="mini" @click="handleBatchAdd" v-hasPermi="['life:video:add']">批量添加</el-button>
|
|
|
</el-col>
|
|
|
+ <el-col :span="1.5">
|
|
|
+ <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleBatchDelete" v-hasPermi="['life:video:remove']">批量删除</el-button>
|
|
|
+ </el-col>
|
|
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
|
</el-row>
|
|
|
|
|
|
- <el-table border v-loading="loading" :data="videoList">
|
|
|
+ <el-table border v-loading="loading" :data="videoList" @selection-change="handleSelectionChange">
|
|
|
+ <el-table-column type="selection" width="55" align="center"/>
|
|
|
<el-table-column label="视频ID" align="center" prop="videoId" width="90"/>
|
|
|
<el-table-column label="封面" align="center" width="80">
|
|
|
<template slot-scope="scope">
|
|
|
@@ -112,6 +116,7 @@
|
|
|
:fileName.sync="form.fileName"
|
|
|
@video-ready="onVideoReady"
|
|
|
@change="onVideoReady"
|
|
|
+ @video-duration="onVideoDuration"
|
|
|
ref="videoUpload"
|
|
|
/>
|
|
|
<el-form-item v-if="form.videoUrl" label="上传时间">
|
|
|
@@ -119,7 +124,10 @@
|
|
|
</el-form-item>
|
|
|
<el-form-item label="时长(秒)" prop="duration">
|
|
|
<el-input-number v-model="form.duration" :min="0" :controls="false"/>
|
|
|
- <span style="margin-left:8px;color:#909399;font-size:12px">默认 0,可手动修改</span>
|
|
|
+ <span style="margin-left:8px;color:#909399;font-size:12px">上传/选取后自动读取,可手动修改</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="播放量" prop="views">
|
|
|
+ <el-input-number v-model="form.views" :min="0" :controls="false" style="width:160px"/>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="点赞数" prop="likes">
|
|
|
<el-input-number v-model="form.likes" :min="0" :controls="false" style="width:160px"/>
|
|
|
@@ -142,7 +150,13 @@
|
|
|
<el-radio :label="0">否</el-radio>
|
|
|
</el-radio-group>
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="关联商品">
|
|
|
+ <el-form-item label="是否关联商品" prop="isProduct">
|
|
|
+ <el-radio-group v-model="form.isProduct" @change="onIsProductChange">
|
|
|
+ <el-radio :label="1">是</el-radio>
|
|
|
+ <el-radio :label="0">否</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item v-show="form.isProduct === 1" label="关联商品">
|
|
|
<el-button type="primary" size="mini" :disabled="selectedProducts.length >= 1" @click="openProductDialog">选择商品</el-button>
|
|
|
<span style="margin-left:8px;color:#909399;font-size:12px">最多关联 1 个商品</span>
|
|
|
<el-table :data="selectedProducts" border size="mini" style="margin-top:8px">
|
|
|
@@ -204,13 +218,17 @@
|
|
|
:fileName.sync="row.fileName"
|
|
|
@video-ready="onBatchVideoReady(index)"
|
|
|
@change="onBatchVideoReady(index)"
|
|
|
+ @video-duration="d => onBatchVideoDuration(index, d)"
|
|
|
/>
|
|
|
<el-form-item v-if="row.videoUrl" label="上传时间">
|
|
|
<el-input :value="row.uploadTimeDisplay" disabled style="width:220px"/>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="时长(秒)">
|
|
|
<el-input-number v-model="row.duration" :min="0" :controls="false"/>
|
|
|
- <span style="margin-left:8px;color:#909399;font-size:12px">默认 0,可手动修改</span>
|
|
|
+ <span style="margin-left:8px;color:#909399;font-size:12px">自动读取,可改</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="播放量">
|
|
|
+ <el-input-number v-model="row.views" :min="0" :controls="false" style="width:120px"/>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="赞/藏/享">
|
|
|
<el-input-number v-model="row.likes" :min="0" :controls="false" style="width:90px"/>
|
|
|
@@ -280,6 +298,8 @@ export default {
|
|
|
showSearch: true,
|
|
|
total: 0,
|
|
|
videoList: [],
|
|
|
+ ids: [],
|
|
|
+ multiple: true,
|
|
|
vestOptions: [],
|
|
|
categoryOptions: [],
|
|
|
title: '',
|
|
|
@@ -300,7 +320,8 @@ export default {
|
|
|
title: [{ required: true, message: '标题不能为空', trigger: 'blur' }],
|
|
|
coverUrl: [{ required: true, message: '封面不能为空', trigger: 'change' }],
|
|
|
videoUrl: [{ required: true, message: '请上传或选择视频', trigger: 'change' }],
|
|
|
- isShow: [{ required: true, message: '请选择是否上架', trigger: 'change' }]
|
|
|
+ isShow: [{ required: true, message: '请选择是否上架', trigger: 'change' }],
|
|
|
+ isProduct: [{ required: true, message: '请选择是否关联商品', trigger: 'change' }]
|
|
|
},
|
|
|
selectedProducts: [],
|
|
|
productOpen: false,
|
|
|
@@ -385,12 +406,11 @@ export default {
|
|
|
return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate())
|
|
|
+ ' ' + pad(d.getHours()) + ':' + pad(d.getMinutes()) + ':' + pad(d.getSeconds())
|
|
|
},
|
|
|
- /** 本地上传完成 / 素材库选完后展示上传时间;时长保持默认 0,可手动改 */
|
|
|
+ /** 本地上传完成 / 素材库选完后展示上传时间 */
|
|
|
onVideoReady() {
|
|
|
if (!this.form.videoUrl) {
|
|
|
return
|
|
|
}
|
|
|
- // 新增:展示当前选择/上传时间;修改:保留原 createTime
|
|
|
if (this.form.videoId) {
|
|
|
this.uploadTimeDisplay = this.parseTime(this.form.createTime) || this.formatNow()
|
|
|
} else {
|
|
|
@@ -403,6 +423,12 @@ export default {
|
|
|
this.$refs.form && this.$refs.form.validateField('videoUrl')
|
|
|
})
|
|
|
},
|
|
|
+ onVideoDuration(duration) {
|
|
|
+ const d = Number(duration)
|
|
|
+ if (!isNaN(d) && d >= 0) {
|
|
|
+ this.form.duration = Math.round(d)
|
|
|
+ }
|
|
|
+ },
|
|
|
reset() {
|
|
|
this.form = {
|
|
|
videoId: null,
|
|
|
@@ -413,11 +439,13 @@ export default {
|
|
|
coverUrl: null,
|
|
|
videoUrl: null,
|
|
|
duration: 0,
|
|
|
+ views: 0,
|
|
|
likes: 0,
|
|
|
favoriteNum: 0,
|
|
|
shareNum: 0,
|
|
|
isShow: 1,
|
|
|
isHot: 0,
|
|
|
+ isProduct: 0,
|
|
|
productIds: []
|
|
|
}
|
|
|
this.uploadTimeDisplay = ''
|
|
|
@@ -459,6 +487,7 @@ export default {
|
|
|
fileName: null,
|
|
|
uploadTimeDisplay: '',
|
|
|
duration: 0,
|
|
|
+ views: 0,
|
|
|
likes: 0,
|
|
|
favoriteNum: 0,
|
|
|
shareNum: 0,
|
|
|
@@ -486,6 +515,14 @@ export default {
|
|
|
row.duration = 0
|
|
|
}
|
|
|
},
|
|
|
+ onBatchVideoDuration(index, duration) {
|
|
|
+ const row = this.batchRows[index]
|
|
|
+ if (!row) return
|
|
|
+ const d = Number(duration)
|
|
|
+ if (!isNaN(d) && d >= 0) {
|
|
|
+ row.duration = Math.round(d)
|
|
|
+ }
|
|
|
+ },
|
|
|
submitBatch() {
|
|
|
if (!this.batchVestId) {
|
|
|
this.$message.warning('请选择马甲号')
|
|
|
@@ -510,6 +547,7 @@ export default {
|
|
|
videoUrl: row.videoUrl,
|
|
|
fileName: row.fileName,
|
|
|
duration: row.duration || 0,
|
|
|
+ views: row.views || 0,
|
|
|
likes: row.likes || 0,
|
|
|
favoriteNum: row.favoriteNum || 0,
|
|
|
shareNum: row.shareNum || 0,
|
|
|
@@ -529,17 +567,29 @@ export default {
|
|
|
handleUpdate(row) {
|
|
|
this.reset()
|
|
|
getLifeVideo(row.videoId).then(res => {
|
|
|
- this.form = Object.assign({}, res.data)
|
|
|
- if (!this.form.category) {
|
|
|
- this.form.category = this.defaultCategory()
|
|
|
+ const data = res.data || {}
|
|
|
+ const ids = data.productIds || []
|
|
|
+ // 一次性赋值,保证 isProduct 等前端字段进入响应式;radio 统一为 Number,避免类型不一致点不动
|
|
|
+ this.form = {
|
|
|
+ videoId: data.videoId,
|
|
|
+ vestId: data.vestId,
|
|
|
+ category: data.category || this.defaultCategory(),
|
|
|
+ title: data.title,
|
|
|
+ fileName: data.fileName,
|
|
|
+ coverUrl: data.coverUrl,
|
|
|
+ videoUrl: data.videoUrl,
|
|
|
+ duration: data.duration == null ? 0 : Number(data.duration),
|
|
|
+ views: Number(data.views || 0),
|
|
|
+ likes: Number(data.likes || 0),
|
|
|
+ favoriteNum: Number(data.favoriteNum || 0),
|
|
|
+ shareNum: Number(data.shareNum || 0),
|
|
|
+ isShow: data.isShow == null ? 1 : Number(data.isShow),
|
|
|
+ isHot: data.isHot == null ? 0 : Number(data.isHot),
|
|
|
+ isProduct: ids.length > 0 ? 1 : 0,
|
|
|
+ productIds: ids,
|
|
|
+ createTime: data.createTime
|
|
|
}
|
|
|
- this.form.likes = this.form.likes || 0
|
|
|
- this.form.favoriteNum = this.form.favoriteNum || 0
|
|
|
- this.form.shareNum = this.form.shareNum || 0
|
|
|
- this.form.duration = this.form.duration == null ? 0 : this.form.duration
|
|
|
this.uploadTimeDisplay = this.parseTime(this.form.createTime) || ''
|
|
|
- const ids = res.data.productIds || []
|
|
|
- this.form.productIds = ids
|
|
|
this.selectedProducts = ids.map(id => ({ productId: id, productName: '商品#' + id, price: '-', stock: '-' }))
|
|
|
if (ids.length) {
|
|
|
searchLifeVideoProduct({ pageNum: 1, pageSize: 100 }).then(p => {
|
|
|
@@ -552,14 +602,27 @@ export default {
|
|
|
this.title = '修改生活号视频'
|
|
|
})
|
|
|
},
|
|
|
+ onIsProductChange(val) {
|
|
|
+ // 切到「否」时清空已选商品,避免误保存
|
|
|
+ if (Number(val) !== 1) {
|
|
|
+ this.selectedProducts = []
|
|
|
+ this.form.productIds = []
|
|
|
+ }
|
|
|
+ },
|
|
|
submitForm() {
|
|
|
this.$refs['form'].validate(valid => {
|
|
|
if (!valid) return
|
|
|
+ if (this.form.isProduct === 1 && this.selectedProducts.length === 0) {
|
|
|
+ this.$message.warning('请选择关联商品')
|
|
|
+ return
|
|
|
+ }
|
|
|
if (this.selectedProducts.length > 1) {
|
|
|
this.$message.warning('最多关联一个商品')
|
|
|
return
|
|
|
}
|
|
|
- this.form.productIds = this.selectedProducts.map(p => p.productId)
|
|
|
+ this.form.productIds = this.form.isProduct === 1
|
|
|
+ ? this.selectedProducts.map(p => p.productId)
|
|
|
+ : []
|
|
|
const req = this.form.videoId != null ? updateLifeVideo(this.form) : addLifeVideo(this.form)
|
|
|
req.then(() => {
|
|
|
this.msgSuccess('操作成功')
|
|
|
@@ -575,6 +638,10 @@ export default {
|
|
|
this.getList()
|
|
|
})
|
|
|
},
|
|
|
+ handleSelectionChange(selection) {
|
|
|
+ this.ids = selection.map(item => item.videoId)
|
|
|
+ this.multiple = !selection.length
|
|
|
+ },
|
|
|
handleDelete(row) {
|
|
|
this.$confirm('删除后不可恢复,确认删除该视频?', '警告', { type: 'warning' }).then(() => {
|
|
|
return delLifeVideo(row.videoId)
|
|
|
@@ -583,6 +650,18 @@ export default {
|
|
|
this.msgSuccess('删除成功')
|
|
|
}).catch(() => {})
|
|
|
},
|
|
|
+ handleBatchDelete() {
|
|
|
+ if (!this.ids.length) {
|
|
|
+ this.$message.warning('请选择要删除的视频')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.$confirm('删除后不可恢复,确认批量删除选中的 ' + this.ids.length + ' 条视频?', '警告', { type: 'warning' }).then(() => {
|
|
|
+ return delLifeVideo(this.ids.join(','))
|
|
|
+ }).then(() => {
|
|
|
+ this.getList()
|
|
|
+ this.msgSuccess('删除成功')
|
|
|
+ }).catch(() => {})
|
|
|
+ },
|
|
|
openProductDialog() {
|
|
|
this.productOpen = true
|
|
|
this.searchProduct()
|
|
|
@@ -607,6 +686,7 @@ export default {
|
|
|
return
|
|
|
}
|
|
|
this.selectedProducts.push(row)
|
|
|
+ this.form.isProduct = 1
|
|
|
this.productOpen = false
|
|
|
},
|
|
|
removeProduct(index) {
|