zxl
2025-08-13 934654b44fb2670a7ce08aafa3d1d85fe783ae26
manager/src/views/video/VideoList.vue
@@ -115,10 +115,25 @@
              </FormItem>
            </Col>
          </Row>
          <Row>
            <Col span="24" v-show="uploadVideoForm.videoFileKey && !uploadVideoForm.coverUrl">
              <FormItem label="上传封面" prop="coverUrl" :label-width="80">
                <Upload
                  :multiple="true"
                  :before-upload="upLoadImagCover"
                  accept="image/*"
                  action=""
                >
                  <Button icon="ios-cloud-upload-outline">选择封面</Button>
                </Upload>
              </FormItem>
            </Col>
          </Row>
          <Row :gutter="24">
            <Col span="12" v-if="uploadVideoForm.videoFileKey">
              <FormItem :labelWidth="80">
                <Button @click="reloadVideo" type="primary">重新上传视频</Button>
                <Button @click="reloadVideo" type="primary" >重新上传视频</Button>
                <Button type="primary" @click="clearCoverImage" v-show="uploadVideoForm.coverUrl" style="margin-left: 20px">重新上传封面</Button>
              </FormItem>
            </Col>
          </Row>
@@ -134,9 +149,9 @@
                        <Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>
                      </div>
                    </template>
                    <!--                    <template v-else>-->
                    <!--                      <Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>-->
                    <!--                    </template>-->
                    <!--                      <template v-else>-->
                    <!--                        <Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>-->
                    <!--                      </template>-->
                  </div>
                  <Upload
                    ref="upload"
@@ -212,14 +227,16 @@
                          align-items: center;justify-content: flex-start;border: 1px solid gray;margin-top: 10px;
                          padding: 10px;border-radius: 20px">
                    <div>
                      <img :src="endpoint+'/'+item.thumbnail" style="width: 80px;height: 80px">
                      <img :src="item.thumbnail.includes('http') ? item.thumbnail : endpoint + '/' + item.thumbnail"
                           style="width: 80px;height: 80px">
                    </div>
                    <div style="display: flex;flex-direction: column;margin-left: 20px">
                      <div style="font-size: 1.5em;font-weight: bold">{{ item.goodsName }}</div>
                      <div style="color: #ff6f6f;display: flex;align-content: center;justify-content: flex-start">
                        <div> ¥{{ item.price }}</div>
                        <div style="margin-left: 10px">
                          <InputNumber v-model="item.goodsNum" :min="0" :max="99" controls-outside @on-change="changeGoodsNum(item.goodsSkuId,index,item.goodsNum)"
                          <InputNumber v-model="item.goodsNum" :min="0" :max="99" controls-outside
                                       @on-change="changeGoodsNum(item.goodsSkuId,index,item.goodsNum)"
                                       style="vertical-align: center;width: 100px"></InputNumber>
                        </div>
                      </div>
@@ -402,6 +419,9 @@
          <Button type="primary" size="small" style="margin-right: 5px" v-if="row.status === '99'"
                  @click="openAuditing(row)">审核
          </Button>
          <Button type="primary" size="small" style="margin-right: 5px"
                  @click="editVideo(row)">编辑
          </Button>
          <Button type="error" size="small" style="margin-right: 5px" v-if="row.status === '1'"
                  @click="openVideoDown(row)">下架
          </Button>
@@ -420,7 +440,7 @@
        :mask-closable="false"
      >
        <vue-qr
          text="https://myk.9village.cn/scanpage/recommend?shareType=videoRecommend&videoId=1948284811844190209"
          :text="QRCodeUrl"
          :margin="0"
          colorDark="#000"
          colorLight="#fff"
@@ -428,7 +448,7 @@
        ></vue-qr>
        <div slot="footer">
          <Button type="text" @click="closeGeneralQrCode">关闭</Button>
          <Button type="primary" @click="generalQrCode">确认</Button>
          <!--          <Button type="primary" @click="generalQrCode">确认</Button>-->
        </div>
      </Modal>
      <Row type="flex" justify="end" class="mt_10">
