From c1e567ddda7f65651179a8a73ca849b07b066b14 Mon Sep 17 00:00:00 2001
From: zxl <763096477@qq.com>
Date: 星期四, 19 六月 2025 19:58:42 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev

---
 manager/src/api/kitchen-video.js                            |   33 
 manager/src/views/video/VideoList.vue                       |   67 +
 manager/src/api/kitchen.js                                  |   48 
 seller/src/views/goods/goods-seller/goodsOperation.vue      |    6 
 manager/src/views/goods/goods-info/goods.vue                |   18 
 manager/src/views/goods/goods-info/goodsApply.vue           |    6 
 manager/src/views/goods/goods-info/goodsDetail.vue          |   21 
 manager/src/views/kitchen/kitchenVideo.vue                  |  975 +++++++++++++++++
 manager/package.json                                        |    5 
 seller/src/api/file.js                                      |   31 
 manager/src/api/file.js                                     |    9 
 seller/src/libs/axios.js                                    |    3 
 manager/src/views/video/GoodsExpandRow.vue                  |   35 
 manager/src/api/health-video.js                             |   33 
 seller/src/utils/file.js                                    |   40 
 seller/package.json                                         |    1 
 seller/src/views/goods/goods-seller/goodsOperationFirst.vue |   48 
 seller/src/views/goods/goods-seller/goods.vue               |    3 
 manager/src/views/health/HealthVideoList.vue                |  929 ++++++++++++++++
 manager/src/views/kitchen/kitchenType.vue                   |  370 ++++++
 manager/src/utils/file.js                                   |   40 
 seller/src/views/goods/goods-seller/goodsOperationSec.vue   |  618 ++++++++--
 22 files changed, 3,139 insertions(+), 200 deletions(-)

diff --git a/manager/package.json b/manager/package.json
index 7090251..8de4220 100644
--- a/manager/package.json
+++ b/manager/package.json
@@ -14,9 +14,11 @@
     "@antv/g2": "^4.1.12",
     "axios": "^0.21.1",
     "core-js": "^3.6.5",
+    "cos-js-sdk-v5": "^1.10.1",
     "dplayer": "^1.26.0",
     "js-cookie": "^2.2.1",
     "node-sass": "^4.14.1",
+    "price-color": "1.0.2",
     "sass-loader": "^8.0.2",
     "sockjs-client": "^1.4.0",
     "swiper": "^6.3.5",
@@ -31,8 +33,7 @@
     "vue-router": "^3.1.3",
     "vuedraggable": "^2.23.2",
     "vuex": "^3.4.0",
-    "xss": "^1.0.7",
-    "price-color": "1.0.2"
+    "xss": "^1.0.7"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "^4.4.4",
diff --git a/manager/src/api/file.js b/manager/src/api/file.js
index 8cdbd88..2d866b6 100644
--- a/manager/src/api/file.js
+++ b/manager/src/api/file.js
@@ -12,3 +12,12 @@
     })
 }
 
+// 鑾峰彇STS璁块棶浠ょ墝
+export const getSts = () => {
+    return service({
+        baseURL: commonUrl,
+        url: "/common/lmk/file/sts",
+        method: "GET"
+    })
+}
+
diff --git a/manager/src/api/health-video.js b/manager/src/api/health-video.js
new file mode 100644
index 0000000..76adb3c
--- /dev/null
+++ b/manager/src/api/health-video.js
@@ -0,0 +1,33 @@
+import service from "@/libs/axios";
+
+// 瑙嗛鍙戝竷
+export const healthVideo = (data) => {
+  return service({
+    url: "/lkm/health/healthVideo",
+    method: "POST",
+    data: data
+  })
+}
+// 瑙嗛淇敼
+export const updateHealthVideo = (data) => {
+  return service({
+    url: "/lkm/health/updateHealthVideo",
+    method: "POST",
+    data: data
+  })
+}
+// 瑙嗛鏌ヨ
+export const getHealthVideos = (data) => {
+  return service({
+    url: "/lkm/health/page",
+    method: "POST",
+    data: data
+  })
+}
+// 瑙嗛鏌ヨ
+export const delHealth = (id) => {
+  return service({
+    url: "/lkm/health/del/" + id,
+    method: "POST"
+  })
+}
diff --git a/manager/src/api/kitchen-video.js b/manager/src/api/kitchen-video.js
new file mode 100644
index 0000000..5f1fb28
--- /dev/null
+++ b/manager/src/api/kitchen-video.js
@@ -0,0 +1,33 @@
+import service from "@/libs/axios";
+
+// 鍘ㄧ瑙嗛鍙戝竷
+export const addKitchenVideo = (data) => {
+  return service({
+    url: "/lmk/kitchen-video/addKitchenVideo",
+    method: "POST",
+    data: data
+  })
+}
+// 瑙嗛淇敼
+export const updateKitchenVideo = (data) => {
+  return service({
+    url: "/lmk/kitchen-video/updateKitchenVideo",
+    method: "POST",
+    data: data
+  })
+}
+// 瑙嗛鏌ヨ
+export const getKitchenVideos = (data) => {
+  return service({
+    url: "/lmk/kitchen-video/page",
+    method: "POST",
+    data: data
+  })
+}
+// 鍒犻櫎瑙嗛
+export const delKitchen = (id) => {
+  return service({
+    url: "/lmk/kitchen-video/del/" + id,
+    method: "POST"
+  })
+}
diff --git a/manager/src/api/kitchen.js b/manager/src/api/kitchen.js
new file mode 100644
index 0000000..855cfe4
--- /dev/null
+++ b/manager/src/api/kitchen.js
@@ -0,0 +1,48 @@
+import service from "@/libs/axios";
+
+// 绁炲帹鍒嗛〉
+export const getKitchenType = (data) => {
+  return service({
+    url: "/lmk/kitchen-type/page",
+    method: "GET",
+    params: data
+  })
+}
+// 绁炲帹鍒嗙被涓嶅垎椤�
+export const getKitchenTypeAllList = () => {
+  return service({
+    url: "/lmk/kitchen-type/list",
+    method: "GET",
+  })
+}
+// 娣诲姞绁炲帹鏍囩
+export const addKitchenType = (data) => {
+  return service({
+    url: "/lmk/kitchen-type",
+    method: "POST",
+    data: data
+  })
+}
+// 娣诲姞绁炲帹鏍囩
+export const editKitchenType = (data) => {
+  return service({
+    url: "/lmk/kitchen-type",
+    method: "PUT",
+    data: data
+  })
+}
+// 鍒犻櫎绁炲帹鏍囩
+export const delKitchenType = (id) => {
+  return service({
+    url: "/lmk/kitchen-type/"+id,
+    method: "DELETE",
+  })
+}
+// 鎵归噺鍒犻櫎绁炲帹鏍囩
+export const deleteBatch = (data) => {
+  return service({
+    url: "/lmk/kitchen-type/batch",
+    method: "DELETE",
+    data: data
+  })
+}
diff --git a/manager/src/utils/file.js b/manager/src/utils/file.js
new file mode 100644
index 0000000..74cfa34
--- /dev/null
+++ b/manager/src/utils/file.js
@@ -0,0 +1,40 @@
+
+/**
+ * 鐢熸垚fileKey
+ *
+ * @param fileName 鏂囦欢鍚�
+ * @returns {*}
+ */
+export function getFileKey (fileName) {
+    const extension = fileName.split('.').pop().toLowerCase();
+        
+	const fileTypes = {
+		image: { name: '鍥剧墖', exts: ["jpg", "png", "jpeg", "gif", "bmp", "webp", "tiff", "svg", "ico", "psd", "raw"] },
+		video: { name: '瑙嗛', exts: ["mp4", "avi", "rmvb", "mov", "wmv", "flv", "mkv", "mpeg", "mpg", "m4v", "3gp", "webm", "vob", "swf"] },
+		radio: { name: '闊抽', exts: ["mp3", "wma", "wav", "mpeg-4", "cd", "m4a", "aac", "flac", "ogg", "aiff", "ape", "midi", "amr", "ra"] },
+		text: { name: '鏂囨湰', exts: ["txt", "xls", "xlsx", "doc", "docx", "pdf", "ppt", "pptx", "csv", "rtf", "odt", "ods", "odp", "epub", "mobi", "pages", "numbers", "key"] },
+		zip: { name: '鍘嬬缉鏂囦欢', exts: ["zip", "rar", "7z", "tar", "gz", "bz2", "xz", "iso", "dmg", "pkg", "cab", "z", "lz", "lzma", "lzo"] }
+	};
+  
+	// 鑾峰彇褰撳墠鏃堕棿骞舵牸寮忓寲涓� yyyyMMddHHmmss
+	const now = new Date();
+	const yyyyMMddHHmmss = [
+		now.getFullYear(),
+		String(now.getMonth() + 1).padStart(2, '0'),
+		String(now.getDate()).padStart(2, '0'),
+		String(now.getHours()).padStart(2, '0'),
+		String(now.getMinutes()).padStart(2, '0'),
+		String(now.getSeconds()).padStart(2, '0')
+	].join('');
+	
+	// 鐢熸垚5浣嶉殢鏈烘暟瀛�
+	const random5Digits = Math.floor(10000 + Math.random() * 90000);
+	
+	// 鏌ユ壘鍖归厤鐨勬枃浠剁被鍨�
+	for (const [type, data] of Object.entries(fileTypes)) {
+		if (data.exts.includes(extension)) {
+			return `${type}/${yyyyMMddHHmmss}${random5Digits}` + '.' + extension;
+		}
+	}
+    return '';
+}
diff --git a/manager/src/views/goods/goods-info/goods.vue b/manager/src/views/goods/goods-info/goods.vue
index 7a5f7d3..7d1d4e4 100644
--- a/manager/src/views/goods/goods-info/goods.vue
+++ b/manager/src/views/goods/goods-info/goods.vue
@@ -89,9 +89,12 @@
         <template slot="goodsSlot" slot-scope="{ row }">
           <div style="margin: 5px 0px; height: 80px; display: flex">
             <div style="">
-              <img
+              <img v-if="row.original"
                 :src="row.original"
                 style="height: 60px; margin-top: 1px; width: 60px"
+              />
+              <video v-else
+                     :src="row.goodsVideo" style="height: 60px; margin-top: 1px; width: 60px"
               />
             </div>
 
@@ -159,6 +162,7 @@
 
 <script>
 import { getGoodsListData, upGoods, lowGoods } from "@/api/goods";
+import {getSts} from '@/api/file'
 import vueQr from "vue-qr";
 export default {
   components: {
@@ -376,6 +380,18 @@
         this.loading = false;
         if (res.success) {
           this.data = res.result.records;
+          getSts().then(res => {
+         const endpoint = res.data.endpoint
+            this.data.forEach(item => {
+              if (item.goodsVideo != null && item.goodsVideo.indexOf('http')===-1) {
+                item.goodsVideo = endpoint + '/' + item.goodsVideo;
+              }
+              if (item.original !=null && item.original.indexOf('http') ===-1) {
+                item.original = endpoint + '/' + item.original;
+              }
+            })
+          })
+
           this.total = res.result.total;
         }
       });
diff --git a/manager/src/views/goods/goods-info/goodsApply.vue b/manager/src/views/goods/goods-info/goodsApply.vue
index 30deb6a..8b8aa08 100644
--- a/manager/src/views/goods/goods-info/goodsApply.vue
+++ b/manager/src/views/goods/goods-info/goodsApply.vue
@@ -42,11 +42,13 @@
         <!-- 鍟嗗搧鏍忕洰鏍煎紡鍖� -->
         <template slot="goodsSlot" slot-scope="scope">
           <div style="margin-top: 5px; height: 80px; display: flex">
-            <div style="">
-              <img
+            <div style="" >
+              <img v-if="scope.row.original"
                 :src="scope.row.original"
                 style="height: 60px; margin-top: 3px; width: 60px"
               />
+              <video v-else :src="scope.row.goodsVideo"      style="height: 60px; margin-top: 3px; width: 60px"
+              />
             </div>
 
             <div style="margin-left: 13px">
diff --git a/manager/src/views/goods/goods-info/goodsDetail.vue b/manager/src/views/goods/goods-info/goodsDetail.vue
index 60d4c41..af66491 100644
--- a/manager/src/views/goods/goods-info/goodsDetail.vue
+++ b/manager/src/views/goods/goods-info/goodsDetail.vue
@@ -143,6 +143,7 @@
 </template>
 <script>
 import { getGoodsDetail } from "@/api/goods";
