node-sass 4.x cannot build on arm64/Node 16. Use sass with ::v-deep instead of /deep/, and only replace the server dist after the upload is unpacked and verified. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
588 lines
17 KiB
Vue
Executable File
588 lines
17 KiB
Vue
Executable File
<template>
|
||
<div class="edit-video-box">
|
||
<el-dialog
|
||
:title="'视频编辑'"
|
||
:visible.sync="dialogVisible"
|
||
width="800px"
|
||
:before-close="handleClose"
|
||
:close-on-click-modal="false"
|
||
>
|
||
<el-form ref="form" :model="editParam" :rules="rules" label-width="100px">
|
||
<div class="form-flex-box">
|
||
<el-form-item label="视频标题:">
|
||
<el-input
|
||
type="textarea"
|
||
:rows="2"
|
||
placeholder="请谨慎修改用户上传数据"
|
||
v-model="editParam.title"
|
||
:disabled="editTitle"
|
||
></el-input>
|
||
<el-button type="success" size="small" @click="editTitle = false"
|
||
>修改</el-button
|
||
>
|
||
</el-form-item>
|
||
</div>
|
||
<div class="form-flex-box">
|
||
<el-form-item label="视频内容:">
|
||
<el-input
|
||
type="textarea"
|
||
:rows="2"
|
||
placeholder="请谨慎修改用户上传数据"
|
||
v-model="editParam.content"
|
||
:disabled="editContent"
|
||
></el-input>
|
||
<el-button type="success" size="small" @click="editContent = false"
|
||
>修改</el-button
|
||
>
|
||
</el-form-item>
|
||
</div>
|
||
<div class="form-flex-box">
|
||
<el-form-item label="封面上传:" prop="cover">
|
||
<base-upload
|
||
:cover="editParam.cover"
|
||
:action="action"
|
||
@successCallback="successCallback"
|
||
@changeImgUrl="changeImgUrl"
|
||
:id="sourceID"
|
||
:wSize="360"
|
||
:hSize="640"
|
||
:width="'120px'"
|
||
:height="'213px'"
|
||
></base-upload>
|
||
</el-form-item>
|
||
<div class="item-box el-form-item">
|
||
<el-form-item label="价格:" prop="coins">
|
||
<el-input
|
||
v-model.number="editParam.coins"
|
||
size="small"
|
||
placeholder="请输入价格"
|
||
></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="免费时长:">
|
||
<el-input
|
||
v-model.number="editParam.freeTime"
|
||
size="small"
|
||
placeholder="请输入视频免费时长"
|
||
></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="用户ID:" prop="publisherID">
|
||
<el-input
|
||
v-model.number="editParam.publisherID"
|
||
size="small"
|
||
placeholder="请输入用户ID"
|
||
></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="是否可推荐:" prop="recoWeight">
|
||
<el-select
|
||
v-model.number="editParam.recoWeight"
|
||
placeholder="请选择可否推荐"
|
||
size="small"
|
||
>
|
||
<el-option label="可推荐" :value="0"></el-option>
|
||
<el-option label="不可推荐" :value="-1"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="广告排序号:" prop="sortCode">
|
||
<el-input
|
||
v-model.number="editParam.sortCode"
|
||
size="small"
|
||
></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="作品排序:" prop="worksSort">
|
||
<el-input
|
||
v-model.number="editParam.worksSort"
|
||
size="small"
|
||
></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="帖子类型:">
|
||
<el-select
|
||
v-model="editParam.newsType"
|
||
placeholder="请输入帖子类型"
|
||
size="small"
|
||
style="width: 180px"
|
||
>
|
||
<el-option
|
||
v-for="item in newsTypes"
|
||
:key="item.value"
|
||
:label="item.label"
|
||
:value="item.value"
|
||
>
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</div>
|
||
</div>
|
||
<div class="flex-item">
|
||
<el-form-item label="广告跳转链接:" prop="linkUrl">
|
||
<el-input
|
||
type="textarea"
|
||
v-model="editParam.linkUrl"
|
||
size="small"
|
||
></el-input>
|
||
</el-form-item>
|
||
</div>
|
||
<div class="flex-item">
|
||
<el-form-item
|
||
label="种子下载链接:"
|
||
prop="seedLinkUrl"
|
||
v-if="editParam.newsType == 'SEED_LINK'"
|
||
>
|
||
<el-input
|
||
type="textarea"
|
||
v-model="editParam.seedLinkUrl"
|
||
size="small"
|
||
></el-input>
|
||
</el-form-item>
|
||
</div>
|
||
<div class="flex-item" v-if="editParam.newsType == 'SEED_LINK'">
|
||
<el-form-item label="种子影片时长:" prop="seedPlayTime">
|
||
<el-input
|
||
v-model.number="editParam.seedPlayTime"
|
||
size="small"
|
||
></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="种子影片大小:" prop="seedSize">
|
||
<el-input
|
||
v-model.number="editParam.seedSize"
|
||
size="small"
|
||
></el-input>
|
||
</el-form-item>
|
||
</div>
|
||
<div class="topic">
|
||
<el-form-item label="选择父专题" class="tipicItem">
|
||
<el-select
|
||
v-model="subSections"
|
||
placeholder="请选择父专题"
|
||
size="small"
|
||
clearable
|
||
@change="selectChild"
|
||
clear
|
||
>
|
||
<el-option
|
||
v-for="(section, index) in sections"
|
||
:key="index"
|
||
:label="section.subModuleName"
|
||
:value="section.id"
|
||
>
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="选择子专题" class="tipicItem">
|
||
<el-select
|
||
v-model="subSectionId"
|
||
placeholder="请选择子专题"
|
||
size="small"
|
||
clearable
|
||
>
|
||
<el-option
|
||
v-for="(subSection, index) in subSectionList"
|
||
:key="index"
|
||
:label="subSection.sectionName"
|
||
:value="subSection.id"
|
||
>
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</div>
|
||
<el-form-item label="选择活动:">
|
||
<el-select
|
||
v-model="editParam.activityId"
|
||
filterable
|
||
placeholder="未选择活动则该视频不参加大赛"
|
||
clearable
|
||
class="activity-box"
|
||
>
|
||
<el-option
|
||
v-for="item in activityList"
|
||
:key="item.id"
|
||
:label="item.desc"
|
||
:value="item.id"
|
||
>
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<div class="form-flex-box">
|
||
<el-form-item label="标签:" prop="tags">
|
||
<tag-selector
|
||
v-model="editParam.tags"
|
||
:tagList="tagList"
|
||
></tag-selector>
|
||
</el-form-item>
|
||
</div>
|
||
</el-form>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button @click="handleClose" size="small">取 消</el-button>
|
||
<el-button
|
||
type="primary"
|
||
size="small"
|
||
@click="submitDate()"
|
||
:loading="flag"
|
||
>确 认</el-button
|
||
>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import baseConfig from "@/utils/serverUrlConfig";
|
||
import { validatorIndex, validatorWorksSort } from "@/utils/validator";
|
||
import API from "@/api";
|
||
import TagSelector from "@/components/tagSelector";
|
||
export default {
|
||
components: {
|
||
TagSelector,
|
||
},
|
||
data() {
|
||
return {
|
||
dialogVisible: false,
|
||
flag: false,
|
||
// 封面上传地址
|
||
action: baseConfig.baseServerUrl + "/vid/uploadStatic",
|
||
tagList: [],
|
||
sourceID: "",
|
||
editTitle: true,
|
||
editContent: true,
|
||
editParam: {
|
||
id: "",
|
||
tags: [],
|
||
cover: "",
|
||
coverThumb: "",
|
||
title: "",
|
||
content: "",
|
||
fakeLikeCount: 0,
|
||
fakePlayCount: 0,
|
||
fakeShareCount: 0,
|
||
size: "",
|
||
likeCount: 0,
|
||
playCount: 0,
|
||
shareCount: 0,
|
||
freeTime: 0,
|
||
coins: 0,
|
||
type: 0,
|
||
linkUrl: "",
|
||
seedPlayTime: 0,
|
||
seedSize: 0,
|
||
sortCode: "",
|
||
worksSort: "",
|
||
activityId: "",
|
||
publisherID: "",
|
||
recoWeight: 0,
|
||
tID: undefined,
|
||
newsType: "SP",
|
||
// isSubSection: true,
|
||
},
|
||
newsType: "SP",
|
||
newsTypes: [
|
||
{
|
||
label: "长视频",
|
||
value: "SP",
|
||
},
|
||
{
|
||
label: "短视频",
|
||
value: "SHORT",
|
||
},
|
||
{
|
||
label: "图集",
|
||
value: "PIC",
|
||
},
|
||
{
|
||
label: "种子贴",
|
||
value: "SEED_LINK",
|
||
},
|
||
{
|
||
label: "图文",
|
||
value: "COVER",
|
||
},
|
||
],
|
||
subSectionList: [],
|
||
subSectionId: "",
|
||
sections: [],
|
||
subSections: [],
|
||
activityList: [],
|
||
// 表单验证规则
|
||
rules: {
|
||
cover: [
|
||
{ required: true, message: "请输入添加封面图片", trigger: "blur" },
|
||
],
|
||
freeTime: [
|
||
{ required: true, message: "请输入免费时长", trigger: "blur" },
|
||
{ validator: validatorIndex, trigger: "blur" },
|
||
],
|
||
coins: [
|
||
{ required: true, message: "请输入价格", trigger: "blur" },
|
||
{ validator: validatorIndex, trigger: "blur" },
|
||
],
|
||
tags: [{ required: true, message: "请选择标签", trigger: "blur" }],
|
||
worksSort: [{ validator: validatorWorksSort, trigger: "blur" }],
|
||
},
|
||
};
|
||
},
|
||
methods: {
|
||
async getVideoActivity() {
|
||
const params = {};
|
||
let ret = await API.getVideoActivity(params);
|
||
if (ret.code == 200) {
|
||
this.activityList = ret.data;
|
||
this.activityList = this.activityList.concat([
|
||
{
|
||
id: "000000000000000000000000",
|
||
desc: "不参加活动",
|
||
},
|
||
]);
|
||
}
|
||
},
|
||
getTagList() {
|
||
const params = {};
|
||
API.queryTagList(params).then((res) => {
|
||
if (res.code === 200) {
|
||
this.tagList = res.data.list;
|
||
}
|
||
});
|
||
},
|
||
// 提交验证
|
||
submitDate() {
|
||
this.$refs.form.validate((valid) => {
|
||
if (valid) {
|
||
if (this.subSections && !this.subSectionId) {
|
||
this.$message.error("请选择子专题");
|
||
return;
|
||
}
|
||
// this.flag = true;
|
||
// const tags = this.editParam.tags.filter(
|
||
// (item) => this.tagList.map((e) => e.name).indexOf(item) === -1
|
||
// );
|
||
// if (tags.length > 0) {
|
||
// this.$confirm(
|
||
// `标签${tags.join(",")}不属于常用标签,确定修改?`,
|
||
// "提示",
|
||
// {
|
||
// confirmButtonText: "确定",
|
||
// cancelButtonText: "取消",
|
||
// type: "warning",
|
||
// }
|
||
// )
|
||
// .then(() => {
|
||
// this.editVideo();
|
||
// })
|
||
// .catch(() => {
|
||
// this.flag = false;
|
||
// return false;
|
||
// });
|
||
// } else {
|
||
this.editVideo();
|
||
// }
|
||
} else {
|
||
this.flag = false;
|
||
return false;
|
||
}
|
||
});
|
||
},
|
||
// 编辑
|
||
editVideo() {
|
||
if (!this.editParam.activityId) {
|
||
this.editParam.activityId = "000000000000000000000000";
|
||
}
|
||
if (this.subSections && !this.subSectionId) {
|
||
this.$message.error("请选择子专题");
|
||
return;
|
||
}
|
||
if (this.subSections && this.subSectionId) {
|
||
this.editParam.sectionID = this.subSectionId;
|
||
} else {
|
||
this.editParam.sectionID = "";
|
||
}
|
||
|
||
API.editVideoInfo(this.editParam)
|
||
.then((res) => {
|
||
if (res.code === 200) {
|
||
this.$message({
|
||
message: "编辑成功!",
|
||
type: "success",
|
||
});
|
||
this.$emit("handlerEditList");
|
||
} else {
|
||
this.$message.error("编辑失败!");
|
||
}
|
||
this.handleClose();
|
||
this.flag = false;
|
||
})
|
||
.catch(() => {
|
||
this.handleClose();
|
||
this.flag = false;
|
||
});
|
||
},
|
||
// 标签封面上传成功回掉
|
||
successCallback(res) {
|
||
this.editParam.cover = res.data.coverImg;
|
||
this.editParam.coverThumb = res.data.coverImg;
|
||
},
|
||
// 打开编辑视频弹窗、传递需要编辑的参数
|
||
open(data) {
|
||
this.getTagList();
|
||
this.getVideoActivity();
|
||
this.dialogVisible = true;
|
||
this.editParam.id = data.id;
|
||
this.editParam.cover = data.cover;
|
||
this.editParam.title = data.title;
|
||
this.editParam.content = data.content;
|
||
this.editParam.activityId = data.activityId;
|
||
this.editParam.publisherID = data.publisher.uid;
|
||
this.editParam.coverThumb = data.coverThumb;
|
||
this.editParam.fakeLikeCount = data.fakeLikeCount;
|
||
this.editParam.fakePlayCount = data.fakePlayCount;
|
||
this.editParam.fakeShareCount = data.fakeShareCount;
|
||
this.editParam.size = data.size;
|
||
this.editParam.likeCount = data.likeCount;
|
||
this.editParam.playCount = data.playCount;
|
||
this.editParam.shareCount = data.shareCount;
|
||
this.editParam.freeTime = data.freeTime > 2 ? data.freeTime : 3;
|
||
this.editParam.isChosen = data.chosen;
|
||
this.editParam.coins = data.coins;
|
||
this.editParam.recoWeight = data.recoWeight;
|
||
this.editParam.linkUrl = data.linkUrl;
|
||
this.editParam.seedPlayTime = data.seedPlayTime;
|
||
this.editParam.seedSize = data.seedSize;
|
||
this.editParam.sortCode = data.sortCode;
|
||
this.editParam.worksSort = data.worksSort;
|
||
this.editParam.newsType = data.newsType;
|
||
this.sourceID = data.sourceID;
|
||
this.editParam.tags = data.tags ? data.tags.map((item) => item.name) : [];
|
||
this.editParam.freeTime = data.freeTime;
|
||
this.getSections(data.sectionName);
|
||
this.editParam.tID =
|
||
data.sectionName && data.sectionName.length > 0
|
||
? data.sectionName[0].tID
|
||
: undefined;
|
||
this.subSections =
|
||
data.sectionName && data.sectionName.length > 0
|
||
? data.sectionName[0].subModuleID
|
||
: undefined;
|
||
},
|
||
// 关闭回掉
|
||
handleClose() {
|
||
this.dialogVisible = false;
|
||
this.editTitle = true;
|
||
this.editContent = true;
|
||
this.$refs.form.resetFields();
|
||
this.subSectionList = [];
|
||
// this.subSectionId = "";
|
||
this.sections = [];
|
||
this.subSections = "";
|
||
},
|
||
|
||
changeImgUrl(data) {
|
||
this.editParam.cover = data;
|
||
this.editParam.coverThumb = data;
|
||
},
|
||
|
||
// 验证播放数
|
||
validatorPlayer(rule, value, callback) {
|
||
if (value >= this.editParam.playCount) {
|
||
callback();
|
||
} else {
|
||
callback(
|
||
new Error(
|
||
"假播放数必须大于或者等于真播放数(当前真播放数为:" +
|
||
this.editParam.playCount +
|
||
")",
|
||
),
|
||
);
|
||
}
|
||
},
|
||
// 验证点赞数
|
||
validatorLike(rule, value, callback) {
|
||
if (value >= this.editParam.likeCount) {
|
||
callback();
|
||
} else {
|
||
callback(
|
||
new Error(
|
||
"假点赞数必须大于或者等于真点赞数(当前真点赞数为:" +
|
||
this.editParam.likeCount +
|
||
")",
|
||
),
|
||
);
|
||
}
|
||
},
|
||
// 验证点赞数
|
||
validatorShare(rule, value, callback) {
|
||
if (value >= this.editParam.shareCount) {
|
||
callback();
|
||
} else {
|
||
callback(
|
||
new Error(
|
||
"假共享数必须大于或者等于真共享数(当前真共享数为:" +
|
||
this.editParam.shareCount +
|
||
")",
|
||
),
|
||
);
|
||
}
|
||
},
|
||
|
||
selectChild(val) {
|
||
// this.isSubSection = false;
|
||
this.sections.forEach((i) => {
|
||
if (i.id == val) {
|
||
this.subSectionList = i.sections;
|
||
}
|
||
});
|
||
// this.subSectionList = val;
|
||
this.subSectionId = "";
|
||
},
|
||
getSections(item) {
|
||
API.sectionList().then((res) => {
|
||
if (res && res.code === 200) {
|
||
this.sections = res.data;
|
||
if (item && item.length > 0) {
|
||
this.sections.forEach((i) => {
|
||
if (i.id == item[0].subModuleID) {
|
||
this.subSectionList = i.sections;
|
||
this.subSectionId = item[0].sectionsId;
|
||
}
|
||
});
|
||
}
|
||
}
|
||
});
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.edit-video-box {
|
||
.el-input {
|
||
width: 150px;
|
||
}
|
||
.activity-box {
|
||
::v-deep .el-input {
|
||
width: 500px !important;
|
||
}
|
||
}
|
||
.flex-item {
|
||
width: 90%;
|
||
display: flex;
|
||
.el-form-item {
|
||
flex: 1;
|
||
}
|
||
}
|
||
.form-flex-box {
|
||
display: flex;
|
||
.el-form-item {
|
||
flex: 1;
|
||
}
|
||
.item-box {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
}
|
||
.topic {
|
||
margin-top: 10px;
|
||
width: 100%;
|
||
display: flex;
|
||
.tipicItem {
|
||
flex: 1;
|
||
}
|
||
}
|
||
}
|
||
</style>
|