@@ -450,7 +470,17 @@
</template>
<script>
import {getVideos, recommendSet, getVideoById, auditingVideo, up, down, recreateIndex,publish} from "@/api/video";
import {
  getVideos,
  recommendSet,
  getVideoById,
  auditingVideo,
  up,
  down,
  recreateIndex,
  publish,
  updatePublish
} from "@/api/video";
import {getVideoTagList, recommend, videoGoodsEsPage} from "@/api/videoTag";
import {getFilePreview, getSts} from "@/api/file";
import Editor from '@/components/editor/index.vue'
@@ -459,10 +489,16 @@
import {getFileKey} from "@/utils/file";
import vuedraggable from "vuedraggable";
import vueQr from "vue-qr";
import uploadImage from "../../components/editor/upload-image.vue";
export default {
  name: "VideoList",
  components: {vuedraggable, Editor, GoodsExpandRow,"vue-qr": vueQr},
  computed: {
    uploadImage() {
      return uploadImage
    }
  },
  components: {vuedraggable, Editor, GoodsExpandRow, "vue-qr": vueQr},
  watch: {
    'uploadVideoForm.videoContentType'(newValue, oldValue) {
      if (newValue === 'video') {
@@ -478,6 +514,7 @@
      }
    },
    chooseTag(newValue, oldValue) {
      console.log('触发新值变化',newValue);
      this.uploadVideoForm.tags = newValue.map(item => {
        const findTag = this.videoTagList.find(tagItem => {
          return tagItem.tagName === item
@@ -499,7 +536,10 @@
  },
  data() {
    return {
      showGeneralQrCode:false,
      // https://myk.9village.cn/scanpage/recommend?shareType=videoRecommend&videoId=1948284811844190209
      baseQRCodeUrl: this.QRcodeBaseUrl + '/scanpage/recommend',
      QRCodeUrl: '',
      showGeneralQrCode: false,
      endpoint: '',
      searchGoods: '',
      videoTagList: [],
@@ -513,6 +553,8 @@
      videoProgress: 0,
      upLoadVideoShow: false,
      uploadVideoForm: {
        coverUrl:null,
        showCoverUrl:null,
        id: '',
        title: '',
        cover: "",
@@ -686,6 +728,7 @@
          slot: "action",
          align: "center",
          width: 200,
          fixed: "right"
        },
      ],
      goodsData: [],
@@ -701,13 +744,85 @@
    this.getTags('')
  },
  methods: {
    generalQrCode(row){
    async editVideo(row) {
      // this.uploadVideoForm = {};
      // this.uploadVideoForm = row;
      // this.showUploadVideoShow = true;
      this.videoTagList = []
     await recommend({
        searchType: "HOT"
      }).then(res => {
        this.videoTagList = res.data;
      })
      this.upLoadVideoShow = true;
      this.chooseTag = row.tagList.map(item => {
        return item.tagName
      })
      console.log('选中列表---》',row.goodsList)
      row.goodsList.forEach(item => {
        item.goodsSkuId = item.id
      })
      this.uploadVideoForm = {
        id: '',
        title: '',
        cover: "",
        videoFileKey: "",
        videoDuration: 0,
        videoFit: "cover",
        videoContentType: 'video',
        videoImgs: [],
        showListImages: [],
        tags: [],
        fileInfo: {},
        goodsList: []
      }
      // 遍历已选择的标签
      row.tagList.forEach(tag => {
        // 检查标签是否已存在于videoTagList中
        const exists = this.videoTagList.some(item => item.tagName === tag.tagName);
        // 如果不存在,则添加到选项列表
        if (!exists) {
          this.videoTagList.push({
            id: tag.id, // 生成临时ID
            tagName: tag.tagName
          });
        }
      });
      this.uploadVideoForm = row
      console.log("打印值",this.uploadVideoForm)
      this.uploadVideoForm.fileInfo= {};
      this.uploadVideoForm.videoImgs = JSON.parse(this.uploadVideoForm.videoImgs)
      const sts = await getSts();
      if (this.uploadVideoForm.videoContentType === 'video') {
        this.uploadVideoForm.showVideoUrl = sts.data.endpoint + '/' + this.uploadVideoForm.videoFileKey
        if (this.uploadVideoForm.coverUrl !== '' && this.uploadVideoForm.coverUrl != null) {
          this.uploadVideoForm.showCoverUrl =  this.uploadVideoForm.coverUrl
        }
      } else if (this.uploadVideoForm.videoContentType === 'img') {
        this.uploadVideoForm.showListImages = this.uploadVideoForm.videoImgs.map(item => {
          return sts.data.endpoint + '/' + item
        })
      }
      console.log("处理过后",this.uploadVideoForm)
      this.searchGoodsList();
    },
    closeGeneralQrCode() {
      this.showGeneralQrCode = false;
      this.QRCodeUrl = '';
    },
    generalQrCode(row) {
      this.showGeneralQrCode = true
      console.log('-------------------->',row);
      console.log('-------------------->', row);
      this.QRCodeUrl = this.baseQRCodeUrl + '?shareType=videoRecommend' + '&videoId=' + row.id;
      console.log(this.QRCodeUrl)
    },
    //todo 保留后续可能会使用
    changeGoodsNum(id,index,goodsNum){
      console.log('-------------------->',id,index,goodsNum)
    changeGoodsNum(id, index, goodsNum) {
      console.log('-------------------->', id, index, goodsNum)
    },
    chooseGoods(id) {
      const goods = this.goodsData.find(item => {
@@ -744,38 +859,59 @@
      this.upLoadVideoShow = false;
    },
    submitVideoUpload() {
      this.uploadVideoForm.goodsList =  this.uploadVideoForm.goodsList.filter(item => {
        return item.goodsNum >0;
      console.log(this.uploadVideoForm.coverUrl)
      if (this.uploadVideoForm.coverUrl === null || this.uploadVideoForm.coverUrl === undefined) {
        this.$Message.error('标题不能为空');
        return;
      }
      this.uploadVideoForm.goodsList = this.uploadVideoForm.goodsList.filter(item => {
        return item.goodsNum > 0;
      })
      if (!this.uploadVideoForm.title) {
        this.$Message.error('标题不能为空');
        return;
      }
      //表单校验
      if (this.uploadVideoForm.videoContentType==='video') {
        if (!this.uploadVideoForm.videoFileKey){
      if (this.uploadVideoForm.videoContentType === 'video') {
        if (!this.uploadVideoForm.videoFileKey) {
          this.$Message.error('视频不能为空');
          return;
        }
      }
      if (this.uploadVideoForm.videoContentType==='img') {
        if (this.uploadVideoForm.videoImgs<1){
      if (this.uploadVideoForm.videoContentType === 'img') {
        if (this.uploadVideoForm.videoImgs < 1) {
          this.$Message.error('图片不能为空');
          return;
        }
      }
      publish(this.uploadVideoForm).then(response => {
        if (response.code == 200) {
          this.$Message.success("视频发布成功");
          this.upLoadVideoShow = false;
          this.getDataList();
        }
      }).then(error=>{
        this.$Message.success(error);
      })
      console.log('提交表单--------------->', this.uploadVideoForm)
      if (this.uploadVideoForm.id) {
        updatePublish(this.uploadVideoForm).then(response => {
          if (response.code == 200) {
            this.$Message.success("视频修改成功");
            this.upLoadVideoShow = false;
            this.getDataList();
          }
        }).then(error => {
          this.$Message.success(error);
        })
      } else {
        publish(this.uploadVideoForm).then(response => {
          if (response.code == 200) {
            this.$Message.success("视频发布成功");
            this.upLoadVideoShow = false;
            this.getDataList();
          }
        }).then(error => {
          this.$Message.success(error);
        })
      }
    },
    //todo 后续可能会使用预留
    createVideoTag(e) {
      console.log('------------>',e)
    },
    handleRemove(file) {
      const fileList2 = this.uploadVideoForm.showListImages;
@@ -786,13 +922,62 @@
      this.imgName = name;
      this.visible = true;
    },
    async upLoadImagCover(file) {
      try {
        // 获取文件上传临时密钥
        const sts = await getSts();
        const cos = new COS({
          getAuthorization: async function (options, callback) {
            callback({
              TmpSecretId: sts.data.tmpSecretId,
              TmpSecretKey: sts.data.tmpSecretKey,
              SecurityToken: sts.data.sessionToken,
              // 建议返回服务器时间作为签名的开始时间,避免客户端本地时间偏差过大导致签名错误
              StartTime: sts.data.stsStartTime, // 时间戳,单位秒,如:1580000000
              ExpiredTime: sts.data.stsEndTime,// 时间戳,单位秒,如:1580000000
              ScopeLimit: true, // 细粒度控制权限需要设为 true,会限制密钥只在相同请求时重复使用
            });
          }
        })
        const fileKey = getFileKey(file.name)
        const upData = await cos.uploadFile({
          Bucket: sts.data.bucket,
          Region: sts.data.region,
          Key: fileKey,
          Body: file, // 要上传的文件对象。cover
          SliceSize: 1024 * 1024 * 5,
          onProgress: function (progressData) {
            console.log('上传进度:', progressData);
          },
        });
        this.$set(this.uploadVideoForm, 'coverUrl', fileKey);
        this.$set(this.uploadVideoForm, 'showCoverUrl', `${sts.data.endpoint}/${fileKey}`);
        this.uploadVideoForm.cover = fileKey;
        if (this.$refs.videoInfo) {
          this.$refs.videoInfo.poster = this.uploadVideoForm.showCoverUrl;
          this.$refs.videoInfo.load(); // 重新加载视频
        }
        console.log(this.uploadVideoForm)
      } catch (e) {
        console.log("上传失败", upData)
      } finally {
      }
      return false;
    },
    clearCoverImage(){
      this.$set(this.uploadVideoForm, 'coverUrl', '');
      this.$set(this.uploadVideoForm, 'showCoverUrl', '');
      this.$set(this.uploadVideoForm, 'temp', new Date().getTime());
    },
    async upLoadImg(file) {
      if (this.uploadVideoForm.videoImgs >= 5) {
        this.$Message.error("图片上传不能超过5个");
        return;
      }
      try {
        // this.upLoadVideoLoading = true;
        // 获取文件上传临时密钥
        const sts = await getSts();
        const cos = new COS({
@@ -829,7 +1014,6 @@
        console.log("上传失败", upData)
        return false;
      } finally {
        // this.upLoadVideoLoading = false;
      }
      return false;
@@ -894,7 +1078,7 @@
          this.uploadVideoForm.showVideoUrl = sts.data.endpoint + "/" + fileKey;
        })
        console.log("上传成功", upData)
        const duration = this.$refs.healthVideoInfo.duration;
        const duration = this.$refs.videoInfo.duration;
        console.log('-测试获取时间信息---------------->', duration);
      } catch (e) {
        console.log("上传失败", upData)
@@ -1100,7 +1284,7 @@
    // 获取列表数据
    getGoodsDataList() {
      let search = this.searchGoodsForm;
      console.log('-------------------------->',this.searchGoodsForm)
      console.log('-------------------------->', this.searchGoodsForm)
      if (search.pageNumber > 0) {
        search.pageNumber = search.pageNumber - 1;
      }
@@ -1157,7 +1341,7 @@
    },
    // 分页 改变页码
    goodsChangePage(v) {
      console.log('-------------------------->分页',v);
      console.log('-------------------------->分页', v);
      this.searchGoodsForm.pageNumber = v;
      this.getGoodsDataList();
    },