+import {getSts} from '@/api/file'
 export default {
   name: "goodsDetail",
   data() {
@@ -193,6 +194,26 @@
     initGoods(id) {
       getGoodsDetail(id).then((res) => {
         this.goods = res.result;
+        if (this.goods.goodsVideo != null && this.goods.goodsVideo !== '') {
+          getSts().then(res => {
+            console.log('--------------->',this.goods.goodsVideo.indexOf('http')!== -1)
+            if (this.goods.goodsVideo !== null && this.goods.goodsVideo.indexOf('http')=== -1) {
+              this.goods.goodsVideo = res.data.endpoint+'/'+this.goods.goodsVideo;
+            }
+          })
+        }
+        if (this.goods.goodsGalleryList != null && this.goods.goodsGalleryList.length > 0) {
+          getSts().then(res => {
+            this.goods.goodsGalleryList =  this.goods.goodsGalleryList.map((item) => {
+              if (item !== null&&item.indexOf('http')===-1) {
+                return  res.data.endpoint+'/'+item;
+              }else {
+                return item;
+              }
+            })
+          })
+        }
+
         let that = this;
         res.result.skuList.forEach(function (sku, index, array) {
           that.skuData.push({
diff --git a/manager/src/views/health/HealthVideoList.vue b/manager/src/views/health/HealthVideoList.vue
new file mode 100644
index 0000000..43ef70c
--- /dev/null
+++ b/manager/src/views/health/HealthVideoList.vue
@@ -0,0 +1,929 @@
+<template>
+  <div>
+    <Card>
+      <Form
+        ref="searchForm"
+        @keydown.enter.native="handleSearch"
+        :model="searchForm"
+        inline
+        :label-width="70"
+        class="search-form"
+      >
+        <Form-item label="鏍囬" prop="title">
+          <Input
+            type="text"
+            v-model="searchForm.title"
+            clearable
+            @on-clear="handleSearch"
+            @on-change="handleSearch"
+            style="width: 160px"
+          />
+        </Form-item>
+<!--      todo  鏆傛椂闅愯棌澶у仴搴蜂竴鏈熸病瀹氫箟鏍囩-->
+        <Form-item v-if="false" label="鏍囩" prop="tagList">
+          <Select
+            v-model="searchForm.tagList"
+            clearable
+            filterable
+            multiple
+            @on-clear="handleSearch"
+            @on-change="handleSearch"
+            style="width: 160px"
+          >
+            <Option v-for="tag in tagList" :key="tag.id" :value="tag.id">{{ tag.tagName }}</Option>
+          </Select>
+        </Form-item>
+        <Form-item label="瑙嗛鐘舵��" prop="status">
+          <Select
+            v-model="searchForm.status"
+            clearable
+            @on-clear="handleSearch"
+            @on-change="handleSearch"
+            style="width: 160px"
+          >
+            <Option value="99">寰呭鏍�</Option>
+            <Option value="1">宸插彂甯�</Option>
+            <Option value="0">宸蹭笅鏋�</Option>
+            <Option value="-1">瀹℃牳鏈�氳繃</Option>
+          </Select>
+        </Form-item>
+        <Button
+          @click="handleSearch"
+          type="primary"
+          icon="ios-search"
+          class="search-btn"
+        >鎼滅储
+        </Button
+        >
+        <Button
+          @click="handleVideoUpLoad"
+          type="primary"
+          icon="md-arrow-up"
+          class="search-btn"
+        >涓婁紶瑙嗛
+        </Button
+        >
+      </Form>
+      <!--      澶у仴搴疯棰戜笂浼�-->
+      <Modal
+        v-model="upLoadVideoShow"
+        :title="uploadVideoForm.id?'缂栬緫澶у仴搴疯棰�':'涓婁紶澶у仴搴疯棰�'"
+        width="800"
+        :mask-closable="false"
+      >
+
+        <Form
+          :model="uploadVideoForm"
+          ref="uploadVideoForm"
+          :rules="uploadVideoFileRule"
+        >
+          <Row :gutter="24">
+            <Col span="24">
+              <Spin size="large" fix v-if="upLoadVideoLoading"> 鏂囦欢涓婁紶涓�...</Spin>
+            </Col>
+            <Col span="12">
+              <FormItem label="鏍囬" prop="title">
+                <Input placeholder="璇疯緭鍏ユ爣棰�" v-model="uploadVideoForm.title"
+                       style="width: 200px"
+                />
+              </FormItem>
+            </Col>
+            <Col span="24">
+              <FormItem label="鍒锋柊dom浣跨敤" prop="title" v-show="false">
+                <Input placeholder="璇疯緭鍏ユ爣棰�" v-model="uploadVideoForm.temp"
+                       style="width: 200px"
+                />
+              </FormItem>
+            </Col>
+            <Col span="12" v-if="!uploadVideoForm.videoFileKey">
+              <FormItem label="涓婁紶瑙嗛" prop="videoFileKey">
+                <Upload
+                  :multiple="true"
+                  :before-upload="upLoadVideo"
+                  accept="video/*"
+                  action=""
+                >
+                  <Button icon="ios-cloud-upload-outline">閫夋嫨瑙嗛</Button>
+                </Upload>
+              </FormItem>
+            </Col>
+
+            <Col span="24" v-else>
+              <FormItem label="瑙嗛">
+                <video style="width: 150px;height: 150px"
+                       controls
+                       @loadedmetadata="getVideoDuration"
+                       :poster="uploadVideoForm.showCoverUrl"
+                       :autoplay="false"
+                       id="remoteVideo" :src="uploadVideoForm.showVideoUrl"
+                       ref="healthVideoInfo"
+                ></video>
+              </FormItem>
+            </Col>
+
+            <Col span="12" v-show="uploadVideoForm.videoFileKey && !uploadVideoForm.coverUrl">
+              <FormItem label="涓婁紶灏侀潰" prop="coverUrl">
+                <Upload
+                  :multiple="true"
+                  :before-upload="upLoadImg"
+                  accept="image/*"
+                  action=""
+                >
+                  <Button icon="ios-cloud-upload-outline">閫夋嫨灏侀潰</Button>
+                </Upload>
+              </FormItem>
+            </Col>
+            <Col span="24">
+              <div>
+                <Button type="primary" @click="clearCoverImage" v-show="uploadVideoForm.coverUrl">閲嶆柊涓婁紶灏侀潰</Button>
+                <Button type="primary" @click="clearVideo" style="margin-left: 20px"
+                        v-show="uploadVideoForm.videoFileKey">閲嶆柊涓婁紶瑙嗛
+                </Button>
+              </div>
+            </Col>
+            <!--            <Col span="24" v-else>-->
+            <!--              <FormItem label="灏侀潰">-->
+            <!--                <div class="showCoverImg" style="width: 150px;height: 150px;">-->
+            <!--                  <img :src="uploadVideoForm.showCoverUrl" style="width: 150px;height: 150px" class="coverImg"/>-->
+            <!--                  <Icon type="ios-close" size="24" class="coverImgRemove" color="red"-->
+            <!--                        style="border-radius: 50%;background: #fff;cursor: pointer"-->
+            <!--                        @click="removeCover"-->
+            <!--                  />-->
+            <!--                </div>-->
+            <!--              </FormItem>-->
+            <!--            </Col>-->
+          </Row>
+
+        </Form>
+        <div slot="footer">
+          <Button type="text" @click="closeHealthVideo">鍏抽棴</Button>
+          <Button type="primary" @click="submitHealthVideo">纭</Button>
+        </div>
+      </Modal>
+      <Modal
+        v-model="playVideoShow"
+        :title="playVideoTitle"
+        width="800"
+        :mask-closable="false"
+      >
+        <div class="video-warp">
+          <video :src="playVideoUrl" autoplay controls style="width: 768px;height: 432px"/>
+        </div>
+        <div slot="footer">
+          <Button type="text" @click="playVideoClose">鍏抽棴</Button>
+        </div>
+      </Modal>
+
+      <Modal
+        v-model="auditingShow"
+        title="瑙嗛瀹℃牳"
+        width="800"
+        :loading="auditingLoading"
+        :mask-closable="false"
+      >
+
+        <Form
+          ref="auditingForm"
+          :model="auditingForm"
+          :label-width="70"
+          :rules="auditingRule"
+        >
+          <Form-item label="鏍囬锛�">
+            <div>{{ detail.title }}</div>
+          </Form-item>
+          <Form-item label="鏍囩锛�">
+            <div style="display: flex;flex-wrap: wrap">
+              <div v-for="(tag, index) in detail.tagList" :key="'tag' + index" style="margin-right: 5px">
+                <Tag color="red">{{ tag.tagName }}</Tag>
+              </div>
+            </div>
+          </Form-item>
+          <Form-item label="瑙嗛鏃堕暱锛�" :label-width="72">
+            <div>{{ formatSeconds(detail.videoDuration) }}</div>
+          </Form-item>
+          <Form-item class="video-warp" :label-width="0">
+            <video :src="detail.videoUrl" autoplay controls style="width: 768px;height: 432px"/>
+          </Form-item>
+          <Form-item label="瀹℃牳缁撴灉锛�" :label-width="100" prop="result">
+            <RadioGroup v-model="auditingForm.result">
+              <Radio :label="1">閫氳繃</Radio>
+              <Radio :label="0">涓嶉�氳繃</Radio>
+            </RadioGroup>
+          </Form-item>
+          <Form-item v-show="auditingForm.result === 0" label="涓嶉�氳繃鍘熷洜锛�" :label-width="100" prop="reason">
+            <Input
+              type="textarea"
+              v-model="auditingForm.reason"
+              clearable
+              style="width: 100%"
+            />
+          </Form-item>
+        </Form>
+        <div slot="footer">
+          <Button type="text" @click="closeAuditing">鍏抽棴</Button>
+          <Button type="primary" @click="submitAuditing">纭</Button>
+        </div>
+      </Modal>
+
+      <Modal
+        v-model="videoDownShow"
+        title="瑙嗛涓嬫灦"
+        width="800"
+        :mask-closable="false"
+      >
+        <Form :model="videoDownForm" :rules="videoDownRule" ref="videoDownForm">
+          <FormItem label="涓嬫灦鍘熷洜锛�" :labelWidth="100" prop="reason">
+            <editor ref="editor" @input="getReason"/>
+          </FormItem>
+        </Form>
+        <div slot="footer">
+          <Button type="text" @click="closeVideoDown">鍏抽棴</Button>
+          <Button type="primary" @click="videoDown">纭</Button>
+        </div>
+      </Modal>
+
+      <Table
+        :loading="loading"
+        border
+        :columns="columns"
+        :data="data"
+        ref="table"
+        sortable="custom"
+        @on-sort-change="changeSort"
+        @on-selection-change="showSelect"
+      >
+        <template slot-scope="{ row, index }" slot="tagList">
+          <div v-for="(tag, index) in row.tagList" :key="'tag' + index" style="margin-top: 5px">
+            <Tag color="red">{{ tag.tagName }}</Tag>
+          </div>
+        </template>
+        <template slot-scope="{ row, index }" slot="videoFileKey">
+          <div class="play-text" @click="playVideo(row.videoFileKey, row.title)">鐐瑰嚮鎾斁</div>
+        </template>
+        <template slot-scope="{ row, index }" slot="videoDuration">
+          <div>{{ formatSeconds(row.videoDuration) }}</div>
+        </template>
+        <template slot-scope="{ row, index }" slot="recommend">
+          <i-switch v-model="row.recommend" :before-change="() => handleBeforeChange(row)" true-color="#13ce66"/>
+        </template>
+        <template slot-scope="{ row, index }" slot="status">
+          {{ transStatus(row.status) }}
+        </template>
+        <template slot-scope="{ row, index }" slot="action">
+          <Button type="primary" size="small" style="margin-right: 5px" v-if="row.status === '99'"
+                  @click="openAuditing(row)">瀹℃牳
+          </Button>
+          <Button type="error" size="small" style="margin-right: 5px" v-if="row.status === '1'"
+                  @click="openVideoDown(row)">涓嬫灦
+          </Button>
+          <Button type="success" size="small" style="margin-right: 5px" v-else-if="row.status === '0'"
+                  @click="videoUp(row)">涓婃灦
+          </Button>
+          <Button type="success" size="small" style="margin-right: 5px"
+                  @click="handleVideoUpLoad(row)">缂栬緫
+          </Button>
+          <Button type="success" size="small" style="margin-right: 5px"
+                  @click="deleteHealthVideo(row)">鍒犻櫎
+          </Button>
+        </template>
+      </Table>
+
+      <Row type="flex" justify="end" class="mt_10">
+        <Page
+          :current="searchForm.pageNumber"
+          :total="total"
+          :page-size="searchForm.pageSize"
+          @on-change="changePage"
+          @on-page-size-change="changePageSize"
+          :page-size-opts="[10, 20, 50]"
+          size="small"
+          show-total
+          show-elevator
+          show-sizer
+        ></Page>
+      </Row>
+    </Card>
+  </div>
+</template>
+
+<script>
+import {recommendSet, getVideoById, auditingVideo, up, down} from "@/api/video";
+import {healthVideo, getHealthVideos, updateHealthVideo,delHealth} from "@/api/health-video";
+import {getVideoTagList} from "@/api/videoTag";
+import {getFilePreview, getSts} from "@/api/file";
+import Editor from '@/components/editor/index.vue'
+import COS from 'cos-js-sdk-v5';
+import {getFileKey} from "@/utils/file.js";
+
+export default {
+  name: "VideoList",
+  components: {Editor},
+  data() {
+    return {
+      videoDownForm: {
+        id: '',
+        reason: ''
+      },
+      videoDownRule: {
+        reason: [
+          {
+            require: true,
+            message: '璇疯緭鍏ヤ笅鏋跺師鍥�',
+            trigger: 'blur',
+            validator: (rule, value, callback) => {
+              if (value === null || value === '') {
+                callback(new Error('璇疯緭鍏ヤ笅鏋跺師鍥�'));
+              } else {
+                callback();
+              }
+            }
+          }
+        ]
+      },
+      videoDownShow: false, // 瑙嗛涓嬫灦
+      videoDownMsg: '', // 涓嬫灦鎻愮ず淇℃伅
+      auditingForm: { // 瀹℃牳琛ㄥ崟
+        id: null,
+        result: null,
+        reason: ''
+      },
+      auditingRule: {
+        result: [
+          {
+            required: true,
+            message: '璇烽�夋嫨瑙嗛瀹℃牳缁撴灉',
+            trigger: 'change',
+            validator: (rule, value, callback) => {
+              if (value === null || value === undefined) {
+                callback(new Error('璇烽�夋嫨瑙嗛瀹℃牳缁撴灉'));
+              } else {
+                callback();
+              }
+            }
+          }
+        ],
+      },
+      uploadVideoFileRule: {
+        coverUrl: [
+          {
+            required: true,
+            message: '璇蜂笂浼犲皝闈�',
+            trigger: 'blur',
+            validator: (rule, value, callback) => {
+              if (value === null || value === undefined) {
+                callback(new Error('璇蜂笂浼犲皝闈�'));
+              } else {
+                callback();
+              }
+            }
+          }
+        ],
+        title: [
+          {
+            required: true,
+            message: '璇疯緭鍏ユ爣棰�',
+            trigger: 'blur',
+            validator: (rule, value, callback) => {
+              console.log('楠岃瘉鍊�:-------------->', value, '绫诲瀷:', typeof value);
+              if (value === null || value === undefined) {
+                callback(new Error('璇疯緭鍏ユ爣棰�'));
+              } else {
+                callback();
+              }
+            }
+          }
+        ],
+      },
+      detail: {}, // 瑙嗛璇︽儏淇℃伅
+      auditingShow: false, // 瀹℃牳寮圭獥
+      upLoadVideoShow: false,//鏂囦欢涓婁紶寮圭獥
+      auditingLoading: false, // 瀹℃牳寮圭獥
+      upLoadVideoLoading: false,//涓婁紶瑙嗛
+      playVideoShow: false, // 瑙嗛鎾斁寮圭獥
+      playVideoTitle: '', // 瑙嗛鎾斁鏍囬
+      playVideoUrl: '', // 褰撳墠姝e湪鎾斁鐨勮棰戝湴鍧�
+      modelShow: false, // 寮圭獥鏄鹃殣
+      modelTitle: '', // 寮圭獥title
+      loading: false, // 琛ㄥ崟鍔犺浇鐘舵��
+      searchForm: {
+        // 鎼滅储妗嗗垵濮嬪寲瀵硅薄
+        pageNumber: 1, // 褰撳墠椤垫暟
+        pageSize: 10, // 椤甸潰澶у皬
+        title: '', // 鏍囬
+        tagList: [], // 鏍囩
+        status: '99'
+      },
+      tagList: [], // 鏍囩鍒楄〃
+      columns: [
+        {
+          type: 'selection',
+          width: 60,
+          align: 'center'
+        },
+        {
+          title: "鏍囬",
+          key: "title",
+          minWidth: 240,
+          tooltip: true,
+        },
+        // {
+        //   title: "浣滆��",
+        //   key: "authorName",
+        //   width: 130,
+        //   tooltip: true,
+        // },
+        // {
+        //   title: "瑙嗛鏍囩",
+        //   key: "tagList",
+        //   width: 180,
+        //   slot: "tagList",
+        // },
+        {
+          title: "瑙嗛鍐呭",
+          key: "videoFileKey",
+          width: 170,
+          slot: "videoFileKey"
+        },
+        {
+          title: "鏃堕暱",
+          key: "videoDuration",
+          width: 80,
+          align: 'center',
+          slot: "videoDuration",
+        },
+        {
+          title: "鎾斁閲�",
+          key: "playNum",
+          width: 80,
+          align: 'center'
+        },
+        {
+          title: "鏀惰棌鏁�",
+          key: "collectNum",
+          width: 80,
+          align: 'center'
+        },
+        {
+          title: "璇勮鏁�",
+          key: "commentNum",
+          width: 80,
+          align: 'center'
+        },
+        {
+          title: "棣栭〉鎺ㄨ崘",
+          key: "recommend",
+          slot: "recommend",
+          width: 100,
+          align: 'center'
+        },
+        {
+          title: "鏉冮噸",
+          key: "weight",
+          width: 170,
+        },
+        {
+          title: "鐘舵��",
+          key: "status",
+          slot: "status",
+          width: 120,
+          align: 'center'
+        },
+        {
+          title: "鎿嶄綔",
+          key: "action",
+          slot: "action",
+          align: "center",
+          width: 200,
+        },
+      ],
+      data: [], // 琛ㄥ崟鏁版嵁
+      total: 0, // 琛ㄥ崟鏁版嵁鎬绘暟
+      selectCount: 0, // 宸查�夋暟閲�
+      selectList: [], // 宸查�夋暟鎹垪琛�
+      uploadVideoForm: {
+        id: null,
+        coverUrl: null,
+        videoFileKey: null,
+        videoFit: null,
+        videoDuration: null,
+        title: null,
+        videoContentType: null,
+        videoType: null,
+        showCoverUrl: null,
+        showVideoUrl: null,
+        temp: null
+
+      },
+    }
+  },
+  created() {
+    this.getDataList();
+    this.getTags('')
+  },
+  methods: {
+    // 绉掕浆x鍒唜绉�
+    formatSeconds(seconds) {
+      if (isNaN(seconds) || seconds < 0) return '0绉�';
+
+      const mins = Math.floor(seconds / 60);
+      const secs = seconds % 60;
+
+      if (mins === 0) return `${secs}绉抈;
+      if (secs === 0) return `${mins}鍒哷;
+
+      return `${mins}鍒�${secs}绉抈;
+    },
+    // 鑾峰彇鏍囩鍒楄〃
+    getTags(tagName) {
+      let params = {
+        'tagName': tagName
+      }
+      getVideoTagList(params).then(res => {
+        this.tagList = res.data
+      })
+    },
+    // 鑾峰彇瀵屾枃鏈紪杈戝櫒鐨勫唴瀹�
+    getReason(content) {
+      this.videoDownForm.reason = content
+    },
+    //閲嶆柊涓婁紶灏侀潰
+    clearCoverImage() {
+      this.$set(this.uploadVideoForm, 'coverUrl', '');
+      this.$set(this.uploadVideoForm, 'showCoverUrl', '');
+      this.$set(this.uploadVideoForm, 'temp', new Date().getTime());
+    },
+    //閲嶆柊涓婁紶瑙嗛
+    clearVideo() {
+      this.clearCoverImage();
+      this.$set(this.uploadVideoForm, 'videoFileKey', '');
+      this.$set(this.uploadVideoForm, 'showVideoUrl', '');
+      this.$set(this.uploadVideoForm, 'temp', new Date().getTime());
+      console.log(this.uploadVideoForm)
+    },
+    // 瑙嗛涓婃灦
+    videoUp(row) {
+      this.$Modal.confirm({
+        title: "鎿嶄綔纭",
+        content: "鎮ㄧ‘璁よ涓婃灦瑙嗛銆� " + row.title + "銆戝悧?",
+        loading: true,
+        onOk: () => {
+          up(row.id).then(res => {
+            this.$Modal.remove();
+            if (res.code == 200) {
+              this.$Message.success("瑙嗛涓婃灦鎴愬姛");
+              this.getDataList();
+            }
+          });
+        }
+      });
+    },
+    // 瑙嗛涓嬫灦
+    videoDown() {
+      this.$refs.videoDownForm.validate((valid) => {
+        if (valid) {
+          down(this.videoDownForm).then(res => {
+            this.$Message.success("涓嬫灦鎴愬姛")
+            this.closeVideoDown()
+            this.getDataList()
+          })
+        }
+      })
+    },
+    // 鍏抽棴瑙嗛涓嬫灦
+    closeVideoDown() {
+      this.videoDownShow = false
+      this.videoDownForm = {
+        id: '',
+        reason: ''
+      }
+      this.$refs.editor.setContent('')
+    },
+    // 瑙嗛涓嬫灦
+    openVideoDown(row) {
+      this.videoDownForm.id = row.id
+      this.videoDownShow = true
+    },
+    // 瑙嗛鍙戝竷/淇敼
+    submitHealthVideo() {
+      try {
+        this.upLoadVideoLoading = true
+        this.$refs.uploadVideoForm.validate((valid) => {
+          if (valid) {
+            // 淇敼
+            if (this.uploadVideoForm.id) {
+              updateHealthVideo(this.uploadVideoForm).then(res => {
+                this.$Message.success("淇敼瀹屾垚")
+                this.closeHealthVideo()
+                this.getDataList()
+              })
+            } else {
+              healthVideo(this.uploadVideoForm).then(res => {
+                this.$Message.success("娣诲姞瀹屾垚")
+                this.closeHealthVideo()
+                this.getDataList()
+              })
+            }
+          }
+        })
+      } finally {
+        this.upLoadVideoLoading = false
+      }
+    },
+    // 鍏抽棴绐楀彛
+    closeHealthVideo() {
+      //
+      this.uploadVideoForm = {};
+      this.upLoadVideoShow = false;
+    },
+    // 鎻愪氦瀹℃牳缁撴灉
+    submitAuditing() {
+      console.log(this.auditingForm, "sb")
+      this.$refs.auditingForm.validate((valid) => {
+        if (valid) {
+          auditingVideo(this.auditingForm).then(res => {
+            this.$Message.success("瀹℃牳瀹屾垚")
+            this.closeAuditing()
+            this.getDataList()
+          })
+        }
+      })
+    },
+    // 瀹℃牳缁撴灉鍙樺寲
+    resultChange(selected) {
+      this.auditingForm.result = selected === '閫氳繃' ? 1 : 0
+      console.log(this.auditingForm.result)
+    },
+    closeAuditing() {
+      this.auditingForm = {
+        id: null,
+        result: null,
+        reason: ''
+      }
+      this.detail = {}
+      this.auditingShow = false
+    },
+    // 鎵撳紑瀹℃牳寮圭獥
+    openAuditing(row) {
+      this.auditingShow = true
+      this.auditingLoading = true
+      this.auditingForm.id = row.id
+      getVideoById(row.id).then(res => {
+        this.detail = res.data
+        this.auditingLoading = false
+      })
+    },
+    getVideoDuration(e){
+      const duration = this.$refs.healthVideoInfo.duration;
+      this.uploadVideoForm.videoDuration = Math.floor(duration);
+    },
+    // 鎵撳紑缂栬緫寮圭獥
+    deleteHealthVideo(row) {
+      console.log('鍒犻櫎娴嬭瘯', row)
+      this.$Modal.confirm({
+        title: "鎿嶄綔纭",
+        content: "鎮ㄧ‘璁よ鍒犻櫎瑙嗛銆� " + row.title + "銆戝悧?",
+        loading: true,
+        onOk: () => {
+          delHealth(row.id).then(res => {
+            this.$Modal.remove();
+            if (res.code === 200) {
+              this.$Message.success("瑙嗛鍒犻櫎鎴愬姛");
+              this.getDataList();
+            }
+          });
+        }
+      });
+    },
+    // 缈昏瘧鐘舵��
+    transStatus(status) {
+      switch (status) {
+        case '99':
+          return '寰呭鏍�'
+        case '1':
+          return '宸插彂甯�'
+        case '0':
+          return '宸蹭笅鏋�'
+        case '-1':
+          return '瀹℃牳鏈�氳繃'
+        default:
+          return '鏈煡'
+      }
+    },
+    // 寮�鍚垨鍏抽棴鎺ㄨ崘鐨勬柟娉�
+    handleBeforeChange(row) {
+      let content = ""
+      if (row.recommend) {
+        content = '纭瑕佸叧闂椤垫帹鑽愬悧锛�'
+      } else {
+        content = '纭瑕佸紑鍚椤垫帹鑽愬悧锛�'
+      }
+      return new Promise((resolve) => {
+        this.$Modal.confirm({
+          title: '鎿嶄綔鎻愰啋',
+          content: content,
+          onOk: () => {
+            recommendSet({id: row.id, recommend: !row.recommend}).then(res => {
+              this.$Message.success(res.msg);
+              resolve();
+            })
+          }
+        });
+      });
+    },
+    // 鍏抽棴瑙嗛鎾斁
+    playVideoClose() {
+      this.playVideoTitle = '';
+      this.playVideoUrl = '';
+      this.playVideoShow = false
+    },
+    // 鐐瑰嚮鎾斁瑙嗛
+    playVideo(fileKey, title) {
+      this.playVideoTitle = title;
+
+      getFilePreview(fileKey).then(res => {
+        this.playVideoUrl = res.data
+        this.playVideoShow = true
+      })
+    },
+    // 鎼滅储
+    handleSearch() {
+      this.searchForm.pageNumber = 1;
+      this.searchForm.pageSize = 10;
+      this.getDataList();
+    },
+    // 鑾峰彇鍒楄〃鏁版嵁
+    getDataList() {
+      this.loading = true;
+      getHealthVideos(this.searchForm).then((res) => {
+        console.log(res)
+        this.loading = false;
+        if (res.code === 200) {
+          this.data = res.data;
+          this.total = res.total;
+        }
+      });
+      this.total = this.data.length;
+      this.loading = false;
+    },
+    showSelect(e) {
+      this.selectList = e.map(d => d.id);
+      this.selectCount = e.length;
+    },
+    // 鎺掑簭
+    changeSort(e) {
+      this.searchForm.sort = e.key;
+      this.searchForm.order = e.order;
+      if (e.order == "normal") {
+        this.searchForm.order = "";
+      }
+      this.getDataList();
+    },
+    // 鍒嗛〉 鏀瑰彉椤电爜
+    changePage(v) {
+      this.searchForm.pageNumber = v;
+      this.getDataList();
+    },
+    // 鍒嗛〉 鏀瑰彉椤垫暟
+    changePageSize(v) {
+      this.searchForm.pageNumber = 1;
+      this.searchForm.pageSize = v;
+      this.getDataList();
+    },
+    handleVideoUpLoad(row) {
+      this.uploadVideoForm = {};
+      this.upLoadVideoShow = true;
+      if (row.id) {
+        this.uploadVideoForm.id = row.id;
+        this.uploadVideoForm.showVideoUrl = row.videoUrl
+        this.uploadVideoForm.videoFileKey = row.videoFileKey;
+        this.uploadVideoForm.coverUrl = row.coverUrl;
+        this.uploadVideoForm.showCoverUrl = row.coverShowUrl;
+        this.uploadVideoForm.title = row.title;
+      }
+    },
+    async upLoadVideo(file) {
+      try {
+        this.$nextTick(() => {
+          this.upLoadVideoLoading = true;
+        })
+        // 鑾峰彇鏂囦欢涓婁紶涓存椂瀵嗛挜
+        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, // 瑕佷笂浼犵殑鏂囦欢瀵硅薄銆�
+          SliceSize: 1024 * 1024 * 5,
+          onProgress: function (progressData) {
+            console.log('涓婁紶杩涘害锛�', progressData);
+          },
+        });
+
+        console.log(this.uploadVideoForm)
+        this.$nextTick(() => {
+          this.uploadVideoForm.videoFileKey = fileKey;
+          this.uploadVideoForm.showVideoUrl = sts.data.endpoint + "/" + fileKey;
+        })
+        console.log("涓婁紶鎴愬姛", upData)
+        const duration = this.$refs.healthVideoInfo.duration;
+        console.log('-娴嬭瘯鑾峰彇鏃堕棿淇℃伅---------------->', duration);
+      } catch (e) {
+        console.log("涓婁紶澶辫触", upData)
+      } finally {
+        this.$nextTick(() => {
+          this.upLoadVideoLoading = false;
+        })
+      }
+      return false;
+    },
+    async upLoadImg(file) {
+      try {
+        this.upLoadVideoLoading = true;
+        // 鑾峰彇鏂囦欢涓婁紶涓存椂瀵嗛挜
+        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, // 瑕佷笂浼犵殑鏂囦欢瀵硅薄銆�
+          SliceSize: 1024 * 1024 * 5,
+          onProgress: function (progressData) {
+            console.log('涓婁紶杩涘害锛�', progressData);
+          },
+        });
+        console.log("涓婁紶鎴愬姛", upData)
+        this.$nextTick(() => {
+          this.uploadVideoForm.coverUrl = fileKey;
+          this.uploadVideoForm.showCoverUrl = sts.data.endpoint + "/" + fileKey;
+        })
+
+      } catch (e) {
+        console.log("涓婁紶澶辫触", upData)
+      } finally {
+        this.upLoadVideoLoading = false;
+      }
+      return false;
+    }
+  }
+}
+</script>
+
+<style scoped>
+.play-text {
+  width: 100%;
+  text-align: center;
+  color: #2d8cf0;
+}
+
+.play-text:hover {
+  cursor: pointer;
+}
+
+.video-warp {
+  width: 786px;
+  height: 432px;
+}
+
+.data-item {
+  display: flex;
+  align-items: center;
+}
+
+.showCoverImg {
+  position: relative;
+}
+
+.coverImgRemove {
+  position: absolute;
+  top: 15px;
+  right: -15px;
+}
+</style>
diff --git a/manager/src/views/kitchen/kitchenType.vue b/manager/src/views/kitchen/kitchenType.vue
new file mode 100644
index 0000000..7123251
--- /dev/null
+++ b/manager/src/views/kitchen/kitchenType.vue
@@ -0,0 +1,370 @@
+<template>
+  <div>
+    <Card>
+      <Form
+        ref="searchForm"
+        @keydown.enter.native="handleSearch"
+        :model="searchForm"
+        inline
+        :label-width="70"
+        class="search-form"
+      >
+        <Form-item label="鏍囩鍚嶇О" prop="typeName">
+          <Input
+            type="text"
+            v-model="searchForm.typeName"
+            clearable
+            @on-clear="handleSearch"
+            @on-change="handleSearch"
+            style="width: 160px"
+          />
+        </Form-item>
+        <Button
+          @click="handleSearch"
+          type="primary"
+          icon="ios-search"
+          class="search-btn"
+        >鎼滅储</Button
+        >
+      </Form>
+
+      <Row class="operation padding-row">
+        <Button @click="openAdd" type="info">娣诲姞</Button>
+        <Button @click="delBatch" type="error">鎵归噺鍒犻櫎</Button>
+      </Row>
+
+      <Modal
+        v-model="modelShow"
+        :title="modelTitle"
+        >
+        <Form ref="form" :model="form" :label-width="70" :rules="rules">
+          <Row :gutter="24">
+            <Col span="12">
+              <FormItem label="鏍囩鍚嶇О" prop="typeName">
+                <Input v-model="form.typeName" autocomplete="off"/>
+              </FormItem>
+            </Col>
+            <Col span="12">
+              <FormItem label="鎺掑簭" prop="sortNum">
+                <Input v-model="form.sortNum" autocomplete="off"/>
+              </FormItem>
+            </Col>
+          </Row>
+        </Form>
+        <div slot="footer">
+          <Button type="text" @click="modelClose">鍙栨秷</Button>
+          <Button type="primary" :loading="submitLoading" @click="saveOrUpdate">鎻愪氦</Button>
+        </div>
+      </Modal>
+
+      <Table
+        :loading="loading"
+        border
+        :columns="columns"
+        :data="data"
+        ref="table"
+        sortable="custom"
+        @on-sort-change="changeSort"
+        @on-selection-change="showSelect"
+      >
+        <template slot-scope="{ row, index }" slot="action">
+          <Button type="info" size="small" style="margin-right: 5px" @click="openEdit(row)">缂栬緫</Button>
+          <Button type="error" size="small" @click="delById(row)">鍒犻櫎</Button>
+        </template>
+      </Table>
+
+      <Row type="flex" justify="end" class="mt_10">
+        <Page
+          :current="searchForm.pageNumber"
+          :total="total"
+          :page-size="searchForm.pageSize"
+          @on-change="changePage"
+          @on-page-size-change="changePageSize"
+          :page-size-opts="[10, 20, 50]"
+          size="small"
+          show-total
+          show-elevator
+          show-sizer
+        ></Page>
+      </Row>
+    </Card>
+  </div>
+</template>
+
+<script>
+import JsonExcel from "vue-json-excel";
+import {deleteVideoTagById, getVideoTags, editVideoTag, addVideoTag, deleteVideoTagByIds} from "@/api/videoTag";
+import {addKitchenType, deleteBatch, delKitchenType, editKitchenType, getKitchenType} from "@/api/kitchen";
+export default {
+  name: "VideoTagList",
+  components: {
+    "download-excel": JsonExcel,
+  },
+  data() {
+    return {
+      // 淇濆瓨鍔犺浇
+      submitLoading: false,
+      // 鏂板淇敼琛ㄥ崟
+      form: {
+        id: '',
+        typeName: '',
+        sortNum: '',
+      },
+      rules: {
+        typeName: [
+          {required: true, message: "鏍囩鍚嶇О涓嶈兘涓虹┖", trigger: "blur",
+            validator: (rule, value, callback) => {
+              if (value === null || value === '') {
+                callback(new Error('鏍囩鍚嶇О涓嶈兘涓虹┖'));
+              } else {
+                callback();
+              }
+            }
+          }
+        ],
+        sortNum : [
+          {required: true, message: "搴忓彿涓嶈兘涓虹┖", trigger: "blur",
+            validator: (rule, value, callback) => {
+              if (value === null || value === '') {
+                callback(new Error('搴忓彿涓嶈兘涓虹┖'));
+              } else {
+                callback();
+              }
+            }}
+        ],
+      },
+      modelShow: false, // 寮圭獥鏄鹃殣
+      modelTitle: '', // 寮圭獥title
+      // 琛ㄦ牸鐨勮〃澶翠互鍙婂唴瀹�
+      fields: {
+        绫诲瀷: "tagName",
+        寮曠敤娆℃暟: "useNum",
+        鎺掑簭: "sort_num",
+        鎿嶄綔: "action"
+      },
+      loading: true, // 琛ㄥ崟鍔犺浇鐘舵��
+      searchForm: {
+        // 鎼滅储妗嗗垵濮嬪寲瀵硅薄
+        pageNumber: 1, // 褰撳墠椤垫暟
+        pageSize: 10, // 椤甸潰澶у皬
+        typeName: '', // 鏍囩鍚嶇О
+      },
+      selectDate: null,
+      columns: [
+        {
+          type: 'selection',
+          width: 60,
+          align: 'center'
+        },
+        {
+          title: "鏍囩",
+          key: "typeName",
+          minWidth: 170,
+          tooltip: true,
+        },
+        // {
+        //   title: "寮曠敤娆℃暟",
+        //   key: "useNum",
+        //   width: 170,
+        //   sortable: true
+        // },
+        {
+          title: "鎺掑簭",
+          key: "sortNum",
+          width: 400,
+        },
+        {
+          title: "鎿嶄綔",
+          key: "action",
+          slot: "action",
+          align: "center",
+          width: 400,
+        },
+      ],
+      data: [], // 琛ㄥ崟鏁版嵁
+      total: 0, // 琛ㄥ崟鏁版嵁鎬绘暟
+      selectCount: 0, // 宸查�夋暟閲�
+      selectList: [], // 宸查�夋暟鎹垪琛�
+    };
+  },
+  methods: {
+    showSelect(e) {
+      this.selectList = e.map(d => d.id);
+      this.selectCount = e.length;
+    },
+    // 鎺掑簭
+    changeSort(e) {
+      this.searchForm.sort = e.key;
+      this.searchForm.order = e.order;
+      if (e.order == "normal") {
+        this.searchForm.order = "";
+      }
+      this.getDataList();
+    },
+    // 鎵归噺鍒犻櫎
+    delBatch() {
+      if (this.selectCount <= 0) {
+        this.$Message.warning("鎮ㄨ繕鏈�夋嫨瑕佸垹闄ょ殑鏁版嵁");
+        return;
+      }
+      this.$Modal.confirm({
+        title: "纭鍒犻櫎",
+        content: "鎮ㄧ‘璁よ鍒犻櫎鎵�閫夌殑 " + this.selectCount + " 鏉℃暟鎹�?",
+        loading: true,
+        onOk: () => {
+          deleteBatch(this.selectList).then(res => {
+            this.$Modal.remove();
+            if (res.code == 200) {
+              this.$Message.success("鍒犻櫎鎴愬姛");
+              this.selectList = [];
+              this.selectCount = 0;
+              this.getDataList();
+            }
+          });
+        }
+      });
+    },
+    // id鍒犻櫎
+    delById(row) {
+      this.$Modal.confirm({
+        title: "纭鍒犻櫎",
+        content: "鎮ㄧ‘璁よ鍒犻櫎鏍囩锛� " + row.typeName + " ?",
+        loading: true,
+        onOk: () => {
+          delKitchenType(row.id).then(res => {
+            this.$Modal.remove();
+            if (res.code == 200) {
+              this.$Message.success("鍒犻櫎鎴愬姛");
+              this.getDataList();
+            }
+          });
+        }
+      });
+    },
+    // 鎵撳紑鏂板
+    openAdd() {
+      this.modelTitle = "鏂板鏍囩"
+      this.modelShow = true
+      this.form ={}
+    },
+    // 鎵撳紑淇敼
+    openEdit(row) {
+      this.modelTitle = "淇敼鏍囩"
+      this.form = {};
+      this.form.id = row.id
+      this.form.typeName = row.typeName
+      this.form.sortNum = row.sortNum
+      this.modelShow = true
+      console.log(this.form)
+    },
+    // 鏂板鎴栦慨鏀�
+    saveOrUpdate() {
+      this.$refs.form.validate(valid => {
+        try {
+          if (valid) {
+            this.submitLoading = true
+            if (this.form.id) {
+              // 淇敼
+              editKitchenType(this.form).then(res => {
+                if (res.code == 200) {
+                  this.$Message.success("淇敼鎴愬姛");
+                  this.modelClose()
+                  this.getDataList()
+                }
+              })
+            } else {
+              // 鏂板
+              addKitchenType(this.form).then(res => {
+                if (res.code == 200) {
+                  this.$Message.success("娣诲姞鎴愬姛");
+                  this.modelClose()
+                  this.getDataList()
+                }
+              })
+            }
+          }
+        }finally {
+          this.submitLoading = false
+        }
+      });
+    },
+    // 鍏抽棴寮圭獥
+    modelClose() {
+      this.submitLoading = false
+      this.modelShow = false
+    },
+    // 鍒濆鍖栨暟鎹�
+    init() {
+      this.getDataList();
+    },
+    // 鍒嗛〉 鏀瑰彉椤电爜
+    changePage(v) {
+      this.searchForm.pageNumber = v;
+      this.getDataList();
+    },
+    // 鍒嗛〉 鏀瑰彉椤垫暟
+    changePageSize(v) {
+      this.searchForm.pageNumber = 1;
+      this.searchForm.pageSize = v;
+      this.getDataList();
+    },
+    // 鎼滅储
+    handleSearch() {
+      this.searchForm.pageNumber = 1;
+      this.searchForm.pageSize = 10;
+      this.getDataList();
+    },
+    // 璧锋鏃堕棿浠庢柊璧嬪��
+    selectDateRange(v) {
+      if (v) {
+        this.searchForm.startDate = v[0];
+        this.searchForm.endDate = v[1];
+      }
+    },
+    // 鑾峰彇鍒楄〃鏁版嵁
+    getDataList() {
+      this.loading = true;
+      getKitchenType(this.searchForm).then((res) => {
+        console.log(res)
+        this.loading = false;
+        if (res.code == 200) {
+          this.data = res.data;
+          this.total = res.total;
+        }
+      });
+      this.total = this.data.length;
+      this.loading = false;
+    },
+  },
+  mounted() {
+    this.init();
+  },
+};
+</script>
+<style lang="scss" scoped>
+.export {
+  margin: 10px 20px 10px 0;
+}
+.export-excel-wrapper {
+  display: inline;
+}
+.order-tab {
+  width: 950px;
+  height: 36px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  background-color: #f0f0f0;
+  padding: 0 10px;
+  margin-bottom: 10px;
+  div {
+    text-align: center;
+    padding: 4px 12px;
+    border-radius: 4px;
+    cursor: pointer;
+  }
+  .current {
+    background-color: #ffffff;
+  }
+}
+</style>
diff --git a/manager/src/views/kitchen/kitchenVideo.vue b/manager/src/views/kitchen/kitchenVideo.vue
new file mode 100644
index 0000000..40e7079
--- /dev/null
+++ b/manager/src/views/kitchen/kitchenVideo.vue
@@ -0,0 +1,975 @@
+<template>
+  <div>
+    <Card>
+      <Form
+        ref="searchForm"
+        @keydown.enter.native="handleSearch"
+        :model="searchForm"
+        inline
+        :label-width="70"
+        class="search-form"
+      >
+        <Form-item label="鏍囬" prop="title">
+          <Input
+            type="text"
+            v-model="searchForm.title"
+            clearable
+            @on-clear="handleSearch"
+            @on-change="handleSearch"
+            style="width: 160px"
+          />
+        </Form-item>
+        <Form-item label="鍒嗙被" prop="typeList">
+          <Select
+            v-model="searchForm.typeList"
+            clearable
+            filterable
+            multiple
+            @on-clear="handleSearch"
+            @on-change="handleSearch"
+            style="width: 160px"
+          >
+            <Option v-for="type in typeList" :key="type.id" :value="type.id">{{ type.typeName }}</Option>
+          </Select>
+        </Form-item>
+        <Form-item label="瑙嗛鐘舵��" prop="status">
+          <Select
+            v-model="searchForm.status"
+            clearable
+            @on-clear="handleSearch"
+            @on-change="handleSearch"
+            style="width: 160px"
+          >
+            <Option value="99">寰呭鏍�</Option>
+            <Option value="1">宸插彂甯�</Option>
+            <Option value="0">宸蹭笅鏋�</Option>
+            <Option value="-1">瀹℃牳鏈�氳繃</Option>
+          </Select>
+        </Form-item>
+        <Button
+          @click="handleSearch"
+          type="primary"
+          icon="ios-search"
+          class="search-btn"
+        >鎼滅储
+        </Button
+        >
+        <Button
+          @click="handleVideoUpLoad"
+          type="primary"
+          icon="md-arrow-up"
+          class="search-btn"
+        >涓婁紶瑙嗛
+        </Button
+        >
+      </Form>
+      <!--      鍘ㄧ瑙嗛涓婁紶-->
+      <Modal
+        v-model="upLoadVideoShow"
+        :title="uploadVideoForm.id?'缂栬緫鍘ㄧ瑙嗛':'涓婁紶鍘ㄧ瑙嗛'"
+        width="800"
+        :mask-closable="false"
+      >
+
+        <Form
+          :model="uploadVideoForm"
+          ref="uploadVideoForm"
+          :rules="uploadVideoFileRule"
+        >
+          <Row :gutter="24">
+            <Col span="24">
+              <Spin size="large" fix v-if="upLoadVideoLoading"> 鏂囦欢涓婁紶涓�...</Spin>
+            </Col>
+            <Col span="12">
+              <FormItem label="鏍囬" prop="title">
+                <Input placeholder="璇疯緭鍏ユ爣棰�" v-model="uploadVideoForm.title"
+                       style="width: 200px"
+                />
+              </FormItem>
+            </Col>
+<!--            鍒锋柊dom浣跨敤-->
+            <Col span="24">
+              <FormItem label="鍒锋柊dom浣跨敤" prop="title" v-show="false">
+                <Input placeholder="璇疯緭鍏ユ爣棰�" v-model="uploadVideoForm.temp"
+                       style="width: 200px"
+                />
+              </FormItem>
+            </Col>
+            <Col span="12" v-if="!uploadVideoForm.videoFileKey">
+              <FormItem label="涓婁紶瑙嗛" prop="videoFileKey">
+                <Upload
+                  :multiple="true"
+                  :before-upload="upLoadVideo"
+                  accept="video/*"
+                  action=""
+                >
+                  <Button icon="ios-cloud-upload-outline">閫夋嫨瑙嗛</Button>
+                </Upload>
+              </FormItem>
+            </Col>
+
+            <Col span="24" v-else>
+              <FormItem label="瑙嗛">
+                <video style="width: 150px;height: 150px"
+                       controls
+                       @loadedmetadata="getVideoDuration"
+                       :poster="uploadVideoForm.showCoverUrl"
+                       :autoplay="false"
+                       id="remoteVideo" :src="uploadVideoForm.showVideoUrl"
+                       ref="healthVideoInfo"
+                ></video>
+              </FormItem>
+            </Col>
+
+            <Col span="12" v-show="uploadVideoForm.videoFileKey && !uploadVideoForm.coverUrl">
+              <FormItem label="涓婁紶灏侀潰" prop="coverUrl">
+                <Upload
+                  :multiple="true"
+                  :before-upload="upLoadImg"
+                  accept="image/*"
+                  action=""
+                >
+                  <Button icon="ios-cloud-upload-outline">閫夋嫨灏侀潰</Button>
+                </Upload>
+              </FormItem>
+            </Col>
+            <Col span="24" style="padding-right:10px">
+              <FormItem  label="鍘ㄧ鏍囩" prop="checkKitchenType">
+                <Select  filterable multiple
+                         style="width: 600px"
+                         v-model="uploadVideoForm.checkKitchenType"
+                         >
+                  <Option v-for="item in kitchenType" :value="item.id" :key="item.id">{{ item.typeName }}</Option>
+                </Select>
+              </FormItem>
+            </Col>
+            <Col span="24">
+              <div>
+                <Button type="primary" @click="clearCoverImage" v-show="uploadVideoForm.coverUrl">閲嶆柊涓婁紶灏侀潰</Button>
+                <Button type="primary" @click="clearVideo" style="margin-left: 20px"
+                        v-show="uploadVideoForm.videoFileKey">閲嶆柊涓婁紶瑙嗛
+                </Button>
+              </div>
+            </Col>
+          </Row>
+
+        </Form>
+        <div slot="footer">
+          <Button type="text" @click="closeHealthVideo">鍏抽棴</Button>
+          <Button type="primary" @click="submitHealthVideo">纭</Button>
+        </div>
+      </Modal>
+      <Modal
+        v-model="playVideoShow"
+        :title="playVideoTitle"
+        width="800"
+        :mask-closable="false"
+      >
+        <div class="video-warp">
+          <video :src="playVideoUrl" autoplay controls style="width: 768px;height: 432px"/>
+        </div>
+        <div slot="footer">
+          <Button type="text" @click="playVideoClose">鍏抽棴</Button>
+        </div>
+      </Modal>
+
+      <Modal
+        v-model="auditingShow"
+        title="瑙嗛瀹℃牳"
+        width="800"
+        :loading="auditingLoading"
+        :mask-closable="false"
+      >
+
+        <Form
+          ref="auditingForm"
+          :model="auditingForm"
+          :label-width="70"
+          :rules="auditingRule"
+        >
+          <Form-item label="鏍囬锛�">
+            <div>{{ detail.title }}</div>
+          </Form-item>
+          <Form-item label="鏍囩锛�">
+            <div style="display: flex;flex-wrap: wrap">
+              <div v-for="(tag, index) in detail.typeList" :key="'tag' + index" style="margin-right: 5px">
+                <Tag color="red">{{ tag.tagName }}</Tag>
+              </div>
+            </div>
+          </Form-item>
+          <Form-item label="瑙嗛鏃堕暱锛�" :label-width="72">
+            <div>{{ formatSeconds(detail.videoDuration) }}</div>
+          </Form-item>
+          <Form-item class="video-warp" :label-width="0">
+            <video :src="detail.videoUrl" autoplay controls style="width: 768px;height: 432px"/>
+          </Form-item>
+          <Form-item label="瀹℃牳缁撴灉锛�" :label-width="100" prop="result">
+            <RadioGroup v-model="auditingForm.result">
+              <Radio :label="1">閫氳繃</Radio>
+              <Radio :label="0">涓嶉�氳繃</Radio>
+            </RadioGroup>
+          </Form-item>
+          <Form-item v-show="auditingForm.result === 0" label="涓嶉�氳繃鍘熷洜锛�" :label-width="100" prop="reason">
+            <Input
+              type="textarea"
+              v-model="auditingForm.reason"
+              clearable
+              style="width: 100%"
+            />
+          </Form-item>
+        </Form>
+        <div slot="footer">
+          <Button type="text" @click="closeAuditing">鍏抽棴</Button>
+          <Button type="primary" @click="submitAuditing">纭</Button>
+        </div>
+      </Modal>
+
+      <Modal
+        v-model="videoDownShow"
+        title="瑙嗛涓嬫灦"
+        width="800"
+        :mask-closable="false"
+      >
+        <Form :model="videoDownForm" :rules="videoDownRule" ref="videoDownForm">
+          <FormItem label="涓嬫灦鍘熷洜锛�" :labelWidth="100" prop="reason">
+            <editor ref="editor" @input="getReason"/>
+          </FormItem>
+        </Form>
+        <div slot="footer">
+          <Button type="text" @click="closeVideoDown">鍏抽棴</Button>
+          <Button type="primary" @click="videoDown">纭</Button>
+        </div>
+      </Modal>
+
+      <Table
+        :loading="loading"
+        border
+        :columns="columns"
+        :data="data"
+        ref="table"
+        sortable="custom"
+        @on-sort-change="changeSort"
+        @on-selection-change="showSelect"
+      >
+        <template slot-scope="{ row, index }" slot="typeList">
+          <div v-for="(tag, index) in row.typeList" :key="'tag' + index" style="margin-top: 5px">
+            <Tag color="red">{{ tag.typeName }}</Tag>
+          </div>
+        </template>
+        <template slot-scope="{ row, index }" slot="videoFileKey">
+          <div class="play-text" @click="playVideo(row.videoFileKey, row.title)">鐐瑰嚮鎾斁</div>
+        </template>
+        <template slot-scope="{ row, index }" slot="videoDuration">
+          <div>{{ formatSeconds(row.videoDuration) }}</div>
+        </template>
+        <template slot-scope="{ row, index }" slot="recommend">
+          <i-switch v-model="row.recommend" :before-change="() => handleBeforeChange(row)" true-color="#13ce66"/>
+        </template>
+        <template slot-scope="{ row, index }" slot="status">
+          {{ transStatus(row.status) }}
+        </template>
+        <template slot-scope="{ row, index }" slot="action">
+          <Button type="primary" size="small" style="margin-right: 5px" v-if="row.status === '99'"
+                  @click="openAuditing(row)">瀹℃牳
+          </Button>
+          <Button type="error" size="small" style="margin-right: 5px" v-if="row.status === '1'"
+                  @click="openVideoDown(row)">涓嬫灦
+          </Button>
+          <Button type="success" size="small" style="margin-right: 5px" v-else-if="row.status === '0'"
+                  @click="videoUp(row)">涓婃灦
+          </Button>
+          <Button type="success" size="small" style="margin-right: 5px"
+                  @click="handleVideoUpLoad(row)">缂栬緫
+          </Button>
+          <Button type="success" size="small" style="margin-right: 5px"
+                  @click="deleteHealthVideo(row)">鍒犻櫎
+          </Button>
+        </template>
+      </Table>
+
+      <Row type="flex" justify="end" class="mt_10">
+        <Page
+          :current="searchForm.pageNumber"
+          :total="total"
+          :page-size="searchForm.pageSize"
+          @on-change="changePage"
+          @on-page-size-change="changePageSize"
+          :page-size-opts="[10, 20, 50]"
+          size="small"
+          show-total
+          show-elevator
+          show-sizer
+        ></Page>
+      </Row>
+    </Card>
+  </div>
+</template>
+
+<script>
+import {recommendSet, getVideoById, auditingVideo, up, down} from "@/api/video";
+import {addKitchenVideo, delKitchen, getKitchenVideos, updateKitchenVideo} from "@/api/kitchen-video";
+import {getFilePreview, getSts} from "@/api/file";
+import Editor from '@/components/editor/index.vue'
+import COS from 'cos-js-sdk-v5';
+import {getFileKey} from "@/utils/file.js";
+import {getKitchenTypeAllList} from "@/api/kitchen";
+
+export default {
+  name: "VideoList",
+  components: {Editor},
+  data() {
+    return {
+      videoDownForm: {
+        id: '',
+        reason: ''
+      },
+      videoDownRule: {
+        reason: [
+          {
+            require: true,
+            message: '璇疯緭鍏ヤ笅鏋跺師鍥�',
+            trigger: 'blur',
+            validator: (rule, value, callback) => {
+              if (value === null || value === '') {
+                callback(new Error('璇疯緭鍏ヤ笅鏋跺師鍥�'));
+              } else {
+                callback();
+              }
+            }
+          }
+        ]
+      },
+      videoDownShow: false, // 瑙嗛涓嬫灦
+      videoDownMsg: '', // 涓嬫灦鎻愮ず淇℃伅
+      auditingForm: { // 瀹℃牳琛ㄥ崟
+        id: null,
+        result: null,
+        reason: ''
+      },
+      auditingRule: {
+        result: [
+          {
+            required: true,
+            message: '璇烽�夋嫨瑙嗛瀹℃牳缁撴灉',
+            trigger: 'change',
+            validator: (rule, value, callback) => {
+              if (value === null || value === undefined) {
+                callback(new Error('璇烽�夋嫨瑙嗛瀹℃牳缁撴灉'));
+              } else {
+                callback();
+              }
+            }
+          }
+        ],
+      },
+      uploadVideoFileRule: {
+        coverUrl: [
+          {
+            required: true,
+            message: '璇蜂笂浼犲皝闈�',
+            trigger: 'blur',
+            validator: (rule, value, callback) => {
+              if (value === null || value === undefined || value === '') {
+                callback(new Error('璇蜂笂浼犲皝闈�'));
+              } else {
+                callback();
+              }
+            }
+          }
+        ],
+        videoFileKey: [
+          {
+            required: true,
+            message: '璇蜂笂浼犲皝闈�',
+            trigger: 'blur',
+            validator: (rule, value, callback) => {
+              if (value === null || value === undefined || value === '') {
+                callback(new Error('璇蜂笂浼犲皝闈�'));
+              } else {
+                callback();
+              }
+            }
+          }
+        ],
+        checkKitchenType: [
+          {
+            required: true,
+            message: '璇烽�夋嫨鍘ㄧ鏍囩',
+            trigger: 'blur',
+            validator: (rule, value, callback) => {
+              console.log('楠岃瘉鍊�:-------------->', value, '绫诲瀷:', typeof value);
+              if (value === null || value === undefined||value.length >5) {
+                callback(new Error('璇烽�夋嫨鍘ㄧ鏍囩涓斾笉鑳借秴杩�5涓�'));
+              } else {
+                callback();
+              }
+            }
+          }
+        ],
+        title: [
+          {
+            required: true,
+            message: '璇疯緭鍏ユ爣棰�',
+            trigger: 'blur',
+            validator: (rule, value, callback) => {
+              if (value === null || value === undefined) {
+                callback(new Error('璇疯緭鍏ユ爣棰�'));
+              } else {
+                callback();
+              }
+            }
+          }
+        ],
+      },
+      detail: {}, // 瑙嗛璇︽儏淇℃伅
+      auditingShow: false, // 瀹℃牳寮圭獥
+      upLoadVideoShow: false,//鏂囦欢涓婁紶寮圭獥
+      auditingLoading: false, // 瀹℃牳寮圭獥
+      upLoadVideoLoading: false,//涓婁紶瑙嗛
+      playVideoShow: false, // 瑙嗛鎾斁寮圭獥
+      playVideoTitle: '', // 瑙嗛鎾斁鏍囬
+      playVideoUrl: '', // 褰撳墠姝e湪鎾斁鐨勮棰戝湴鍧�
+      modelShow: false, // 寮圭獥鏄鹃殣
+      modelTitle: '', // 寮圭獥title
+      loading: false, // 琛ㄥ崟鍔犺浇鐘舵��
+      searchForm: {
+        // 鎼滅储妗嗗垵濮嬪寲瀵硅薄
+        pageNumber: 1, // 褰撳墠椤垫暟
+        pageSize: 10, // 椤甸潰澶у皬
+        title: '', // 鏍囬
+        typeList: [], // 鏍囩
+        status: '99'
+      },
+      typeList: [], // 鏍囩鍒楄〃
+      columns: [
+        {
+          type: 'selection',
+          width: 60,
+          align: 'center'
+        },
+        {
+          title: "鏍囬",
+          key: "title",
+          minWidth: 240,
+          tooltip: true,
+        },
+        {
+          title: "浣滆��",
+          key: "authorName",
+          width: 130,
+          tooltip: true,
+        },
+        {
+          title: "瑙嗛鍒嗙被",
+          key: "typeList",
+          width: 180,
+          slot: "typeList",
+        },
+        {
+          title: "瑙嗛鍐呭",
+          key: "videoFileKey",
+          width: 170,
+          slot: "videoFileKey"
+        },
+        {
+          title: "鏃堕暱",
+          key: "videoDuration",
+          width: 80,
+          align: 'center',
+          slot: "videoDuration",
+        },
+        {
+          title: "鎾斁閲�",
+          key: "playNum",
+          width: 80,
+          align: 'center'
+        },
+        {
+          title: "鏀惰棌鏁�",
+          key: "collectNum",
+          width: 80,
+          align: 'center'
+        },
+        {
+          title: "璇勮鏁�",
+          key: "commentNum",
+          width: 80,
+          align: 'center'
+        },
+        {
+          title: "棣栭〉鎺ㄨ崘",
+          key: "recommend",
+          slot: "recommend",
+          width: 100,
+          align: 'center'
+        },
+        {
+          title: "鏉冮噸",
+          key: "weight",
+          width: 170,
+        },
+        {
+          title: "鐘舵��",
+          key: "status",
+          slot: "status",
+          width: 120,
+          align: 'center'
+        },
+        {
+          title: "鎿嶄綔",
+          key: "action",
+          slot: "action",
+          align: "center",
+          width: 200,
+        },
+      ],
+      data: [], // 琛ㄥ崟鏁版嵁
+      kitchenType: [], // 鍘ㄧ鍒嗙被
+      total: 0, // 琛ㄥ崟鏁版嵁鎬绘暟
+      selectCount: 0, // 宸查�夋暟閲�
+      selectList: [], // 宸查�夋暟鎹垪琛�
+      uploadVideoForm: {
+        id: null,
+        checkKitchenType:[],
+        coverUrl: null,
+        videoFileKey: null,
+        videoFit: null,
+        videoDuration: null,
+        title: null,
+        videoContentType: null,
+        videoType: null,
+        showCoverUrl: null,
+        showVideoUrl: null,
+        temp: null
+
+      },
+    }
+  },
+  created() {
+    this.getDataList();
+    this.getTypes('')
+  },
+  methods: {
+    // 绉掕浆x鍒唜绉�
+    formatSeconds(seconds) {
+      if (isNaN(seconds) || seconds < 0) return '0绉�';
+
+      const mins = Math.floor(seconds / 60);
+      const secs = seconds % 60;
+
+      if (mins === 0) return `${secs}绉抈;
+      if (secs === 0) return `${mins}鍒哷;
+
+      return `${mins}鍒�${secs}绉抈;
+    },
+    // 鑾峰彇鍒嗙被鍒楄〃
+    getTypes(typeName) {
+      let params = {
+        'typeName': typeName
+      }
+      getKitchenTypeAllList(params).then(res => {
+        this.typeList = res.data
+      })
+    },
+    // 鑾峰彇瀵屾枃鏈紪杈戝櫒鐨勫唴瀹�
+    getReason(content) {
+      this.videoDownForm.reason = content
+    },
+    //閲嶆柊涓婁紶灏侀潰
+    clearCoverImage() {
+      this.$set(this.uploadVideoForm, 'coverUrl', '');
+      this.$set(this.uploadVideoForm, 'showCoverUrl', '');
+      this.$set(this.uploadVideoForm, 'temp', new Date().getTime());
+    },
+    //閲嶆柊涓婁紶瑙嗛
+    clearVideo() {
+      this.clearCoverImage();
+      this.$set(this.uploadVideoForm, 'videoFileKey', '');
+      this.$set(this.uploadVideoForm, 'showVideoUrl', '');
+      this.$set(this.uploadVideoForm, 'temp', new Date().getTime());
+      console.log(this.uploadVideoForm)
+    },
+    getVideoDuration(e){
+      const duration = this.$refs.healthVideoInfo.duration;
+      this.uploadVideoForm.videoDuration = Math.floor(duration);
+    },
+    // 瑙嗛涓婃灦
+    videoUp(row) {
+      this.$Modal.confirm({
+        title: "鎿嶄綔纭",
+        content: "鎮ㄧ‘璁よ涓婃灦瑙嗛銆� " + row.title + "銆戝悧?",
+        loading: true,
+        onOk: () => {
+          up(row.id).then(res => {
+            this.$Modal.remove();
+            if (res.code == 200) {
+              this.$Message.success("瑙嗛涓婃灦鎴愬姛");
+              this.getDataList();
+            }
+          });
+        }
+      });
+    },
+    // 瑙嗛涓嬫灦
+    videoDown() {
+      this.$refs.videoDownForm.validate((valid) => {
+        if (valid) {
+          down(this.videoDownForm).then(res => {
+            this.$Message.success("涓嬫灦鎴愬姛")
+            this.closeVideoDown()
+            this.getDataList()
+          })
+        }
+      })
+    },
+    // 鍏抽棴瑙嗛涓嬫灦
+    closeVideoDown() {
+      this.videoDownShow = false
+      this.videoDownForm = {
+        id: '',
+        reason: ''
+      }
+      this.$refs.editor.setContent('')
+    },
+    // 瑙嗛涓嬫灦
+    openVideoDown(row) {
+      this.videoDownForm.id = row.id
+      this.videoDownShow = true
+    },
+    // 瑙嗛鍙戝竷/淇敼
+    //todo 1
+    submitHealthVideo() {
+      console.log(this.uploadVideoForm)
+      try {
+        this.upLoadVideoLoading = true
+        this.$refs.uploadVideoForm.validate((valid) => {
+          if (valid) {
+            // 淇敼
+            if (this.uploadVideoForm.id) {
+              console.log(this.uploadVideoForm)
+              updateKitchenVideo(this.uploadVideoForm).then(res => {
+                this.$Message.success("淇敼瀹屾垚")
+                this.closeHealthVideo()
+                this.getDataList()
+              })
+            } else {
+              addKitchenVideo(this.uploadVideoForm).then(res => {
+                this.$Message.success("娣诲姞瀹屾垚")
+                this.closeHealthVideo()
+                this.getDataList()
+              })
+            }
+          }
+        })
+      } finally {
+        this.upLoadVideoLoading = false
+      }
+    },
+    //鑾峰彇鏍囩
+    getKitchenTypeList(e){
+    const typeParam =   {typeName:e}
+      getKitchenTypeAllList(typeParam).then(res => {
+       this.kitchenType = res.data
+     })
+
+    },
+
+    // 鍏抽棴绐楀彛
+    closeHealthVideo() {
+      //
+      this.uploadVideoForm = {};
+      this.upLoadVideoShow = false;
+    },
+    // 鎻愪氦瀹℃牳缁撴灉
+    submitAuditing() {
+      console.log(this.auditingForm, "sb")
+      this.$refs.auditingForm.validate((valid) => {
+        if (valid) {
+          auditingVideo(this.auditingForm).then(res => {
+            this.$Message.success("瀹℃牳瀹屾垚")
+            this.closeAuditing()
+            this.getDataList()
+          })
+        }
+      })
+    },
+    // 瀹℃牳缁撴灉鍙樺寲
+    resultChange(selected) {
+      this.auditingForm.result = selected === '閫氳繃' ? 1 : 0
+      console.log(this.auditingForm.result)
+    },
+    closeAuditing() {
+      this.auditingForm = {
+        id: null,
+        result: null,
+        reason: ''
+      }
+      this.detail = {}
+      this.auditingShow = false
+    },
+    // 鎵撳紑瀹℃牳寮圭獥
+    openAuditing(row) {
+      this.auditingShow = true
+      this.auditingLoading = true
+      this.auditingForm.id = row.id
+      getVideoById(row.id).then(res => {
+        this.detail = res.data
+        this.auditingLoading = false
+      })
+    },
+    // 鎵撳紑缂栬緫寮圭獥
+    deleteHealthVideo(row) {
+      console.log('鍒犻櫎娴嬭瘯', row)
+      this.$Modal.confirm({
+        title: "鎿嶄綔纭",
+        content: "鎮ㄧ‘璁よ鍒犻櫎瑙嗛銆� " + row.title + "銆戝悧?",
+        loading: true,
+        onOk: () => {
+          delKitchen(row.id).then(res => {
+            this.$Modal.remove();
+            if (res.code === 200) {
+              this.$Message.success("瑙嗛鍒犻櫎鎴愬姛");
+              this.getDataList();
+            }
+          });
+        }
+      });
+    },
+    // 缈昏瘧鐘舵��
+    transStatus(status) {
+      switch (status) {
+        case '99':
+          return '寰呭鏍�'
+        case '1':
+          return '宸插彂甯�'
+        case '0':
+          return '宸蹭笅鏋�'
+        case '-1':
+          return '瀹℃牳鏈�氳繃'
+        default:
+          return '鏈煡'
+      }
+    },
+    // 寮�鍚垨鍏抽棴鎺ㄨ崘鐨勬柟娉�
+    handleBeforeChange(row) {
+      let content = ""
+      if (row.recommend) {
+        content = '纭瑕佸叧闂椤垫帹鑽愬悧锛�'
+      } else {
+        content = '纭瑕佸紑鍚椤垫帹鑽愬悧锛�'
+      }
+      return new Promise((resolve) => {
+        this.$Modal.confirm({
+          title: '鎿嶄綔鎻愰啋',
+          content: content,
+          onOk: () => {
+            recommendSet({id: row.id, recommend: !row.recommend}).then(res => {
+              this.$Message.success(res.msg);
+              resolve();
+            })
+          }
+        });
+      });
+    },
+    // 鍏抽棴瑙嗛鎾斁
+    playVideoClose() {
+      this.playVideoTitle = '';
+      this.playVideoUrl = '';
+      this.playVideoShow = false
+    },
+    // 鐐瑰嚮鎾斁瑙嗛
+    playVideo(fileKey, title) {
+      this.playVideoTitle = title;
+
+      getFilePreview(fileKey).then(res => {
+        this.playVideoUrl = res.data
+        this.playVideoShow = true
+      })
+    },
+    // 鎼滅储
+    handleSearch() {
+      this.searchForm.pageNumber = 1;
+      this.searchForm.pageSize = 10;
+      this.getDataList();
+    },
+    // 鑾峰彇鍒楄〃鏁版嵁
+    getDataList() {
+      this.loading = true;
+      getKitchenVideos(this.searchForm).then((res) => {
+        console.log(res)
+        this.loading = false;
+        if (res.code === 200) {
+          this.data = res.data;
+          this.total = res.total;
+        }
+      });
+      this.total = this.data.length;
+      this.loading = false;
+    },
+    showSelect(e) {
+      this.selectList = e.map(d => d.id);
+      this.selectCount = e.length;
+    },
+    // 鎺掑簭
+    changeSort(e) {
+      this.searchForm.sort = e.key;
+      this.searchForm.order = e.order;
+      if (e.order == "normal") {
+        this.searchForm.order = "";
+      }
+      this.getDataList();
+    },
+    // 鍒嗛〉 鏀瑰彉椤电爜
+    changePage(v) {
+      this.searchForm.pageNumber = v;
+      this.getDataList();
+    },
+
+    // 鍒嗛〉 鏀瑰彉椤垫暟
+    changePageSize(v) {
+      this.searchForm.pageNumber = 1;
+      this.searchForm.pageSize = v;
+      this.getDataList();
+    },
+
+    handleVideoUpLoad(row) {
+      this.uploadVideoForm = {};
+      this.upLoadVideoShow = true;
+      console.log(row)
+      if (row.id) {
+        this.uploadVideoForm.id = row.id;
+        this.uploadVideoForm.showVideoUrl = row.videoUrl
+        this.uploadVideoForm.videoFileKey = row.videoFileKey;
+        this.uploadVideoForm.coverUrl = row.coverUrl;
+        this.uploadVideoForm.showCoverUrl = row.coverShowUrl;
+        this.uploadVideoForm.title = row.title;
+        this.uploadVideoForm.checkKitchenType = row.typeList.map(item => {return item.id});
+      }
+      this.getKitchenTypeList();
+    },
+    async upLoadVideo(file) {
+      try {
+        this.$nextTick(() => {
+          this.upLoadVideoLoading = true;
+        })
+        // 鑾峰彇鏂囦欢涓婁紶涓存椂瀵嗛挜
+        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, // 瑕佷笂浼犵殑鏂囦欢瀵硅薄銆�
+          SliceSize: 1024 * 1024 * 5,
+          onProgress: function (progressData) {
+            console.log('涓婁紶杩涘害锛�', progressData);
+          },
+        });
+
+        console.log(this.uploadVideoForm)
+        this.$nextTick(() => {
+          this.uploadVideoForm.videoFileKey = fileKey;
+          this.uploadVideoForm.showVideoUrl = sts.data.endpoint + "/" + fileKey;
+        })
+        console.log("涓婁紶鎴愬姛", upData)
+        const duration = this.$refs.healthVideoInfo.duration;
+        console.log('-娴嬭瘯鑾峰彇鏃堕棿淇℃伅---------------->', duration);
+      } catch (e) {
+        console.log("涓婁紶澶辫触", upData)
+      } finally {
+        this.$nextTick(() => {
+          this.upLoadVideoLoading = false;
+        })
+      }
+      return false;
+    },
+    async upLoadImg(file) {
+      try {
+        this.upLoadVideoLoading = true;
+        // 鑾峰彇鏂囦欢涓婁紶涓存椂瀵嗛挜
+        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, // 瑕佷笂浼犵殑鏂囦欢瀵硅薄銆�
+          SliceSize: 1024 * 1024 * 5,
+          onProgress: function (progressData) {
+            console.log('涓婁紶杩涘害锛�', progressData);
+          },
+        });
+        console.log("涓婁紶鎴愬姛", upData)
+        this.$nextTick(() => {
+          this.uploadVideoForm.coverUrl = fileKey;
+          this.uploadVideoForm.showCoverUrl = sts.data.endpoint + "/" + fileKey;
+        })
+
+      } catch (e) {
+        console.log("涓婁紶澶辫触", upData)
+      } finally {
+        this.upLoadVideoLoading = false;
+      }
+      return false;
+    }
+  }
+}
+</script>
+
+<style scoped>
+.play-text {
+  width: 100%;
+  text-align: center;
+  color: #2d8cf0;
+}
+
+.play-text:hover {
+  cursor: pointer;
+}
+
+.video-warp {
+  width: 786px;
+  height: 432px;
+}
+
+.data-item {
+  display: flex;
+  align-items: center;
+}
+
+.showCoverImg {
+  position: relative;
+}
+
+.coverImgRemove {
+  position: absolute;
+  top: 15px;
+  right: -15px;
+}
+</style>
diff --git a/manager/src/views/video/GoodsExpandRow.vue b/manager/src/views/video/GoodsExpandRow.vue
new file mode 100644
index 0000000..d81e691
--- /dev/null
+++ b/manager/src/views/video/GoodsExpandRow.vue
@@ -0,0 +1,35 @@
+<template>
+  <div>
+    <Row v-for="goods in goodsList" :key="goods.goodsId">
+      <Row style="width:100%;align-items: center">
+        <Col span="6">
+          <img :src="goods.thumbnail" style="width: 150px;height: 150px"/>
+        </Col>
+        <Col span="6">
+          <p>鍟嗗搧鍚嶇О: {{ goods.goodsName }}</p>
+        </Col>
+        <Col span="6">
+          <p>鍟嗗搧鍗曚环: 锟{ goods.price }}</p>
+        </Col>
+        <Col span="6">
+          <p>鍟嗗搧鏁伴噺: {{ goods.goodsNum }}</p>
+        </Col>
+      </Row>
+    </Row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "GoodsExpandRow",
+  props: {
+    goodsList: {
+      type: Array
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>
diff --git a/manager/src/views/video/VideoList.vue b/manager/src/views/video/VideoList.vue
index 8e2e6b0..f017ac9 100644
--- a/manager/src/views/video/VideoList.vue
+++ b/manager/src/views/video/VideoList.vue
@@ -72,7 +72,7 @@
       <Modal
         v-model="auditingShow"
         title="瑙嗛瀹℃牳"
-        width="800"
+        width="1200"
         :loading="auditingLoading"
         :mask-closable="false"
       >
@@ -92,11 +92,45 @@
               </div>
             </div>
           </Form-item>
-          <Form-item label="瑙嗛鏃堕暱锛�" :label-width="72">
+          <Form-item v-if="detail.videoContentType === 'video'" label="瑙嗛鏃堕暱锛�" :label-width="72">
             <div>{{formatSeconds(detail.videoDuration)}}</div>
           </Form-item>
-          <Form-item class="video-warp" :label-width="0">
-            <video :src="detail.videoUrl" autoplay controls style="width: 768px;height: 432px"/>
+          <Form-item v-if="detail.videoContentType === 'img'" label="鍥剧墖寮犳暟锛�" :label-width="72">
+            <div>{{detail.imgs.length}}</div>
+          </Form-item>
+          <Form-item v-if="detail.videoContentType === 'video'" class="video-warp" :label-width="0">
+            <Row>
+              <Col span="11">
+                <video :src="detail.videoUrl" autoplay controls style="width: 500px;height: 300px"/>
+              </Col>
+              <Col span="13" style="max-height: 300px;overflow-y: scroll">
+                <Row v-for="goods in detail.goodsList" :key="goods.goodsId" style="width: 100%">
+                  <Row style="width:100%;align-items: center">
+                    <Col span="6">
+                      <img :src="goods.thumbnail" style="width: 100px;height: 100px"/>
+                    </Col>
+                    <Col span="10">
+                      <p>鍟嗗搧鍚嶇О: {{ goods.goodsName }}</p>
+                    </Col>
+                    <Col span="4">
+                      <p>鍟嗗搧鍗曚环: 锟{ goods.price }}</p>
+                    </Col>
+                    <Col span="4">
+                      <p>鍟嗗搧鏁伴噺: {{ goods.goodsNum }}</p>
+                    </Col>
+                  </Row>
+                </Row>
+              </Col>
+            </Row>
+
+          </Form-item>
+          <Form-item v-if="detail.videoContentType === 'img'" :label-width="0">
+            <div style="display: flex;flex-direction: row;flex-wrap: wrap">
+              <div v-for="img in detail.imgs" :key="img" class="img-warp">
+                <img :src="img" class="image">
+              </div>
+            </div>
+
           </Form-item>
           <Form-item label="瀹℃牳缁撴灉锛�" :label-width="100" prop="result">
             <RadioGroup v-model="auditingForm.result">
@@ -193,9 +227,10 @@
 import {getVideoTagList} from "@/api/videoTag";
 import {getFilePreview} from "@/api/file";
 import Editor from '@/components/editor/index.vue'
+import GoodsExpandRow from '@/views/video/GoodsExpandRow'
 export default {
   name: "VideoList",
-  components: {Editor},
+  components: {Editor,GoodsExpandRow},
   data() {
     return {
       videoDownForm: {
@@ -264,6 +299,17 @@
           type: 'selection',
           width: 60,
           align: 'center'
+        },
+        {
+          width: 60,
+          type: 'expand',
+          render: (h, params) => {
+            return h(GoodsExpandRow, {
+              props: {
+                goodsList: params.row.goodsList
+              }
+            })
+          }
         },
         {
           title: "鏍囬",
@@ -566,11 +612,18 @@
   cursor: pointer;
 }
 .video-warp {
-  width: 786px;
-  height: 432px;
+  width: 100%;
+  height: 350px;
 }
 .data-item {
   display: flex;
   align-items: center;
 }
+.img-warp {
+  padding: 10px;
+}
+.image {
+  width: 150px;
+  height: 200px;
+}
 </style>
diff --git a/seller/package.json b/seller/package.json
index 23f4baf..fe2ac56 100644
--- a/seller/package.json
+++ b/seller/package.json
@@ -13,6 +13,7 @@
     "@amap/amap-jsapi-loader": "0.0.7",
     "@antv/g2": "^4.1.14",
     "axios": "^0.21.1",
+    "cos-js-sdk-v5": "^1.10.1",
     "dplayer": "^1.27.1",
     "js-cookie": "^2.2.1",
     "node-sass": "^4.14.1",
diff --git a/seller/src/api/file.js b/seller/src/api/file.js
new file mode 100644
index 0000000..8c1bee0
--- /dev/null
+++ b/seller/src/api/file.js
@@ -0,0 +1,31 @@
+import service, {
+  getRequest,
+  postRequest,
+  putRequest,
+  deleteRequest,
+  importRequest,
+  getRequestWithNoToken,
+  commonUrl,
+  postRequestWithNoForm
+} from "@/libs/axios";
+
+
+// 鑾峰彇鏂囦欢涓存椂璁块棶url
+export const getFilePreview = (fileKey) => {
+    return service({
+        baseURL: commonUrl,
+        url: "/common/lmk/file/preview",
+        method: "POST",
+        data: {"fileKey": fileKey}
+    })
+}
+
+// 鑾峰彇STS璁块棶浠ょ墝
+export const getSts = () => {
+    return service({
+        baseURL: commonUrl,
+        url: "/common/lmk/file/sts",
+        method: "GET"
+    })
+}
+
diff --git a/seller/src/libs/axios.js b/seller/src/libs/axios.js
index a61bcf6..768708e 100644
--- a/seller/src/libs/axios.js
+++ b/seller/src/libs/axios.js
@@ -353,7 +353,8 @@
     }
   });
 };
-
+// 鍘熷鐨刟xios鏆撮湶鍑哄幓鐢ㄥ嵆鍙�
+export default service
 export const uploadFileRequest = (url, params) => {
   let accessToken = getStore("accessToken");
   return service({
diff --git a/seller/src/utils/file.js b/seller/src/utils/file.js
new file mode 100644
index 0000000..74cfa34
--- /dev/null
+++ b/seller/src/utils/file.js
@@ -0,0 +1,40 @@
+
+/**
+ * 鐢熸垚fileKey
+ *
+ * @param fileName 鏂囦欢鍚�
+ * @returns {*}
+ */
+export function getFileKey (fileName) {
+    const extension = fileName.split('.').pop().toLowerCase();
+        
+	const fileTypes = {
+		image: { name: '鍥剧墖', exts: ["jpg", "png", "jpeg", "gif", "bmp", "webp", "tiff", "svg", "ico", "psd", "raw"] },
+		video: { name: '瑙嗛', exts: ["mp4", "avi", "rmvb", "mov", "wmv", "flv", "mkv", "mpeg", "mpg", "m4v", "3gp", "webm", "vob", "swf"] },
+		radio: { name: '闊抽', exts: ["mp3", "wma", "wav", "mpeg-4", "cd", "m4a", "aac", "flac", "ogg", "aiff", "ape", "midi", "amr", "ra"] },
+		text: { name: '鏂囨湰', exts: ["txt", "xls", "xlsx", "doc", "docx", "pdf", "ppt", "pptx", "csv", "rtf", "odt", "ods", "odp", "epub", "mobi", "pages", "numbers", "key"] },
+		zip: { name: '鍘嬬缉鏂囦欢', exts: ["zip", "rar", "7z", "tar", "gz", "bz2", "xz", "iso", "dmg", "pkg", "cab", "z", "lz", "lzma", "lzo"] }
+	};
+  
+	// 鑾峰彇褰撳墠鏃堕棿骞舵牸寮忓寲涓� yyyyMMddHHmmss
+	const now = new Date();
+	const yyyyMMddHHmmss = [
+		now.getFullYear(),
+		String(now.getMonth() + 1).padStart(2, '0'),
+		String(now.getDate()).padStart(2, '0'),
+		String(now.getHours()).padStart(2, '0'),
+		String(now.getMinutes()).padStart(2, '0'),
+		String(now.getSeconds()).padStart(2, '0')
+	].join('');
+	
+	// 鐢熸垚5浣嶉殢鏈烘暟瀛�
+	const random5Digits = Math.floor(10000 + Math.random() * 90000);
+	
+	// 鏌ユ壘鍖归厤鐨勬枃浠剁被鍨�
+	for (const [type, data] of Object.entries(fileTypes)) {
+		if (data.exts.includes(extension)) {
+			return `${type}/${yyyyMMddHHmmss}${random5Digits}` + '.' + extension;
+		}
+	}
+    return '';
+}
diff --git a/seller/src/views/goods/goods-seller/goods.vue b/seller/src/views/goods/goods-seller/goods.vue
index ed68fda..e4efb96 100644
--- a/seller/src/views/goods/goods-seller/goods.vue
+++ b/seller/src/views/goods/goods-seller/goods.vue
@@ -95,10 +95,11 @@
         <template slot="goodsSlot" slot-scope="{ row }">
           <div style="margin-top: 5px; height: 90px; display: flex">
             <div style="">
-              <img
+              <img v-if="row.original"
                 :src="row.original"
                 style="height: 80px; margin-top: 3px; width: 70px"
               />
+              <video :src="row.goodsVideo" v-else style="height: 80px; margin-top: 3px; width: 70px"></video>
             </div>
 
             <div style="margin-left: 13px">
diff --git a/seller/src/views/goods/goods-seller/goodsOperation.vue b/seller/src/views/goods/goods-seller/goodsOperation.vue
index 77c41ec..d689a13 100644
--- a/seller/src/views/goods/goods-seller/goodsOperation.vue
+++ b/seller/src/views/goods/goods-seller/goodsOperation.vue
@@ -13,8 +13,8 @@
     <second-step ref='second' :firstData="firstData" v-if="activestep === 1"></second-step>
     <!-- 绗笁姝� 鍙戝竷瀹屾垚 -->
     <third-step ref='third' v-if="activestep === 2"></third-step>
-    
-    
+
+
   </div>
 </template>
 <script>
@@ -51,7 +51,7 @@
       this.activestep = 0
       this.$refs.first.selectGoodsType = true;
     }
-    
+
   }
 };
 </script>
diff --git a/seller/src/views/goods/goods-seller/goodsOperationFirst.vue b/seller/src/views/goods/goods-seller/goodsOperationFirst.vue
index 47af408..db69887 100644
--- a/seller/src/views/goods/goods-seller/goodsOperationFirst.vue
+++ b/seller/src/views/goods/goods-seller/goodsOperationFirst.vue
@@ -109,19 +109,19 @@
           type: "PHYSICAL_GOODS",
           check: false,
         },
-        {
-          title: "铏氭嫙鍟嗗搧",
-          img: require("@/assets/goodsType2.png"),
-          desc: "铏氭嫙鏍搁獙锛屾棤闇�鐗╂祦",
-          type: "VIRTUAL_GOODS",
-          check: false,
-        },
-        {
-          title: "鍟嗗搧妯℃澘瀵煎叆",
-          img: require("@/assets/goodsTypeTpl.png"),
-          desc: "鍟嗗搧妯℃澘锛屼竴閿鍏�",
-          check: false,
-        },
+        // {
+        //   title: "铏氭嫙鍟嗗搧",
+        //   img: require("@/assets/goodsType2.png"),
+        //   desc: "铏氭嫙鏍搁獙锛屾棤闇�鐗╂祦",
+        //   type: "VIRTUAL_GOODS",
+        //   check: false,
+        // },
+        // {
+        //   title: "鍟嗗搧妯℃澘瀵煎叆",
+        //   img: require("@/assets/goodsTypeTpl.png"),
+        //   desc: "鍟嗗搧妯℃澘锛屼竴閿鍏�",
+        //   check: false,
+        // },
       ],
       // 鍟嗗搧鍒嗙被閫夋嫨鏁扮粍
       category: [
@@ -130,7 +130,8 @@
         { name: "", id: "" },
       ],
       // 鍟嗗搧绫诲瀷
-      goodsType: "",
+      // goodsType: "",
+      goodsType: "PHYSICAL_GOODS",
       /** 1绾у垎绫诲垪琛�*/
       categoryListLevel1: [],
       /** 2绾у垎绫诲垪琛�*/
@@ -230,10 +231,13 @@
       if (!this.category[0].name) {
         this.$Message.error("璇烽�夋嫨鍟嗗搧鍒嗙被");
         return;
-      } else if (!this.category[2].name) {
-        this.$Message.error("蹇呴』閫夋嫨鍒颁笁绾у垎绫�");
-        return;
-      } else if (this.category[2].name) {
+      }
+      //鍏抽棴蹇呴』閫夋嫨3涓祦绋嬬殑閫夐」
+      // else if (!this.category[2].name) {
+      //   this.$Message.error("蹇呴』閫夋嫨鍒颁笁绾у垎绫�");
+      //   return;
+      // }
+      else if (this.category[2].name) {
         let params = {
           category: this.category,
           goodsType: this.goodsType,
@@ -245,6 +249,14 @@
           this.$emit("change", params);
         }
       }
+      //娴佺▼璋冩暣
+      else {
+        let params = {
+          category: this.category,
+          goodsType: this.goodsType,
+        };
+        this.$emit("change", params);
+      }
     },
   },
   mounted() {
diff --git a/seller/src/views/goods/goods-seller/goodsOperationSec.vue b/seller/src/views/goods/goods-seller/goodsOperationSec.vue
index 0965954..a2e8262 100644
--- a/seller/src/views/goods/goods-seller/goodsOperationSec.vue
+++ b/seller/src/views/goods/goods-seller/goodsOperationSec.vue
@@ -26,13 +26,13 @@
             <FormItem label="鍟嗗搧鍗栫偣" prop="sellingPoint">
               <Input v-model="baseInfoForm.sellingPoint" :rows="4" style="width: 260px" type="textarea"/>
             </FormItem>
-            <FormItem label="鍟嗗搧鍝佺墝" prop="brandId">
-              <Select v-model="baseInfoForm.brandId" filterable style="width: 200px">
-                <Option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id"></Option>
-              </Select>
-              <Button class="refresh-icon" icon="md-refresh" shape="circle" type="text"
-                      @click="refresh('brand')"></Button>
-            </FormItem>
+<!--            <FormItem label="鍟嗗搧鍝佺墝" prop="brandId">-->
+<!--              <Select v-model="baseInfoForm.brandId" filterable style="width: 200px">-->
+<!--                <Option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id"></Option>-->
+<!--              </Select>-->
+<!--              <Button class="refresh-icon" icon="md-refresh" shape="circle" type="text"-->
+<!--                      @click="refresh('brand')"></Button>-->
+<!--            </FormItem>-->
           </div>
           <h4>鍟嗗搧浜ゆ槗淇℃伅</h4>
           <div class="form-item-view">
@@ -101,10 +101,10 @@
           </div>
           <h4>鍟嗗搧瑙勬牸鍙婂浘鐗�</h4>
           <div class="form-item-view">
-            <FormItem class="form-item-view-el required" label="涓诲浘" prop="goodsGalleryFiles">
+            <FormItem class="form-item-view-el required" label="涓诲浘" prop="goodsGalleryFiles"  v-if=" baseInfoForm.goodsVideo ==null || baseInfoForm.goodsVideo ===''">
               <div style="display: flex; flex-wrap: wrap;">
-                <vuedraggable :animation="200" :list="baseInfoForm.goodsGalleryFiles">
-                  <div v-for="(item, __index) in baseInfoForm.goodsGalleryFiles" :key="__index"
+                <vuedraggable :animation="200" :list="showListImages">
+                  <div v-for="(item, __index) in showListImages" :key="__index"
                        class="demo-upload-list">
                     <template>
                       <img :src="item"/>
@@ -118,17 +118,17 @@
                   </div>
                 </vuedraggable>
                 <!--<Upload ref="upload"-->
-                        <!--:action="uploadFileUrl" :before-upload="handleBeforeUploadGoodsPicture"-->
-                        <!--:format="['jpg', 'jpeg', 'png', 'webp']"-->
-                        <!--:headers="{ ...accessToken }"-->
-                        <!--:max-size="2048" :on-error="() => { $Spin.hide(); }" :on-exceeded-size="handleMaxSize"-->
-                        <!--:on-format-error="handleFormatError" :on-progress="() => { $Spin.show(); }"-->
-                        <!--:on-success="handleSuccessGoodsPicture" :show-upload-list="false" multiple-->
-                        <!--style="margin-left: 10px"-->
-                        <!--type="drag">-->
-                  <!--<div style="width: 148px; height: 148px; line-height: 148px">-->
-                    <!--<Icon size="20" type="md-add"></Icon>-->
-                  <!--</div>-->
+                <!--:action="uploadFileUrl" :before-upload="handleBeforeUploadGoodsPicture"-->
+                <!--:format="['jpg', 'jpeg', 'png', 'webp']"-->
+                <!--:headers="{ ...accessToken }"-->
+                <!--:max-size="2048" :on-error="() => { $Spin.hide(); }" :on-exceeded-size="handleMaxSize"-->
+                <!--:on-format-error="handleFormatError" :on-progress="() => { $Spin.show(); }"-->
+                <!--:on-success="handleSuccessGoodsPicture" :show-upload-list="false" multiple-->
+                <!--style="margin-left: 10px"-->
+                <!--type="drag">-->
+                <!--<div style="width: 148px; height: 148px; line-height: 148px">-->
+                <!--<Icon size="20" type="md-add"></Icon>-->
+                <!--</div>-->
                 <!--</Upload>-->
               </div>
               <div style="width: 100%;display: flex;justify-content: start;margin-top: 10px;">
@@ -139,22 +139,33 @@
               </Modal>
             </FormItem>
             <FormItem>
-              <div style="color: grey">涓诲浘浠呮敮鎸乸ng锛宩pg锛宩peg鏍煎紡锛屽楂樿嚦灏�600*600px锛屽ぇ灏�2M鍐咃紝鍙嫋鎷借皟鏁翠富鍥鹃『搴�</div>
+
+<!--              <div class="demo-upload-list" v-for="(item,index) in showListImages">-->
+<!--                <template style="display: flex">-->
+<!--                  <img :src="item">-->
+<!--                  <div class="demo-upload-list-cover">-->
+<!--                    <Icon type="ios-eye-outline" @click.native="handleView(item)"></Icon>-->
+<!--                    <Icon type="ios-trash-outline" @click.native="handleRemove(index)"></Icon>-->
+<!--                  </div>-->
+<!--                </template>-->
+<!--              </div>-->
+              <div style="color: grey"  v-if="!baseInfoForm.goodsVideo">涓诲浘浠呮敮鎸乸ng锛宩pg锛宩peg鏍煎紡锛屽楂樿嚦灏�600*600px锛屽ぇ灏�2M鍐�</div>
             </FormItem>
-            <FormItem class="form-item-view-el" label="涓诲浘瑙嗛" prop="goodsVideo">
+            <FormItem class="form-item-view-el" label="瑙嗛" prop="goodsVideo" v-if="!(baseInfoForm.goodsGalleryFiles !=null &&baseInfoForm.goodsGalleryFiles.length>0)">
               <div class="goods-video">
                 <div v-if="baseInfoForm.goodsVideo">
                   <div>
-                    <video :src="baseInfoForm.goodsVideo" class="video" controls style="max-width: 300px;"/>
+                    <video :src="baseInfoForm.showGoodsVideo" class="video" controls style="max-width: 300px;"/>
                   </div>
                 </div>
-                <Upload ref="upload" :action="uploadFileUrl" :format="['avi', 'wmv', 'mpeg', 'mp4', 'mov']"
+                <Upload ref="upload" action="-" :format="['avi', 'wmv', 'mpeg', 'mp4', 'mov']"
                         :headers="{ ...accessToken }"
                         :max-size="10240" :on-error="() => { loadingVideo = false }"
                         :on-exceeded-size="handleVideoMaxSize"
                         :on-format-error="handleFormatError" :on-progress="() => { loadingVideo = true }"
                         :on-success="handleSuccessGoodsVideo" :show-upload-list="false"
-                        multiple
+                        :before-upload="upLoadVideo"
+                        accept="video/*"
                         style="margin-left: 10px" type="drag">
                   <Button :loading="loadingVideo" icon="ios-cloud-upload-outline" type="text">
                     <span v-if="!loadingVideo">
@@ -165,6 +176,9 @@
                     </span>
                   </Button>
                 </Upload>
+                <Button :loading="loadingVideo" v-if="baseInfoForm.goodsVideo"  icon="delete" @click="removeVideo" type="text">
+                  <span>鍒犻櫎瑙嗛</span>
+                </Button>
               </div>
             </FormItem>
             <div class="layout" style="width: 100%">
@@ -176,7 +190,7 @@
                       <div v-for="(item, $index) in skuInfo" :key="$index" class="sku-item-content">
                         <Card :bordered="true" class="ivu-card-body">
                           <a slot="extra" style="margin-left: 6px">
-                            <Icon size="20" type="md-trash"  @click="handleCloseSkuItem($index, item)"></Icon>
+                            <Icon size="20" type="md-trash" @click="handleCloseSkuItem($index, item)"></Icon>
                           </a>
                           <div>
                             <div style="display: flex;margin-bottom: 10px;font-weight: bold">瑙勬牸椤�</div>
@@ -185,10 +199,13 @@
                               <div>
                                 <AutoComplete v-model="item.name" :filter-method="filterMethod"
                                               :maxlength="30" placeholder="璇疯緭鍏ヨ鏍奸」鍚嶇О" style="width: 150px"
-                                              @on-focus="changeSkuItem(item.name)" @on-change="editSkuItem(item.name, $index, item)">
+                                              @on-focus="changeSkuItem(item.name)"
+                                              @on-change="editSkuItem(item.name, $index, item)">
                                 </AutoComplete>
 
-                                <iSwitch v-if="$index === 0" style="margin-left: 10px" size="small" @on-change="changeSkuOpenImage" v-model="openImage" /><span v-if="$index === 0" style="margin-left: 5px">娣诲姞瑙勬牸鍥剧墖</span>
+<!--                                <iSwitch v-if="$index === 0" style="margin-left: 10px" size="small"-->
+<!--                                         @on-change="changeSkuOpenImage" v-model="openImage"/>-->
+<!--                                <span v-if="$index === 0" style="margin-left: 5px">娣诲姞瑙勬牸鍥剧墖</span>-->
                               </div>
                             </FormItem>
 
@@ -210,7 +227,8 @@
                                                 @on-change="skuValueChange(val, index, item)">
                                   </AutoComplete>
                                   <a style="margin-left: 6px" v-if="val.value && val.value !== ''">
-                                    <Icon size="15" type="md-trash" @click="handleCloseSkuValue(val, index, item)"></Icon>
+                                    <Icon size="15" type="md-trash"
+                                          @click="handleCloseSkuValue(val, index, item)"></Icon>
                                   </a>
                                 </div>
                                 <div v-if="$index === 0 && openImage" style="margin-top: 10px">
@@ -225,19 +243,20 @@
                                           style="width: 180px;height: 140px"
                                         />
                                         <div class="sku-upload-list-cover">
-                                          <div style="margin-top: 50px" >
+                                          <div style="margin-top: 50px">
                                             <Icon size="25" type="md-search" @click="handleView(img)"></Icon>
-                                            <Icon size="25" type="md-trash" @click="handleRemove(val.images, __index)"></Icon>
+                                            <Icon size="25" type="md-trash"
+                                                  @click="handleRemove(val.images, __index)"></Icon>
                                           </div>
                                         </div>
                                       </template>
                                     </div>
                                   </vuedraggable>
-                                  <Upload ref="uploadSku" :action="uploadFileUrl"
+<!--                                  todo 3-->
+                                  <Upload ref="uploadSku" action="-"
                                           v-if="val.images < 1"
                                           :before-upload="handleBeforeUpload"
                                           :format="['jpg', 'jpeg', 'png', 'webp']"
-                                          :headers="{ ...accessToken }"
                                           :max-size="2048"
                                           :on-error="() => { $Spin.hide(); }"
                                           :on-exceeded-size="handleMaxSize"
@@ -255,7 +274,9 @@
                                 </div>
                               </FormItem>
 
-                              <FormItem v-if="item.spec_values.length < 10 && item.spec_values.length >= 1 && item.spec_values[0].value !== ''" class="sku-item-content-val flex" label="" style="line-height: 32px;">
+                              <FormItem
+                                v-if="item.spec_values.length < 10 && item.spec_values.length >= 1 && item.spec_values[0].value !== ''"
+                                class="sku-item-content-val flex" label="" style="line-height: 32px;">
                                 <AutoComplete ref="input" v-model="newSkuValues[$index]"
                                               :filter-method="filterMethod"
                                               :maxlength="30" placeholder="鑷畾涔夎鏍煎��" style="width: 180px"
@@ -473,8 +494,32 @@
     <!--<Modal width="1200px" v-model="picModelFlag">-->
     <!--<ossManage @callback="callbackSelected" ref="ossManage" />-->
     <!--</Modal>-->
-    <Modal v-model="picModelFlag" width="1200px" @on-ok="confirmUrls">
-      <ossManage ref="ossManage" :isComponent="true" :initialize="picModelFlag" @callback="callbackSelected" @selected="(list)=>{ selectedImage = list}"/>
+    <!--    todo web-->
+    <Modal v-model="picModelFlag" width="1200px">
+      <!--      <ossManage ref="ossManRage" :isComponent="true" :initialize="picModelFlag" @callback="callbackSelected" @selected="(list)=>{ selectedImage = list}"/>-->
+      <div class="demo-upload-list" v-for="(item,index) in showListImages">
+        <template>
+          <img :src="item">
+          <div class="demo-upload-list-cover">
+            <Icon type="ios-eye-outline" @click.native="handleView(item)"></Icon>
+            <Icon type="ios-trash-outline" @click.native="handleRemove(null,index)"></Icon>
+          </div>
+        </template>
+      </div>
+      <div class="demo-upload-list">
+        <Upload
+          :before-upload="upLoadImg"
+          accept="image/*"
+          action="-"
+          type="drag"
+          style=" display: inline-block;width: 58px"
+        >
+          <div style="width: 58px;height:58px;line-height: 58px;">
+            <Icon type="ios-camera" size="20"></Icon>
+          </div>
+        </Upload>
+      </div>
+
     </Modal>
 
   </div>
@@ -491,6 +536,9 @@
 import DPlayer from 'dplayer';
 // import ossManage from "@/views/sys/oss-manage/ossManage";
 import ossManage from "@/views/shop/ossManages";
+import COS from 'cos-js-sdk-v5';
+import {getFileKey} from "@/utils/file.js";
+import {getFilePreview, getSts} from "@/api/file";
 
 
 export default {
@@ -523,6 +571,7 @@
       }, 1000);
     };
     return {
+      showListImages: [],
       regular,
       openImage: false,
       needToloadSku: false,
@@ -625,6 +674,7 @@
         /** 鍟嗗搧鍒嗙被涓枃鍚� */
         categoryName: [],
         goodsVideo: "",
+        showGoodsVideo: "",
       },
       /** 琛ㄦ牸澶� */
       skuTableColumn: [],
