123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- <script setup>
- import { ref, onMounted, watch } from "vue";
- import { raiInterface, raiVideoApi, getOSSSign } from "@/api/api.js";
- import { ElMessageBox, ElMessage, ElLoading } from "element-plus";
- import MD5 from "js-md5";
- const props = defineProps({
- addEditdialogVisib: {
- type: Boolean,
- default: false,
- },
- chartPermissionList: {
- type: Array,
- default: [],
- },
- playDetailsList: {
- default: {},
- type: Object,
- },
- });
- const addEditVideo = ref({
- videoName: "", //音频名称
- industryId: "", //行业id
- property: "", //产业名称
- publishDate: "", //发布时间
- videoUrl: "", //视频链接
- VideoSeconds: "", //时长
- imgUrl: "", // 视频封面
- shareImgUrl: "", // 分享的视频封面
- detailImgUrl: "", // 详情的视频封面
- });
- const rules = ref({
- videoName: [{ required: true, message: "请上传视频", trigger: "blur" }],
- industryId: [{ required: true, message: "请选择行业", trigger: "change" }],
- property: { required: true, message: "请选择产业", trigger: "change" },
- publishDate: [{ required: true, message: "请选择发布时间", trigger: "change" }],
- imgUrl: { required: true, message: "请选择列表页封面", trigger: "change" },
- shareImgUrl: { required: true, message: "请选择视频分享图", trigger: "change" },
- detailImgUrl: { required: true, message: "请选择详情页封面", trigger: "change" },
- });
- const videoId = ref(0);
- const publishStatus = ref(0);
- const industryArr = ref([]);
- const selectedIndustryArr = ref([]);
- const defaultProps = ref({
- label: "PermissionName",
- children: "List",
- value: "ChartPermissionId",
- });
- const percentage = ref(0);
- const startUpload = ref(false); //开始上传
- watch(
- () => props.playDetailsList,
- async (newval) => {
- if (JSON.stringify(newval) != "{}") {
- await getIndustry(newval.ChartPermissionId);
- console.log(newval);
- addEditVideo.value = {
- videoName: newval.VideoName, //音频名称
- industryId: newval.ChartPermissionId, //行业id
- property: newval.IndustryId || "", //产业名称
- publishDate: newval.PublishDate, //发布时间
- videoUrl: newval.VideoUrl, //视频链接
- VideoSeconds: newval.VideoDuration, //时长
- imgUrl: newval.ImgUrl, // 视频封面
- shareImgUrl: newval.ShareImgUrl, // 分享的视频封面
- detailImgUrl: newval.DetailImgUrl,
- };
- videoId.value = newval.VideoId;
- publishStatus.value = newval.PublishStatus;
- } else {
- videoId.value = 0;
- selectedIndustryArr.value = [];
- publishStatus.value = 0;
- }
- },
- {
- deep: true,
- }
- );
- /* 获取全部的行业 前的判断 */
- function industrySelectFocus() {
- if (!addEditVideo.value.industryId) {
- ElMessage.error("请先选择行业");
- }
- }
- // 行业更改
- function selectChangeHandle(value) {
- addEditVideo.value.property = "";
- value ? getIndustry(value) : (selectedIndustryArr.value = []);
- }
- /* 获取选择的行业 */
- function getIndustry(industryId) {
- if (industryArr.value.length) {
- selectedIndustryArr.value = industryArr.value.filter((item) => item.ChartPermissionId == industryId)[0].List;
- return;
- }
- raiInterface.getListIndustrial().then((res) => {
- if (res.Ret === 200) {
- industryArr.value = res.Data.List || [];
- selectedIndustryArr.value = industryArr.value.filter((item) => item.ChartPermissionId == industryId)[0].List;
- }
- });
- }
- //获取视频时长的promise
- function handleGetDuration(file) {
- return new Promise((resolve, reject) => {
- const fileUrl = URL.createObjectURL(file);
- const audioEl = new Audio(fileUrl);
- audioEl.addEventListener("loadedmetadata", (e) => {
- resolve(audioEl.duration);
- });
- });
- }
- //上传视频判断格式
- function handelBeforeUploadVideo(e) {
- if (e.type != "video/mp4") {
- ElMessage.warning("上传失败,上传视频格式不正确");
- return false;
- }
- }
- // 上传视频
- async function handleUpload(e) {
- const duration = await handleGetDuration(e.file);
- addEditVideo.value.videoName = e.file.name;
- addEditVideo.value.VideoSeconds = duration + ""; //时常
- const res = await getOSSSign();
- if (res.Ret === 200) {
- let accessKeyId = res.Data.AccessKeyId;
- let accessKeySecret = res.Data.AccessKeySecret;
- let stsToken = res.Data.SecurityToken;
- handleUploadToOSS(e.file, accessKeyId, accessKeySecret, stsToken);
- }
- }
- //上传到阿里云
- async function handleUploadToOSS(file, accessKeyId, accessKeySecret, stsToken) {
- startUpload.value = true;
- const ALOSSINS = new OSS({
- // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
- region: "oss-cn-shanghai",
- // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
- accessKeyId: accessKeyId,
- accessKeySecret: accessKeySecret,
- // 从STS服务获取的安全令牌(SecurityToken)。
- stsToken: stsToken,
- // 填写Bucket名称,例如examplebucket。
- bucket: "hzchart",
- endpoint: "hzstatic.hzinsights.com",
- cname: true,
- timeout: 600000,
- });
- // 生成文件名
- const t = new Date().getTime().toString();
- const temName = `static/yb/video/${MD5(t)}.${file.name.split(".")[1]}`;
- const options = {
- // 获取分片上传进度、断点和返回值。
- progress: (p, cpt, res) => {
- percentage.value = parseInt(p * 100);
- },
- // 设置并发上传的分片数量。
- parallel: 10,
- // 设置分片大小。默认值为1 MB,最小值为100 KB。
- partSize: 1024 * 1024 * 10, // 10MB
- };
- try {
- const res = await ALOSSINS.multipartUpload(temName, file, { ...options });
- if (res.res.status === 200) {
- addEditVideo.value.videoUrl = "https://hzstatic.hzinsights.com/" + res.name;
- startUpload.value = false;
- percentage.value = 0;
- }
- } catch (error) {
- ElMessage.warning("上传失败,请刷新重试");
- startUpload.value = false;
- percentage.value = 0;
- }
- }
- const $emit = defineEmits(["getVideoList"]);
- const ruleFormVideo = ref(null);
- //保存或发布
- function confirmSubmit(type) {
- ruleFormVideo.value.validate(async (valid) => {
- if (valid) {
- const res = await raiVideoApi.addVideo({
- VideoName: addEditVideo.value.videoName,
- ChartPermissionId: addEditVideo.value.industryId,
- IndustryId: addEditVideo.value.property || 0,
- VideoUrl: addEditVideo.value.videoUrl,
- VideoDuration: addEditVideo.value.VideoSeconds,
- PublishDate: addEditVideo.value.publishDate,
- PublishOrSave: type == 1 ? type : publishStatus.value,
- VideoId: videoId.value,
- ImgUrl: addEditVideo.value.imgUrl,
- ShareImgUrl: addEditVideo.value.shareImgUrl,
- DetailImgUrl: addEditVideo.value.detailImgUrl,
- });
- if (res.Ret === 200) {
- ElMessage.success("添加成功");
- cancelHandle();
- $emit("getVideoList");
- }
- } else {
- console.log("error submit!!");
- return false;
- }
- });
- }
- // ------------------图片上传
- function handleImageUpload(e, type) {
- let formData = new FormData();
- formData.append("file", e.file);
- raiInterface.upload(formData).then((res) => {
- if (type == "imgUrl") {
- addEditVideo.value.imgUrl = res.Data.ResourceUrl;
- } else if (type == "shareImgUrl") {
- addEditVideo.value.shareImgUrl = res.Data.ResourceUrl;
- } else {
- addEditVideo.value.detailImgUrl = res.Data.ResourceUrl;
- }
- // 触发表单验证
- ruleFormVideo.value.validateField(type);
- });
- }
- //详情进来编辑
- async function editVideo() {
- const res = await raiVideoApi.editVideo({});
- }
- function cancelHandle() {
- ruleFormVideo.value.resetFields();
- addEditVideo.value = {
- videoName: "", //音频名称
- industryId: "", //行业id
- property: "", //产业名称
- publishDate: "", //发布时间
- videoUrl: "", //视频链接
- VideoSeconds: "", //时长
- imgUrl: "", // 视频封面
- shareImgUrl: "", // 分享的视频封面
- detailImgUrl: "",
- };
- $emit("update:addEditdialogVisib", false);
- $emit("update:playDetailsList", {});
- }
- </script>
- <template>
- <div class="container add-edit-video">
- <el-dialog
- draggable
- :close-on-click-modal="false"
- :modal-append-to-body="false"
- center
- width="568px"
- title="添加视频"
- v-model="props.addEditdialogVisib"
- customClass="add-edit-video-dlg"
- :before-close="cancelHandle"
- >
- <div>
- <el-form :model="addEditVideo" :rules="rules" ref="ruleFormVideo" class="demo-ruleForm">
- <el-form-item prop="audioName">
- <div style="display: flex; justify-content: space-between">
- <el-input style="width: 75%" clearable placeholder="请上传视频" v-model="addEditVideo.videoName"></el-input>
- <el-upload action="" accept=".mp4" :http-request="handleUpload" :before-upload="handelBeforeUploadVideo" :show-file-list="false" :disabled="startUpload">
- <el-button type="primary" :loading="startUpload">上传视频</el-button>
- </el-upload>
- <el-progress type="circle" :percentage="percentage" width="40" style="margin-left: 10px" v-if="startUpload"></el-progress>
- </div>
- <p style="color: #ff3737">注:视频格式支持mp4</p>
- </el-form-item>
- <el-form-item prop="industryId">
- <el-select style="width: 100%" placeholder="请选择行业" v-model="addEditVideo.industryId" clearable @change="selectChangeHandle">
- <el-option
- v-for="item in props.chartPermissionList.filter((item) => item.PermissionName != '宏观' && item.PermissionName != '策略' && item.PermissionName != '研选订阅')"
- :label="item.PermissionName"
- :key="item.ChartPermissionId"
- :value="item.ChartPermissionId"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item prop="property">
- <!-- <el-cascader
- style="width: 100%"
- @focus="industrySelectFocus"
- placeholder="请选择产业"
- v-model="addEditVideo.property"
- :props="{ ...defaultProps }"
- :options="selectedIndustryArr"
- :key="addEditVideo.industryId"
- filterable
- clearable
- ></el-cascader> -->
- <el-select v-model="addEditVideo.property" placeholder="请选择产业" clearable filterable style="width: 100%" @focus="industrySelectFocus">
- <el-option :label="item.PermissionName" :value="item.ChartPermissionId" v-for="item in selectedIndustryArr" :key="item.ChartPermissionId"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item prop="publishDate">
- <el-date-picker
- style="width: 100%"
- v-model="addEditVideo.publishDate"
- type="date"
- placeholder="请选择发布时间"
- format="YYYY 年 MM 月 DD 日"
- value-format="YYYY-MM-DD"
- @change="conditionChange"
- >
- </el-date-picker>
- </el-form-item>
- <div class="uploadImageContain">
- <el-form-item prop="imgUrl">
- <div class="imgUploadBox">
- <el-upload action="" :http-request="(e) => handleImageUpload(e, 'imgUrl')" :multiple="false" :show-file-list="false" v-if="!addEditVideo.imgUrl">
- <div class="image-upload-item">
- <img src="~@/assets/icons/uploadImg-blue.svg" />
- <span>添加列表页封面</span>
- </div>
- </el-upload>
- <div v-else class="uploaded-image-item">
- <el-image :src="addEditVideo.imgUrl" class="videoImage" :preview-src-list="[addEditVideo.imgUrl]" />
- <span class="del-image" @click="addEditVideo.imgUrl = ''">删除</span>
- </div>
- </div>
- </el-form-item>
- <el-form-item prop="detailImgUrl">
- <div class="imgUploadBox">
- <el-upload action="" :http-request="(e) => handleImageUpload(e, 'detailImgUrl')" :multiple="false" :show-file-list="false" v-if="!addEditVideo.detailImgUrl">
- <div class="image-upload-item">
- <img src="~@/assets/icons/uploadImg-blue.svg" />
- <span>添加详情页封面</span>
- </div>
- </el-upload>
- <div v-else class="uploaded-image-item">
- <el-image :src="addEditVideo.detailImgUrl" class="videoImage" :preview-src-list="[addEditVideo.detailImgUrl]" />
- <span class="del-image" @click="addEditVideo.detailImgUrl = ''">删除</span>
- </div>
- </div>
- </el-form-item>
- <el-form-item prop="shareImgUrl">
- <div class="imgUploadBox">
- <el-upload action="" :http-request="(e) => handleImageUpload(e, 'shareImgUrl')" :multiple="false" :show-file-list="false" v-if="!addEditVideo.shareImgUrl">
- <div class="image-upload-item">
- <img src="~@/assets/icons/uploadImg-blue.svg" />
- <span>添加视频分享图</span>
- </div>
- </el-upload>
- <div v-else class="uploaded-image-item">
- <el-image :src="addEditVideo.shareImgUrl" class="videoImage" :preview-src-list="[addEditVideo.shareImgUrl]" />
- <span class="del-image" @click="addEditVideo.shareImgUrl = ''">删除</span>
- </div>
- </div>
- </el-form-item>
- </div>
- </el-form>
- </div>
- <template #footer>
- <span class="dialog-footer">
- <el-button type="primary" @click="confirmSubmit(0)">保存</el-button>
- <el-button type="primary" v-if="publishStatus != 1" @click="confirmSubmit(1)">发布</el-button>
- <el-button @click="cancelHandle">取消</el-button>
- </span>
- </template>
- </el-dialog>
- </div>
- </template>
- <style lang="scss">
- .add-edit-video {
- .add-edit-video-dlg {
- .el-input {
- width: 100%;
- }
- }
- }
- </style>
- <style lang="scss" scoped>
- .uploadImageContain {
- display: flex;
- justify-content: space-between;
- .imgUploadBox {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 110px;
- height: 110px;
- .image-upload-item {
- display: flex;
- flex-direction: column;
- justify-content: center;
- img {
- height: 32px;
- }
- span {
- color: #409eff;
- font-weight: 400;
- font-size: 14px;
- }
- }
- .uploaded-image-item {
- height: 110px;
- width: 110px;
- display: flex;
- justify-content: center;
- .videoImage {
- border-radius: 1px;
- }
- .del-image {
- display: none;
- color: #fff;
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- text-align: center;
- line-height: 24px;
- width: 110px;
- background-color: rgba($color: #000000, $alpha: 0.8);
- cursor: pointer;
- }
- &:hover {
- .del-image {
- display: block;
- }
- }
- }
- }
- }
- </style>
|