@@ -698,12 +748,19 @@
       if (val) {
         this.initVideo();
       }
+    },
+    showListImages(newValue){
+      this.baseInfoForm.goodsGalleryFiles = newValue.map(item => {
+        return   item.split('/').slice(-2).join('/')
+      })
     }
   },
   methods: {
     // 閫夋嫨鍥剧墖modal
     handleCLickImg(val, index) {
-      this.$refs.ossManage.selectImage = true;
+      console.log('娴嬭瘯杈撳叆鐨勫��----------------銆�', val)
+      // 搴熷純鍘熸湁鐨勫浘鐗囦笂浼�
+      // this.$refs.ossManage.selectImage = true;
       this.picModelFlag = true;
       this.selectedFormBtnName = val;
       // this.picIndex = index;
@@ -865,7 +922,15 @@
     },
     // 绉婚櫎宸查�夊浘鐗�
     handleRemove(item, index) {
-      item.splice(index, 1)
+      if (!item) {
+        this.listImages.splice(index, 1);
+        this.showListImages.splice(index, 1);
+        this.baseInfoForm.goodsGalleryFiles.splice(index, 1);
+        this.baseInfoForm.goodsGalleryList.splice(index, 1);
+      } else {
+        console.log('绉婚櫎娴嬭瘯',item, index);
+        item.splice(index, 1)
+      }
       this.previewPicture = "";
     },
     // 鏌ョ湅鍟嗗搧澶у浘
@@ -999,14 +1064,57 @@
       }
     },
     // sku鍥剧墖涓婁紶鍓嶉挬瀛�
-    handleBeforeUpload(file) {
+  async handleBeforeUpload(file) {
       const check =
         this.selectedSku.images !== undefined &&
         this.selectedSku.images.length > 5;
       if (check) {
         this.$Notice.warning({title: "鍥剧墖鏁伴噺涓嶈兘澶т簬浜斿紶"});
-        return false;
       }
+      try {
+        // this.upLoadVideoLoading = true;
+        // 鑾峰彇鏂囦欢涓婁紶涓存椂瀵嗛挜
+        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, // 瑕佷笂浼犵殑鏂囦欢瀵硅薄銆�
+          SliceSize: 1024 * 1024 * 5,
+          onProgress: function (progressData) {
+            console.log('涓婁紶杩涘害锛�', progressData);
+          },
+        });
+        console.log("涓婁紶鎴愬姛", upData)
+        this.$nextTick(() => {
+          this.listImages.push(fileKey);
+          this.showListImages.push(sts.data.endpoint + "/" + fileKey);
+          this.baseInfoForm.goodsGalleryFiles.push(fileKey);
+        })
+
+      } catch (e) {
+        console.log("涓婁紶澶辫触", upData)
+        return false;
+      } finally {
+        // this.upLoadVideoLoading = false;
+
+      }
+      return false;
+
     },
 
     /** 鏌ヨ鍟嗗搧鍝佺墝鍒楄〃 */
@@ -1086,8 +1194,34 @@
         this.baseInfoForm.goodsGalleryFiles =
           response.result.goodsGalleryList.map((i) => {
             return i;
-          });
+          })
+        try {
+          const stsInfo = await getSts();
+          const endpoint = stsInfo.data.endpoint;
+          this.showListImages = response.result.goodsGalleryList.map((i) => {
+            if (i!=null&&i.indexOf('http')===-1)
+            return endpoint+'/'+i;
+            else return i;
+          })
+          if (response.result.goodsVideo){
+
+          }
+        } catch (e) {
+          console.log('缁勮璺緞鍑洪棶棰�',e);
+        }
+
       }
+     if (response.result.goodsVideo){
+       try {
+         const stsInfo = await getSts();
+         const endpoint = stsInfo.data.endpoint;
+         this.baseInfoForm.goodsVideo = response.result.goodsVideo;
+         this.baseInfoForm.showGoodsVideo = endpoint + '/' + response.result.goodsVideo;
+         console.log('鏄剧ず鍟嗗搧瑙嗛------------------->', this.baseInfoForm.showGoodsVideo);
+       } catch (e) {
+         console.log('缁勮瑙嗛鍦板潃鍑洪敊浜�')
+       }
+     }
 
       if (
         response.result.wholesaleList &&
@@ -1105,7 +1239,8 @@
       this.renderGoodsDetailSku(response.result.skuList);
 
       /** 鏌ヨ鍝佺墝鍒楄〃 */
-      this.getGoodsBrandList();
+      //todo 绉婚櫎鍝佺墝姒傚康
+      // this.getGoodsBrandList();
 
       /** 鏌ヨ搴楅摵鍟嗗搧鍒嗙被 */
       this.GET_ShopGoodsLabel();
@@ -1125,7 +1260,7 @@
       this.firstData.goodsType &&
       (this.baseInfoForm.goodsType = this.firstData.goodsType);
       /** 鏌ヨ鍟嗗搧鍙傛暟 */
-      this.GET_GoodsParams();
+      // this.GET_GoodsParams();
     },
     // 娓叉煋sku鏁版嵁
     renderGoodsDetailSku(skuList) {
@@ -1780,124 +1915,129 @@
     },
     /**  娣诲姞鍟嗗搧 **/
     save() {
-      this.submitLoading = true;
-      this.$refs["baseInfoForm"].validate((valid) => {
-        if (valid) {
-          if (this.baseInfoForm.salesModel === "WHOLESALE") {
-            for (let i = 0; i < this.wholesaleData.length; i++) {
-              this.checkWholesaleNum(i);
-              this.checkWholesalePrice(i);
-              this.wholesaleData[i].goodsId = this.goodsId;
-            }
-            this.baseInfoForm.wholesaleList = this.wholesaleData;
-          }
-          this.baseInfoForm.goodsId = this.goodsId;
-          let submit = JSON.parse(JSON.stringify(this.baseInfoForm));
-          if (
-            submit.goodsGalleryFiles &&
-            submit.goodsGalleryFiles.length <= 0
-          ) {
-            this.submitLoading = false;
-            this.$Message.error("璇蜂笂浼犲晢鍝佸浘鐗�");
-            return;
-          }
-          if (submit.templateId === "") submit.templateId = 0;
-          let flag = false;
-          let paramValue = "";
-
-          if (flag) {
-            this.$Message.error(paramValue + " 鍙傛暟鍊间笉鑳戒负绌�");
-            this.submitLoading = false;
-            return;
-          }
-
-          if (this.goodsUnitList && !this.goodsUnitList.find(i => i === this.baseInfoForm.goodsUnit)) {
-            submit.goodsUnit = ""
-            this.$Message.error("鍟嗗搧鍗曚綅涓嶅瓨鍦�");
-            this.submitLoading = false;
-            return;
-          }
-          let skuInfoNames = this.skuInfo.map((n) => n.name);
-          submit.skuList = [];
-          let containEmptyImage = false;
-          this.skuTableData.map((sku) => {
-            let skuCopy = {
-              cost: 1,
-              price: sku.price,
-              quantity: sku.quantity,
-              // alertQuantity: sku.alertQuantity,
-              sn: sku.sn,
-              images: [],
-            };
-            if (this.openImage) {
-              this.skuInfo[0].spec_values.forEach(item => {
-                if (!item.images || item.images.length === 0) {
-                  containEmptyImage = true;
-                  return;
-                }
-                if (item.value === sku[this.skuInfo[0].name]) {
-                  skuCopy.images = item.images
-                }
-              })
-
-            }
-            if (sku.weight) {
-              skuCopy.weight = sku.weight;
-            }
-            if (this.baseInfoForm.weight) {
-              skuCopy.weight = this.baseInfoForm.weight;
-            }
-            if (sku.id) {
-              skuCopy.id = sku.id;
-            }
-            for (let skuInfoName of skuInfoNames) {
-              skuCopy[skuInfoName] = sku[skuInfoName];
-            }
-            submit.skuList.push(skuCopy);
-          });
-          if (containEmptyImage) {
-            this.$Message.error("寮�鍚鏍煎浘鐗囷紝鎵�鏈夎鏍煎浘鐗囦笉鑳戒负绌猴紒");
-            this.submitLoading = false;
-            return;
-          }
-          if (submit.goodsGalleryFiles.length > 0) {
-            submit.goodsGalleryList = submit.goodsGalleryFiles.map(
-              (i) => i
-            );
-          }
-          /** 鍙傛暟鏍¢獙 **/
-          /* Object.keys(submit.goodsParamsList).forEach((item) => {
-          });*/
-          submit.release ? (submit.release = true) : (submit.release = false);
-          submit.recommend
-            ? (submit.recommend = true)
-            : (submit.recommend = false);
-          if (this.goodsId) {
-            API_GOODS.editGoods(this.goodsId, submit).then((res) => {
-              if (res.success) {
-                this.submitLoading = false;
-                this.$router.go(-1);
-              } else {
-                this.submitLoading = false;
+      try {
+        this.submitLoading = true;
+        this.$refs["baseInfoForm"].validate((valid) => {
+          if (valid) {
+            if (this.baseInfoForm.salesModel === "WHOLESALE") {
+              for (let i = 0; i < this.wholesaleData.length; i++) {
+                this.checkWholesaleNum(i);
+                this.checkWholesalePrice(i);
+                this.wholesaleData[i].goodsId = this.goodsId;
               }
+              this.baseInfoForm.wholesaleList = this.wholesaleData;
+            }
+            this.baseInfoForm.goodsId = this.goodsId;
+            let submit = JSON.parse(JSON.stringify(this.baseInfoForm));
+            console.log('----------------->鎻愪氦',submit);
+            // if (
+            //   (submit.goodsGalleryFiles &&
+            //     submit.goodsGalleryFiles.length <= 0) && !submit.goodsVideo
+            // ) {
+            //   this.submitLoading = false;
+            //   this.$Message.error("璇蜂笂浼犲晢鍝佸浘鐗囨垨鑰呰棰�");
+            //   return;
+            // }
+            if (submit.templateId === "") submit.templateId = 0;
+            let flag = false;
+            let paramValue = "";
+
+            if (flag) {
+              this.$Message.error(paramValue + " 鍙傛暟鍊间笉鑳戒负绌�");
+              this.submitLoading = false;
+              return;
+            }
+
+            if (this.goodsUnitList && !this.goodsUnitList.find(i => i === this.baseInfoForm.goodsUnit)) {
+              submit.goodsUnit = ""
+              this.$Message.error("鍟嗗搧鍗曚綅涓嶅瓨鍦�");
+              this.submitLoading = false;
+              return;
+            }
+            let skuInfoNames = this.skuInfo.map((n) => n.name);
+            submit.skuList = [];
+            let containEmptyImage = false;
+            this.skuTableData.map((sku) => {
+              let skuCopy = {
+                cost: 1,
+                price: sku.price,
+                quantity: sku.quantity,
+                // alertQuantity: sku.alertQuantity,
+                sn: sku.sn,
+                images: [],
+              };
+              if (this.openImage) {
+                this.skuInfo[0].spec_values.forEach(item => {
+                  if (!item.images || item.images.length === 0) {
+                    containEmptyImage = true;
+                    return;
+                  }
+                  if (item.value === sku[this.skuInfo[0].name]) {
+                    skuCopy.images = item.images
+                  }
+                })
+
+              }
+              if (sku.weight) {
+                skuCopy.weight = sku.weight;
+              }
+              if (this.baseInfoForm.weight) {
+                skuCopy.weight = this.baseInfoForm.weight;
+              }
+              if (sku.id) {
+                skuCopy.id = sku.id;
+              }
+              for (let skuInfoName of skuInfoNames) {
+                skuCopy[skuInfoName] = sku[skuInfoName];
+              }
+              submit.skuList.push(skuCopy);
             });
+            if (containEmptyImage) {
+              this.$Message.error("寮�鍚鏍煎浘鐗囷紝鎵�鏈夎鏍煎浘鐗囦笉鑳戒负绌猴紒");
+              this.submitLoading = false;
+              return;
+            }
+            if (submit.goodsGalleryFiles.length > 0) {
+              submit.goodsGalleryList = submit.goodsGalleryFiles.map(
+                (i) => i
+              );
+            }
+            /** 鍙傛暟鏍¢獙 **/
+            /* Object.keys(submit.goodsParamsList).forEach((item) => {
+            });*/
+            submit.release ? (submit.release = true) : (submit.release = false);
+            submit.recommend
+              ? (submit.recommend = true)
+              : (submit.recommend = false);
+            if (this.goodsId) {
+              API_GOODS.editGoods(this.goodsId, submit).then((res) => {
+                if (res.success) {
+                  this.submitLoading = false;
+                  this.$router.go(-1);
+                } else {
+                  this.submitLoading = false;
+                }
+              });
+            } else {
+              API_GOODS.createGoods(submit).then((res) => {
+                if (res.success) {
+                  this.submitLoading = false;
+                  this.$parent.activestep = 2;
+                  window.scrollTo(0, 0);
+                } else {
+                  this.submitLoading = false;
+                }
+              });
+            }
           } else {
-            API_GOODS.createGoods(submit).then((res) => {
-              if (res.success) {
-                this.submitLoading = false;
-                this.$parent.activestep = 2;
-                window.scrollTo(0, 0);
-              } else {
-                this.submitLoading = false;
-              }
-            });
-          }
-        } else {
-          this.submitLoading = false;
+            this.submitLoading = false;
 
-          this.$Message.error("杩樻湁蹇呭~椤规湭鍋氬鐞嗭紝璇锋鏌ヨ〃鍗�");
-        }
-      });
+            this.$Message.error("杩樻湁蹇呭~椤规湭鍋氬鐞嗭紝璇锋鏌ヨ〃鍗�");
+          }
+        });
+      } finally {
+        this.submitLoading = false;
+      }
     },
     /** 淇濆瓨涓烘ā鏉� */
     saveToDraft() {
@@ -1961,8 +2101,110 @@
         } else if (type === 'localRefresh') {
           this.$Message.error("鍒锋柊澶辫触锛岃閲嶈瘯");
         }
+      }).catch(reason => {
+        console.log("鑾峰彇妯℃澘澶辫触",reason)
       });
-    }
+    },
+    removeVideo(){
+      this.baseInfoForm.showGoodsVideo = null;
+      this.baseInfoForm.goodsVideo = null;
+    },
+    // todo 鏂囦欢涓婁紶
+    async upLoadImg(file) {
+      console.log(file,this.count++);
+      if (this.listImages.length >= 5) {
+        this.$Message.error("鍥剧墖涓婁紶涓嶈兘瓒呰繃5涓�");
+        return;
+      }
+      try {
+        // this.upLoadVideoLoading = true;
+        // 鑾峰彇鏂囦欢涓婁紶涓存椂瀵嗛挜
+        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, // 瑕佷笂浼犵殑鏂囦欢瀵硅薄銆�
+          SliceSize: 1024 * 1024 * 5,
+          onProgress: function (progressData) {
+            console.log('涓婁紶杩涘害锛�', progressData);
+          },
+        });
+        console.log("涓婁紶鎴愬姛", upData)
+        this.$nextTick(() => {
+          this.listImages.push(fileKey);
+          this.showListImages.push(sts.data.endpoint + "/" + fileKey);
+          this.baseInfoForm.goodsGalleryFiles.push(fileKey);
+        })
+
+      } catch (e) {
+        console.log("涓婁紶澶辫触", upData)
+        return false;
+      } finally {
+        // this.upLoadVideoLoading = false;
+
+      }
+      return false;
+    },
+    async upLoadVideo(file) {
+      try {
+        // this.upLoadVideoLoading = true;
+        // 鑾峰彇鏂囦欢涓婁紶涓存椂瀵嗛挜
+        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, // 瑕佷笂浼犵殑鏂囦欢瀵硅薄銆�
+          SliceSize: 1024 * 1024 * 5,
+          onProgress: function (progressData) {
+            console.log('涓婁紶杩涘害锛�', progressData);
+          },
+        });
+        console.log("涓婁紶鎴愬姛", upData)
+        this.$nextTick(() => {
+          this.baseInfoForm.goodsVideo = fileKey;
+          this.baseInfoForm.showGoodsVideo = sts.data.endpoint + "/" + fileKey;
+          this.baseInfoForm.goodsVideo = fileKey;
+        })
+
+      } catch (e) {
+        console.log("涓婁紶澶辫触", upData)
+        return false;
+      } finally {
+        // this.upLoadVideoLoading = false;
+
+      }
+      return false;
+    },
   },
   mounted() {
     this.accessToken = {
@@ -1988,12 +2230,17 @@
         this.baseInfoForm.goodsType = this.firstData.goodsType;
 
 
-        /** 鑾峰彇璇ュ晢鍩庡垎绫讳笅 鍟嗗搧鍙傛暟淇℃伅 */
-        this.GET_GoodsParams();
-        /** 鏌ヨ鍝佺墝鍒楄〃 */
-        this.getGoodsBrandList();
-        /** 鏌ヨ鍒嗙被缁戝畾鐨勮鏍间俊鎭� */
-        this.Get_SkuInfoByCategory(this.categoryId);
+
+
+        if (this.categoryId!=null && this.categoryId!=='') {
+          /** 鑾峰彇璇ュ晢鍩庡垎绫讳笅 鍟嗗搧鍙傛暟淇℃伅 */
+          this.GET_GoodsParams();
+          console.log('鍒嗙被id------------------>',this.categoryId);
+          /** 鏌ヨ鍒嗙被缁戝畾鐨勮鏍间俊鎭� */
+          this.Get_SkuInfoByCategory(this.categoryId);
+          /** 鏌ヨ鍝佺墝鍒楄〃 */
+          this.getGoodsBrandList();
+        }
         // 鑾峰彇鍟嗗搧鍗曚綅
         this.GET_GoodsUnit();
         // 鑾峰彇褰撳墠搴楅摵鍒嗙被
@@ -2044,4 +2291,45 @@
 .refresh-icon {
   margin-left: 10px;
 }
+
+.demo-upload-list {
+  display: inline-block;
+  width: 60px;
+  height: 60px;
+  text-align: center;
+  line-height: 60px;
+  border: 1px solid transparent;
+  border-radius: 4px;
+  overflow: hidden;
+  background: #fff;
+  position: relative;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, .2);
+  margin-right: 4px;
+}
+
+.demo-upload-list img {
+  width: 100%;
+  height: 100%;
+}
+
+.demo-upload-list-cover {
+  display: none;
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background: rgba(0, 0, 0, .6);
+}
+
+.demo-upload-list:hover .demo-upload-list-cover {
+  display: block;
+}
+
+.demo-upload-list-cover i {
+  color: #fff;
+  font-size: 20px;
+  cursor: pointer;
+  margin: 0 2px;
+}
 </style>

--
Gitblit v1.8.0