Преглед на файлове

采美百科,采美文章敏感词校验,视频添加

yuwenjun1997 преди 2 години
родител
ревизия
bbcbcfd041

+ 4 - 0
src/main/java/com/caimei/www/controller/BaseController.java

@@ -25,6 +25,8 @@ public class BaseController {
 	private String coreServer;
 	@Value("${caimei.zplmDomain}")
 	private String zplmDomain;
+	@Value("${aliyunOss.ossBucket}")
+	private String ossBucket;
     /** 打包时间 */
     @Value("${caimei.siteEnv}")
     private String siteEnv;
@@ -60,6 +62,8 @@ public class BaseController {
 		model.addAttribute("coreServer", coreServer);
 		// zplm服务器地址
 		model.addAttribute("zplmDomain", zplmDomain);
+		// 阿里云oss对象存储文件上传目录
+		model.addAttribute("ossBucket", ossBucket);
 		// 搜索热门关键字
 		List<String> searchHotWord = baseService.getSearchHotWord();
 		model.addAttribute("searchHotWord", searchHotWord);

+ 5 - 0
src/main/resources/config/beta/application-beta.yml

@@ -57,6 +57,11 @@ caimei:
   # 正品联盟(临时配置)
   zplmDomain: https://zp-b.caimei365.com
 
+# 阿里云oss配置
+aliyunOss:
+  # 文件上传目录
+  ossBucket: beta/dir
+
 #DFS配置
 fdfs:
   so-timeout: 5000 #上传的超时时间

+ 13 - 7
src/main/resources/config/dev/application-dev.yml

@@ -4,13 +4,13 @@ spring:
   #数据源连接--start
   datasource:
     #本地连接数据库
-#    url: jdbc:mysql://192.168.2.100:3306/caimei?characterEncoding=UTF8&serverTimezone=Asia/Shanghai
-#    username: developer
-#    password: 05bZ/OxTB:X+yd%1
-    #测试连接数据库
-    url: jdbc:mysql://120.79.25.27:3306/caimei?characterEncoding=UTF8&serverTimezone=Asia/Shanghai
+    url: jdbc:mysql://192.168.2.100:3306/caimei?characterEncoding=UTF8&serverTimezone=Asia/Shanghai
     username: developer
-    password: J5p3tgOVazNl4ydf
+    password: 05bZ/OxTB:X+yd%1
+    #测试连接数据库
+#    url: jdbc:mysql://120.79.25.27:3306/caimei?characterEncoding=UTF8&serverTimezone=Asia/Shanghai
+#    username: developer
+#    password: J5p3tgOVazNl4ydf
     #type: com.zaxxer.hikari.HikariDataSource
     hikari:
       minimum-idle: 5
@@ -54,7 +54,8 @@ logging:
 caimei:
   siteEnv: 0 #网站环境,(2:正式环境,1:测试环境,0:开发环境)
   #spiServer: http://192.168.2.68:8008
-  coreServer: https://core-b.caimei365.com
+#  coreServer: https://core-b.caimei365.com
+  coreServer: http://192.168.2.100:18002
 #  coreServer: http://192.168.2.67:18002
 #  coreServer: http://192.168.2.75:18002
   imageDomain: https://img-b.caimei365.com
@@ -63,6 +64,11 @@ caimei:
   # 正品联盟(临时配置)
   zplmDomain: https://zp-b.caimei365.com
 
+# 阿里云oss配置
+aliyunOss:
+  # 文件上传目录
+  ossBucket: dev/dir
+
 #DFS配置
 fdfs:
   so-timeout: 5000 #上传的超时时间

+ 5 - 0
src/main/resources/config/prod/application-prod.yml

@@ -57,6 +57,11 @@ caimei:
   # 正品联盟(临时配置)
   zplmDomain: https://zp.caimei365.com
 
+# 阿里云oss配置
+aliyunOss:
+  # 阿里云 oss 文件上传目录
+  ossBucket: prod/dir
+
 #DFS配置
 fdfs:
   so-timeout: 5000 #上传的超时时间

+ 12 - 0
src/main/resources/static/js/common/serviceapi/supplier.service.js

@@ -41,6 +41,18 @@ var SupplierApi = {
             });
         },
 
+        ShopBaikeProductWordsValidate: function (params, callback) { // 供应商百科商品/仪器信息敏感词校验
+            Http.AjaxService({
+                url: '/user/shop/sensitive/words',
+                type: 'get',
+                data: params,
+                json: false,
+            })
+            .then(function (res) {
+                callback(res);
+            });
+        },
+
         ShopBaikeProductSave: function(params, callback){ // 供应商百科商品/仪器信息保存
             Http.AjaxService({
                 url:'/user/shop/baike/product/save',

+ 9 - 0
src/main/resources/static/js/common/serviceapi/utils.service.js

@@ -4,6 +4,15 @@
  * auther ZHJY
  */
 var PublicApi = {
+        // oss 初始化 (临时凭证获取)
+        fetchOssInitData: function(params){
+            return Http.AjaxService({
+                url:'/user/oss/token',
+                type:'get',
+                data:params,
+                json:false,
+            })
+        },
         uploadimg: function (params, callback) {//供应商添加物流上传图片
             Http.uploadImage({ url:'/tools/image/upload/multi',data:params},callback)
         },

+ 8 - 2
src/main/resources/static/js/encyclopedia/common.js

@@ -204,11 +204,17 @@ function pageScrollObserve(selector) {
         if (scrollFlag) return;
         var scrollTop = $(this).scrollTop();
 
-        if (scrollTop < $(selector).eq(0).offset().top - offset) {
+        var selectorEl = $(selector).eq(0);
+
+        if(selectorEl.length === 0){
+            return;
+        }
+
+        if (scrollTop < selectorEl.eq(0).offset().top - offset) {
             callback(null, -1);
         }
 
-        $(selector).each(function (index, el) {
+        selectorEl.each(function (index, el) {
             var offsetTop = $(el).offset().top - offset;
             var height = $(el).height();
 

+ 75 - 4
src/main/resources/static/js/supplier-center/article/article-edit.js

@@ -83,7 +83,7 @@ var articleEdit = new Vue({
                 {required: true, message: '请选择文章所属分类', trigger: 'change'}
             ]
         },
-
+        formValidate: {}
     },
     watch: {
         chooseLabels: function chooseLabels(newVal) {
@@ -114,6 +114,7 @@ var articleEdit = new Vue({
             this.formData.articleId = articleId;
             this.fetchArticleCatagory(); // 文章id就是修改文章
             this.fetchFormList();
+            this.watchFormData()
         },
         // 获取标签列表和分类列表
         fetchFormList: function fetchFormList() {
@@ -191,11 +192,72 @@ var articleEdit = new Vue({
             var _this = this;
             this.$refs.ruleForm.validate(valide=>{
                 if(!valide) return;
-                _this.save();
+                // _this.save();
+                _this.sensitiveWordsValidate(_this.formData)
             });
         },
+
+        // 监听formData
+        watchFormData: function(){
+            const self = this
+            for (const key in this.formData) {
+                self.$set(self.formValidate, key, '')
+                this.$watch('formData.' + key, function () {
+                    self.formValidate[key] = ''
+                })
+            }
+        },
+
+        // 匹配敏感词
+        matchWords: function(word, validate){
+            var list = []
+            const matcher = word.matchAll(new RegExp(validate, 'g'))
+            var done = false
+            while (!done){
+                const item = matcher.next()
+                done = item.done
+                if(item.value){
+                    list.push(item.value[0])
+                }
+            }
+            return list.join(',')
+        },
+
+        // 敏感词校验
+        sensitiveWordsValidate: function(params){
+            const whiteList = [];
+            const self = this;
+            SupplierApi.ShopBaikeProductWordsValidate({ checkPoint: 1 }, function(res){
+                let flag = true
+                for (const key in params) {
+                    if (!whiteList.includes(key)) {
+                        const target = JSON.stringify(params[key])
+                        const bool = new RegExp(res.data, 'g').test(target)
+                        if (bool) {
+                            console.log(key, true)
+                            const value = self.matchWords(target, res.data)
+                            self.formValidate[key] = value
+                            flag = false
+                        } else {
+                            console.log(key, false)
+                            self.formValidate[key] = ''
+                        }
+                    }
+                }
+                console.log(self.formValidate)
+                if(flag) return self.onReallySave(params)
+                const tip = '当前发布内容存在敏感词,已为您标记在输入框下方,请修改后,再进行保存发布,强行保存发布将会导致审核不通过!'
+                self.$confirm(tip, '提示', { confirmButtonText: '保存', cancelButtonText: '取消' }).then(function(){
+                    self.onReallySave(params)
+                }).catch(function(){
+                    console.log('修改敏感词')
+                    self.socrllToErrorWord() // 滚动到提示处
+                })
+            })
+        },
+
         // 保存接口
-        save: function save() {
+        onReallySave: function onReallySave() {
             var _this = this;
             this.formData.shopId = this.shopId;
             SupplierApi.ArticleSubmitSave(this.formData, function (res) {
@@ -222,7 +284,16 @@ var articleEdit = new Vue({
             localStorage.removeItem('articleId');
             window.open('/supplier/article/list.html', 'supplier-article-list');
             window.close();
-        }
+        },
+
+        socrllToErrorWord(){
+            this.$nextTick(() => {
+                const scrollTop = $('.mint-message').eq(0).parents('.mint-filter').offset().top
+                $('body,html').animate({
+                    scrollTop: scrollTop - $('#globalHead').height() -  60
+                }, 800)
+            })
+        },
     }
 });
 

+ 118 - 24
src/main/resources/static/js/supplier-center/encyclopedia/components.js

@@ -6,18 +6,6 @@ function createFormVideoGroup() {
     let groupId = 0
     return {
         template: fetchCompoentTemplate('form-video-group'),
-        props: {
-            action: {
-                type: String,
-                default: ''
-            },
-            data: {
-                type: Object,
-                default: function () {
-                    return {}
-                }
-            }
-        },
         data() {
             return {
                 fileList: [],
@@ -33,36 +21,142 @@ function createFormVideoGroup() {
                 return this.formList.length < 6
             }
         },
-        watch: {
+        watch:{
             formList: {
-                handler: function (nVal) {
+                deep: true,
+                handler: function(){
                     this.$emit('change', this.formList)
-                },
-                deep: true
+                }
             }
         },
         methods: {
-            onUploadSuccess(response, file, fileList) {
-                this.fileList = []
-                this.formData.videoUrl = response.data
-                console.log(this.formData.videoUrl)
+            validate() {
+                const self = this
+                const validateList = self.formList.map(function (form) {
+                    return self.$refs[form.ref][0].validate()
+                })
+                return {
+                    validator: Promise.all(validateList),
+                    formList: self.formList
+                }
             },
-            onUploadError(err, file, fileList) {
-                this.fileList = []
-                this.formData.videoUrl = ''
+
+            init(data = []){
+                const self = this
+                data.forEach(function(item, index){
+                    self.formList.push({
+                        ref: 'videoGroup' + index,
+                        groupId: index,
+                        videoTitle: item.fileTitle,
+                        videoUrl: item.fileUrl,
+                        percentage: 1,
+                        status: 1,
+                        fileName: item.fileName,
+                        ossName: item.ossName
+                    })
+                })
+            },
+
+            // 选择文件
+            onChooseFile(index){
+                const self = this
+                this.$nextTick(function () {
+                    const input = self.$refs.ossFile
+                    input[index - 1].click()
+                })
             },
+            // 文件变化
+            onFileChange(formData, $event) {
+                const self = this
+                let msg = null
+                let flag = true
+                const fileList = Array.from($event.target.files).map(function (file) {
+                    if(file.size > 1024 * 1024 * 50){
+                        CAIMEI.dialog('请上传50MB以内的视频', false);
+                        flag = false
+                    }
+                    return self.generageRowfile(file, formData.groupId)
+                })
+                if(!flag) return
+                this.onUploadFile(fileList)
+            },
+            // 文件上传成功
+            onUploadSuccess(file, response, url) {
+                file.response = response
+                file.status = 1
+                file.url = url
+                const formData = this.formList.find(function (item) {
+                    return item.groupId === file.groupId
+                })
+                formData.videoUrl = file.url
+                formData.status = file.status
+                formData.ossName = file.uuid
+                formData.fileName = file.fileName
+            },
+            // 文件上传失败
+            onUploadError(file, error) {
+                file.response = error
+                file.status = 0
+                const formData = this.formList.find(function (item) {
+                    return item.groupId === file.groupId
+                })
+                formData.status = file.status
+            },
+            // 文件上传进度条
+            onProgress(file, response){
+                const { p, cpt, res } = response
+                file.percentage = p * 100
+                file.checkpoint = cpt
+                file.response = res
+                file.status = 2
+                const formData = this.formList.find(function (item) {
+                    return item.groupId === file.groupId
+                })
+                formData.status = 2
+                formData.percentage = file.percentage
+            },
+            // 插入视频
             insertOne() {
                 groupId++
                 this.formList.push({
                     ref: 'videoGroup' + groupId,
                     groupId: groupId,
                     videoTitle: '',
-                    videoUrl: ''
+                    videoUrl: '',
+                    percentage: 0,
+                    status: -1,
+                    fileName: '',
+                    ossName: ''
                 })
             },
+            // 删除视频
             removeOne(row) {
                 const index = this.formList.findIndex(item => item.groupId === row.groupId)
                 this.formList.splice(index, 1)
+            },
+            // 上传文件对象
+            generageRowfile(file, groupId) {
+                return {
+                    groupId: groupId,
+                    uuid: uuidv4(),
+                    fileName: file.name,
+                    size: file.size,
+                    type: file.type,
+                    file: file,
+                    percentage: 0,
+                    status: -1, // 0 上次失败 1 上传成功 2 上传中 -1 待上传
+                    response: null,
+                    url: '',
+                    checkpoint: null
+                }
+            },
+            // 上传文件
+            onUploadFile(fileList){
+                upload(fileList, {
+                    success: this.onUploadSuccess,
+                    faild: this.onUploadError,
+                    progress: this.onProgress
+                })
             }
         }
     }

+ 128 - 25
src/main/resources/static/js/supplier-center/encyclopedia/instrument-edit.js

@@ -28,6 +28,14 @@ const app = new Vue({
             }
         }
 
+        var linkValidate = (rule, value, callback) => {
+            if(/[a-zA-z]+:\/\/[^\s]*/.test(value)){
+                callback()
+            }else{
+                callback('url地址不正确')
+            }
+        }
+
         return {
             productId: 0,
             commodityType: 2, // 商品类型 1: 产品  2: 仪器
@@ -84,6 +92,8 @@ const app = new Vue({
                 seoKeyword: '',
                 // 仪器链接
                 productLink: '',
+                // 视频列表
+                videoList: []
             },
             rules: {
                 // 仪器名称
@@ -95,7 +105,9 @@ const app = new Vue({
                 // 仪器图片
                 image: [{required: true, message: '请上传仪器图片', trigger: 'change'}],
                 // 产品链接
-                productLink: [{required: true, message: '产品链接不能为空', trigger: ['change', 'blur']}],
+                productLink: [
+                    {required: true, message: '产品链接不能为空', trigger: ['change', 'blur']},
+                    {validator: linkValidate, trigger: ['blur']}],
                 // 产仪器参数
                 paramList: [{required: true, validator: validateParamList, trigger: 'change'}],
                 // // 认证链接
@@ -131,7 +143,7 @@ const app = new Vue({
                 // // 常见问题
                 // questionList: [{required: true, validator: validateQuestionList, trigger: 'change'}],
                 // // 仪器类别
-                // typeId: [{required: true, message: '请选择仪器类别', trigger: 'change'}],
+                typeId: [{required: true, message: '请选择仪器类别', trigger: 'change'}],
                 // // 仪器状态
                 // status: [{required: true, message: '请选择仪器状态', trigger: 'change'}],
             },
@@ -154,7 +166,10 @@ const app = new Vue({
             marketTimeType: 'year',
             nmpaTimeType: 'year',
             // 空缺数量
-            emptyNum: ''
+            emptyNum: '',
+            formValidate: {},
+
+            videoGroupList: [] // 视频列表
         }
     },
     computed: {
@@ -181,10 +196,13 @@ const app = new Vue({
         this.getTypeList();
         this.watchArrayStatus(['paramList', 'questionList', 'authImageList']);
         this.getProductFormData();
+        this.watchFormData()
     },
 
     methods: {
-
+        onVideoGroupChange: function(data){
+            this.formValidate.videoList = ''
+        },
         // 返回文章列表页面
         handleBack: function handleBack() {
             localStorage.removeItem('target-name');
@@ -193,23 +211,26 @@ const app = new Vue({
         },
         // 保存事件
         handleSave() {
-            this.$refs.ruleForm.validate(valide => {
-                console.log(valide);
-                if (!valide) {
-                    this.socrllToErrorInput()
-                    return;
-                }
-                this.emptyNum = this.validateEmptyParams(this.formData)
-                if( this.emptyNum> 0 && this.formData.status === 1){
-                    this.$confirm('您还剩余' + this.emptyNum + '项未完善,将会导致用户对您产品/仪器的认识度不够,确认是否提交?', '提示', {
-                        confirmButtonText: '是',
-                        cancelButtonText: '否'
-                    }).then(() => {
-                        this.saveFormData()
-                    })
-                } else{
-                    this.saveFormData()
-                }
+            const self = this
+            this.$nextTick(function () {
+                const formVideoGroup = self.$refs.formVideoGroup.validate()
+                self.videoGroupList = formVideoGroup.formList
+                console.log(self.videoGroupList)
+                Promise.all([formVideoGroup.validator, self.$refs.ruleForm.validate()]).then(function () {
+                    self.emptyNum = self.validateEmptyParams(self.formData)
+                    if (self.emptyNum > 0 && self.formData.status === 1) {
+                        self.$confirm('您还剩余' + self.emptyNum + '项未完善,将会导致用户对您产品/仪器的认识度不够,确认是否提交?', '提示', {
+                            confirmButtonText: '是',
+                            cancelButtonText: '否'
+                        }).then(() => {
+                            self.saveFormData()
+                        })
+                    } else {
+                        self.saveFormData()
+                    }
+                }).catch(function () {
+                    self.socrllToErrorInput()
+                })
             })
         },
 
@@ -263,10 +284,7 @@ const app = new Vue({
                 commodityType: this.commodityType,
                 paramList: JSON.stringify(this.paramList),
                 questionList: JSON.stringify(this.questionList),
-                // marketTime: dateFormat(this.formData.marketTime, 'yyyy-MM-dd'),
-                // nmpaTime: dateFormat(this.formData.nmpaTime, 'yyyy-MM-dd'),
                 authImageList: this.authImageList.map(image => (image.response ? image.response.data : image.url)),
-                // displayImageList: this.displayImageList.map(image => (image.response ? image.response.data : image.url))
             };
 
             /* 处理时间 */
@@ -283,6 +301,78 @@ const app = new Vue({
 
             params.emptyNum = this.emptyNum;
 
+            const videoList = this.videoGroupList.map(function (video) {
+                return {fileTitle: video.videoTitle, fileName: video.fileName, ossName: video.ossName}
+            })
+
+            params.videoList = JSON.stringify(videoList)
+
+            this.sensitiveWordsValidate(params)
+
+        },
+
+        // 监听formData
+        watchFormData: function(){
+            const self = this
+            for (const key in this.formData) {
+                self.$set(self.formValidate, key, '')
+                this.$watch('formData.' + key, function () {
+                    self.formValidate[key] = ''
+                })
+            }
+        },
+
+        // 匹配敏感词
+        matchWords: function(word, validate){
+            var list = []
+            const matcher = word.matchAll(new RegExp(validate, 'g'))
+            var done = false
+            while (!done){
+                const item = matcher.next()
+                done = item.done
+                if(item.value){
+                    list.push(item.value[0])
+                }
+            }
+            return list.join(',')
+        },
+
+        // 敏感词校验
+        sensitiveWordsValidate: function(params){
+            console.log(params);
+            const whiteList = [];
+            const self = this;
+            SupplierApi.ShopBaikeProductWordsValidate({ checkPoint: 2 }, function(res){
+                let flag = true
+                for (const key in params) {
+                    if (!whiteList.includes(key)) {
+                        const target = JSON.stringify(params[key])
+                        const bool = new RegExp(res.data, 'g').test(target)
+                        if (bool) {
+                            console.log(key, true)
+                            const value = self.matchWords(target, res.data)
+                            self.formValidate[key] = value
+                            flag = false
+                        } else {
+                            console.log(key, false)
+                            self.formValidate[key] = ''
+                        }
+                    }
+                }
+                console.log(self.formValidate)
+                if(flag) return self.onReallySave(params)
+                const tip = '当前发布内容存在敏感词,已为您标记在输入框下方,请修改后,再进行保存发布,强行保存发布将会导致审核不通过!'
+                self.$confirm(tip, '提示', { confirmButtonText: '保存', cancelButtonText: '取消' }).then(function(){
+                    self.onReallySave(params)
+                }).catch(function(){
+                    console.log('修改敏感词')
+                    self.socrllToErrorWord() // 滚动到提示处
+                })
+            })
+        },
+
+        onReallySave(params){
+            const that = this
             console.log(params);
             SupplierApi.ShopBaikeProductSave(params, function (res) {
                 if (res.code === 0) {
@@ -309,6 +399,7 @@ const app = new Vue({
         },
 
 		initFormData: function(formData){
+            const self = this
 			console.log(formData);
 			// 初始化this.formData
             for (var key in this.formData) {
@@ -335,6 +426,9 @@ const app = new Vue({
             // 处理图片
             this.authImageList = formData.authImageList.map(image => ({ url: image, name: 'authImage'}))
             // this.displayImageList = formData.displayImageList.map(image => ({ url: image, name: 'authImage'}))
+            this.$nextTick(function(){
+                self.$refs.formVideoGroup.init(formData.videoList)
+            })
 		},
 
 
@@ -528,10 +622,19 @@ const app = new Vue({
             })
         },
 
+        socrllToErrorWord(){
+            this.$nextTick(() => {
+                const scrollTop = $('.mint-message').eq(0).parents('.mint-filter').offset().top
+                $('body,html').animate({
+                    scrollTop: scrollTop - $('#globalHead').height() -  60
+                }, 800)
+            })
+        },
+
         // 滚动到必填位置
         socrllToErrorInput(){
             this.$nextTick(() => {
-                const scrollTop = $('.el-form-item__error').eq(0).parent().siblings('.el-form-item__label').offset().top
+                const scrollTop = $('.el-form-item__error').eq(0).parents('.el-form-item__content').offset().top
                 $('body,html').animate({
                     scrollTop: scrollTop - $('#globalHead').height() -  40
                 }, 800)

+ 131 - 25
src/main/resources/static/js/supplier-center/encyclopedia/product-edit.js

@@ -1,6 +1,7 @@
 const Editor = window.createEditorComponent()
 const FormVideoGroup = window.createFormVideoGroup()
 
+Vue.config.devtools = true
 
 const app = new Vue({
     components: {
@@ -29,6 +30,14 @@ const app = new Vue({
             }
         }
 
+        var linkValidate = (rule, value, callback) => {
+            if(/[a-zA-z]+:\/\/[^\s]*/.test(value)){
+                callback()
+            }else{
+                callback('url地址不正确')
+            }
+        }
+
         return {
 
             productId: 0,
@@ -82,6 +91,8 @@ const app = new Vue({
                 seoKeyword: '',
                 // 产品链接
                 productLink: '',
+
+                videoList: []
             },
             rules: {
                 // 产品名称
@@ -95,7 +106,9 @@ const app = new Vue({
                 // 产品参数
                 paramList: [{required: true, validator: validateParamList, trigger: 'change'}],
                 // 产品链接
-                productLink: [{required: true, message: '产品链接不能为空', trigger: ['change', 'blur']}],
+                productLink: [
+                    {required: true, message: '产品链接不能为空', trigger: ['change', 'blur']},
+                    {validator: linkValidate, trigger: ['blur']}],
                 // // 产品优点
                 // advantage: [{required: true, message: '产品优点不能为空', trigger: 'change'}],
                 // // 产品缺点
@@ -150,7 +163,10 @@ const app = new Vue({
             marketTimeType: 'year',
             nmpaTimeType: 'year',
             // 空缺数量
-            emptyNum: ''
+            emptyNum: '',
+            formValidate: {},
+
+            videoGroupList: []
         }
     },
     computed: {
@@ -177,11 +193,13 @@ const app = new Vue({
         this.getTypeList();
         this.watchArrayStatus(['paramList', 'questionList', 'authImageList']);
         this.getProductFormData();
-
+        this.watchFormData()
     },
 
     methods: {
-
+        onVideoGroupChange: function(data){
+            this.formValidate.videoList = ''
+        },
         // 返回文章列表页面
         handleBack: function handleBack() {
             localStorage.removeItem('target-name');
@@ -190,23 +208,26 @@ const app = new Vue({
         },
         // 保存事件
         handleSave() {
-            this.$refs.ruleForm.validate(valide => {
-                console.log(valide);
-                if (!valide) {
-                    this.socrllToErrorInput()
-                    return
-                }
-                this.emptyNum = this.validateEmptyParams(this.formData)
-                if( this.emptyNum> 0 && this.formData.status === 1){
-                    this.$confirm('您还剩余' + this.emptyNum + '项未完善,将会导致用户对您产品/仪器的认识度不够,确认是否提交?', '提示', {
-                        confirmButtonText: '是',
-                        cancelButtonText: '否'
-                    }).then(() => {
-                        this.saveFormData()
-                    })
-                } else{
-                    this.saveFormData()
-                }
+            const self = this
+            this.$nextTick(function () {
+                const formVideoGroup = self.$refs.formVideoGroup.validate()
+                self.videoGroupList = formVideoGroup.formList
+                console.log(self.videoGroupList)
+                Promise.all([formVideoGroup.validator, self.$refs.ruleForm.validate()]).then(function () {
+                    self.emptyNum = self.validateEmptyParams(self.formData)
+                    if (self.emptyNum > 0 && self.formData.status === 1) {
+                        self.$confirm('您还剩余' + self.emptyNum + '项未完善,将会导致用户对您产品/仪器的认识度不够,确认是否提交?', '提示', {
+                            confirmButtonText: '是',
+                            cancelButtonText: '否'
+                        }).then(() => {
+                            self.saveFormData()
+                        })
+                    } else {
+                        self.saveFormData()
+                    }
+                }).catch(function () {
+                    self.socrllToErrorInput()
+                })
             })
         },
         // 校验空参数个数
@@ -257,7 +278,6 @@ const app = new Vue({
         // 保存表单数据
         saveFormData() {
             const that = this;
-
             const params = {
                 ...this.formData,
                 shopId: this.shopId,
@@ -273,19 +293,91 @@ const app = new Vue({
             console.log(params);
 
             /* 处理时间 */
-            if(this.formData.marketTime){
+            if (this.formData.marketTime) {
                 params.marketTime = this.sliceDateStr(this.formData.marketTime, this.marketTimeType)
             }
 
             /* 处理时间 */
-            if(this.formData.nmpaTime){
+            if (this.formData.nmpaTime) {
                 params.nmpaTime = this.sliceDateStr(this.formData.nmpaTime, this.nmpaTimeType)
             }
 
             if (this.productId) params.productId = this.productId;
             params.emptyNum = this.emptyNum;
 
+            const videoList = this.videoGroupList.map(function (video) {
+                return {fileTitle: video.videoTitle, fileName: video.fileName, ossName: video.ossName}
+            })
+
+            params.videoList = JSON.stringify(videoList)
+
+            // this.onReallySave(params)
+            this.sensitiveWordsValidate(params)
+        },
+
+        // 监听formData
+        watchFormData: function(){
+            const self = this
+            for (const key in this.formData) {
+                self.$set(self.formValidate, key, '')
+                this.$watch('formData.' + key, function () {
+                    self.formValidate[key] = ''
+                })
+            }
+        },
+
+        // 匹配敏感词
+        matchWords: function(word, validate){
+            var list = []
+            const matcher = word.matchAll(new RegExp(validate, 'g'))
+            var done = false
+            while (!done){
+                const item = matcher.next()
+                done = item.done
+                if(item.value){
+                    list.push(item.value[0])
+                }
+            }
+            return list.join(',')
+        },
+
+        // 敏感词校验
+        sensitiveWordsValidate: function(params){
             console.log(params);
+            const whiteList = [];
+            const self = this;
+            SupplierApi.ShopBaikeProductWordsValidate({ checkPoint: 2 }, function(res){
+                let flag = true
+                for (const key in params) {
+                    if (!whiteList.includes(key)) {
+                        const target = JSON.stringify(params[key])
+                        const bool = new RegExp(res.data, 'g').test(target)
+                        if (bool) {
+                            console.log(key, true)
+                            const value = self.matchWords(target, res.data)
+                            self.formValidate[key] = value
+                            flag = false
+                        } else {
+                            console.log(key, false)
+                            self.formValidate[key] = ''
+                        }
+                    }
+                }
+                console.log(self.formValidate)
+                if(flag) return self.onReallySave(params)
+                const tip = '当前发布内容存在敏感词,已为您标记在输入框下方,请修改后,再进行保存发布,强行保存发布将会导致审核不通过!'
+                self.$confirm(tip, '提示', { confirmButtonText: '保存', cancelButtonText: '取消' }).then(function(){
+                    self.onReallySave(params)
+                }).catch(function(){
+                    console.log('修改敏感词')
+                    self.socrllToErrorWord() // 滚动到提示处
+                })
+            })
+        },
+
+        // 保存表单到数据库
+        onReallySave(params){
+            const that = this;
             SupplierApi.ShopBaikeProductSave(params, function (res) {
                 if (res.code === 0) {
                     CAIMEI.dialog('保存成功', false);
@@ -311,6 +403,7 @@ const app = new Vue({
         },
 
 		initFormData: function(formData){
+            const self = this
 			console.log(formData);
 			// 初始化this.formData
             for (var key in this.formData) {
@@ -337,6 +430,10 @@ const app = new Vue({
             // 处理图片
             this.authImageList = formData.authImageList.map(image => ({ url: image, name: 'authImage'}))
             this.displayImageList = formData.displayImageList.map(image => ({ url: image, name: 'authImage'}))
+
+            this.$nextTick(function(){
+                self.$refs.formVideoGroup.init(formData.videoList)
+            })
 		},
 
 
@@ -525,10 +622,19 @@ const app = new Vue({
             })
         },
 
+        socrllToErrorWord(){
+            this.$nextTick(() => {
+                const scrollTop = $('.mint-message').eq(0).parents('.mint-filter').offset().top
+                $('body,html').animate({
+                    scrollTop: scrollTop - $('#globalHead').height() -  60
+                }, 800)
+            })
+        },
+
         // 滚动到必填位置
         socrllToErrorInput(){
             this.$nextTick(() => {
-                const scrollTop = $('.el-form-item__error').eq(0).parent().siblings('.el-form-item__label').offset().top
+                const scrollTop = $('.el-form-item__error').eq(0).parents('.el-form-item__content').offset().top
                 $('body,html').animate({
                     scrollTop: scrollTop - $('#globalHead').height() -  40
                 }, 800)

Файловите разлики са ограничени, защото са твърде много
+ 3 - 0
src/main/resources/static/lib/aliyun-oss-sdk-6.17.1.min.js


+ 1 - 0
src/main/resources/static/lib/uuidv4.min.js

@@ -0,0 +1 @@
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).uuidv4=e()}(this,(function(){"use strict";var t,e=new Uint8Array(16);function o(){if(!t&&!(t="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return t(e)}var n=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;function r(t){return"string"==typeof t&&n.test(t)}for(var i=[],u=0;u<256;++u)i.push((u+256).toString(16).substr(1));return function(t,e,n){var u=(t=t||{}).random||(t.rng||o)();if(u[6]=15&u[6]|64,u[8]=63&u[8]|128,e){n=n||0;for(var f=0;f<16;++f)e[n+f]=u[f];return e}return function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,o=(i[t[e+0]]+i[t[e+1]]+i[t[e+2]]+i[t[e+3]]+"-"+i[t[e+4]]+i[t[e+5]]+"-"+i[t[e+6]]+i[t[e+7]]+"-"+i[t[e+8]]+i[t[e+9]]+"-"+i[t[e+10]]+i[t[e+11]]+i[t[e+12]]+i[t[e+13]]+i[t[e+14]]+i[t[e+15]]).toLowerCase();if(!r(o))throw TypeError("Stringified UUID is invalid");return o}(u)}}));

+ 8 - 7
src/main/resources/templates/supplier-center/article/article-edit.html

@@ -13,7 +13,7 @@
     <template th:replace="components/analysis"></template>
 </head>
 <body>
-<input type="hidden" th:value="${coreServer}" id="coreServer">
+<input type="hidden" th:value="${ossBucket}" id="ossBucket">
 <!-- 引用头部 -->
 <template th:replace="components/header"></template>
 
@@ -39,12 +39,12 @@
                             <!-- 标题 -->
                             <el-form-item label="标题" prop="title" class="mint-filter">
                                 <el-input v-model="formData.title" placeholder="请输入文章标题"></el-input>
-                                <div class="mint-message">123</div>
+                                <div class="mint-message" v-if="formValidate.title">{{formValidate.title}}</div>
                             </el-form-item>
                             <!-- 文章标签 -->
                             <el-form-item label="文章标签" prop="label" class="mint-filter">
                                 <el-input v-model="formData.label" placeholder="请输入文章标签"></el-input>
-                                <div class="mint-message">123</div>
+                                <div class="mint-message" v-if="formValidate.label">{{formValidate.label}}</div>
                             </el-form-item>
                             <el-form-item  label="">
                                 <!-- 预选标签列表 -->
@@ -65,12 +65,12 @@
                             <!-- SEO关键词 -->
                             <el-form-item label="SEO关键词" prop="keyword" class="mint-filter">
                                 <el-input v-model="formData.keyword" placeholder="请输入SEO关键词"></el-input>
-                                <div class="mint-message">123</div>
+                                <div class="mint-message" v-if="formValidate.keyword">{{formValidate.keyword}}</div>
                             </el-form-item>
                             <!-- 发布人 -->
                             <el-form-item label="发布人" prop="publisher" class="mint-filter">
                                 <el-input v-model="formData.publisher" placeholder="请填写发布人姓名"></el-input>
-                                <div class="mint-message">123</div>
+                                <div class="mint-message" v-if="formValidate.publisher">{{formValidate.publisher}}</div>
                             </el-form-item>
                             <!-- 来源 -->
                             <el-form-item label="来源" prop="source">
@@ -79,13 +79,13 @@
                             <!-- 推荐语(描述) -->
                             <el-form-item label="推荐语(描述)" prop="recommendContent" class="mint-filter">
                                 <el-input type="textarea" :rows="3" v-model="formData.recommendContent" placeholder="请填写推荐语(描述)"></el-input>
-                                <div class="mint-message">123</div>
+                                <div class="mint-message" v-if="formValidate.recommendContent">{{formValidate.recommendContent}}</div>
                             </el-form-item>
                             <!-- 文章内容 -->
                             <el-form-item label="文章内容" prop="articleContent" class="mint-filter">
                                 <el-input v-model="formData.articleContent" v-show="false"></el-input>
                                 <editor v-model="formData.articleContent" placeholder="请输入文章内容"></editor>
-                                <div class="mint-message">123</div>
+                                <div class="mint-message" v-if="formValidate.articleContent">{{formValidate.articleContent}}</div>
                             </el-form-item>
                             <!-- 文章分类 -->
                             <el-form-item label="文章分类" prop="typeId">
@@ -134,6 +134,7 @@
 <!-- 引入底部 -->
 <template th:replace="components/footer"></template>
 <template th:replace="components/foot-link"></template>
+
 <script charset="utf-8" type="text/javascript" th:src="@{/lib/wangEditor.min.js}"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/lib/element-ui/element-ui.min.js}"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/js/center.js(v=${version})}"></script>

+ 29 - 27
src/main/resources/templates/supplier-center/encyclopedia/instrument-edit.html

@@ -13,7 +13,7 @@
     <template th:replace="components/analysis"></template>
 </head>
 <body>
-<input type="hidden" th:value="${coreServer}" id="coreServer">
+<input type="hidden" th:value="${ossBucket}" id="ossBucket">
 <!-- 引用头部 -->
 <template th:replace="components/header"></template>
 
@@ -40,16 +40,16 @@
                             <div class="cm-big-label"><span class="cm-label">仪器简述</span></div>
                             <el-form-item label="仪器名称(必填)" prop="name" class="mint-filter">
                                 <el-input v-model="formData.name" placeholder="请输入仪器名称"></el-input>
-                                <div class="mint-message">123</div>
+                                <div class="mint-message" v-if="formValidate.name">{{formValidate.name}}</div>
                             </el-form-item>
                             <el-form-item label="仪器别名(必填)" prop="alias" class="mint-filter">
                                 <el-input v-model="formData.alias" placeholder="请输入英文名或其他名称"></el-input>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.alias">{{formValidate.alias}}</div>
                             </el-form-item>
                             <el-form-item label="仪器概述(必填)" prop="discription" class="mint-filter">
                                 <el-input v-model="formData.discription" type="textarea" placeholder="请输入仪器概述"
                                           :rows="5"></el-input>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.discription">{{formValidate.discription}}</div>
                             </el-form-item>
                             <el-form-item label="仪器链接(必填)" prop="productLink">
                                 <el-input v-model="formData.productLink" placeholder="输入您采美商城的商品链接详情,便于用户精准找到"></el-input>
@@ -72,9 +72,10 @@
                             </el-form-item>
 
                             <!-- 相关视频 -->
-                            <div class="form-video-group-list">
+                            <div class="form-video-group-list mint-filter">
                                 <div class="cm-big-label"><span class="cm-label">相关视频(各视频大小不超过50M,最多上传6个)</span></div>
-                                <form-video-group :action="action" ></form-video-group>
+                                <form-video-group ref="formVideoGroup" @change="onVideoGroupChange"></form-video-group>
+                                <div class="mint-message" v-if="formValidate.videoList">{{formValidate.videoList}}</div>
                             </div>
 
                             <!-- 仪器参数 -->
@@ -95,7 +96,7 @@
                                         >&times;</span>
                                     </el-row>
                                 </div>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.paramList">{{formValidate.paramList}}</div>
                             </el-form-item>
 
                             <!-- 正品识别 -->
@@ -124,38 +125,38 @@
                             <el-form-item label="仪器优点" prop="advantage" class="cm-big-label-el mint-filter">
                                 <el-input v-model="formData.advantage" v-show="false"></el-input>
                                 <editor v-model="formData.advantage" placeholder="请输入仪器优点"></editor>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.advantage">{{formValidate.advantage}}</div>
                             </el-form-item>
 
                             <!-- 仪器缺点 -->
                             <el-form-item label="仪器缺点" prop="disadvantage" class="cm-big-label-el mint-filter">
                                 <el-input v-model="formData.disadvantage" v-show="false"></el-input>
                                 <editor v-model="formData.disadvantage" placeholder="请输入仪器缺点"></editor>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.disadvantage">{{formValidate.disadvantage}}</div>
                             </el-form-item>
 
                             <!-- 仪器原理 -->
                             <el-form-item label="仪器原理" prop="principle" class="cm-big-label-el mint-filter">
                                 <el-input v-model="formData.principle" v-show="false"></el-input>
                                 <editor v-model="formData.principle" placeholder="请输入仪器原理"></editor>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.principle">{{formValidate.principle}}</div>
                             </el-form-item>
 
                             <!-- SEO关键词 -->
-                            <el-form-item label="SEO关键字" prop="seo" class="mint-filter">
+                            <el-form-item label="SEO关键字" prop="seoKeyword" class="mint-filter">
                                 <el-input v-model="formData.seoKeyword" placeholder="例如:名称,名称"></el-input>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.seoKeyword">{{formValidate.seoKeyword}}</div>
                             </el-form-item>
 
                             <!-- 仪器档案 -->
                             <div class="cm-big-label"><span class="cm-label">仪器档案</span></div>
                             <el-form-item label="品牌" prop="brand" class="mint-filter">
                                 <el-input v-model="formData.brand" placeholder="请输入仪器品牌"></el-input>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.brand">{{formValidate.brand}}</div>
                             </el-form-item>
                             <el-form-item label="产地" prop="producePlace" class="mint-filter">
                                 <el-input v-model="formData.producePlace" placeholder="请输入仪器产地"></el-input>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.producePlace">{{formValidate.producePlace}}</div>
                             </el-form-item>
                             <el-form-item label="上市时间" prop="marketTime">
                                 <el-date-picker class="max-width" v-model="formData.marketTime" :type="marketTimeType"
@@ -169,7 +170,7 @@
                             </el-form-item>
                             <el-form-item label="供应商" prop="company" class="mint-filter">
                                 <el-input v-model="formData.company" placeholder="请输入供应商"></el-input>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.company">{{formValidate.company}}</div>
                             </el-form-item>
                             <el-form-item label="NMPA认证时间" prop="nmpaTime">
                                 <el-date-picker class="max-width" v-model="formData.nmpaTime" :type="nmpaTimeType"
@@ -202,21 +203,21 @@
                             <el-form-item label="适应症" prop="adaptiveMan" class="cm-big-label-el mint-filter">
                                 <el-input v-model="formData.adaptiveMan" v-show="false"></el-input>
                                 <editor v-model="formData.adaptiveMan" placeholder="请输入适应症"></editor>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.adaptiveMan">{{formValidate.adaptiveMan}}</div>
                             </el-form-item>
 
                             <!-- 不适应人群 -->
                             <el-form-item label="不适应人群" prop="unAdaptiveMan" class="cm-big-label-el mint-filter">
                                 <el-input v-model="formData.unAdaptiveMan" v-show="false"></el-input>
                                 <editor v-model="formData.unAdaptiveMan" placeholder="请输入不适应人群"></editor>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.unAdaptiveMan">{{formValidate.unAdaptiveMan}}</div>
                             </el-form-item>
 
                             <!-- 注意事项 -->
                             <el-form-item label="注意事项" prop="aroundOperation" class="cm-big-label-el mint-filter">
                                 <el-input v-model="formData.aroundOperation" v-show="false"></el-input>
                                 <editor v-model="formData.aroundOperation" placeholder="请输入注意事项"></editor>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.aroundOperation">{{formValidate.aroundOperation}}</div>
                             </el-form-item>
 
                             <!-- 效果展示
@@ -254,7 +255,7 @@
                                         >
                                     </div>
                                 </div>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.questionList">{{formValidate.questionList}}</div>
                             </el-form-item>
 
                             <el-form-item label="仪器类别" prop="typeId" class="cm-big-label-el">
@@ -299,20 +300,17 @@
                     <el-form-item label="标题" prop="videoTitle">
                         <el-input v-model="formData.videoTitle" placeholder="请输入视频标题"></el-input>
                     </el-form-item>
-                    <el-form-item label="" prop="videoUrl">
+                    <el-form-item label="" prop="videoUrl" class="mint-filter">
                         <el-row :gutter="12">
                             <el-col :span="18">
-                                <el-input v-model="formData.videoUrl" disabled placeholder="请选择视频路径"></el-input>
+                                <el-input v-model="formData.videoUrl" disabled placeholder="请选择视频路径" ></el-input>
                             </el-col>
                             <el-col :span="6">
-                                <el-upload :action="action" :auto-upload="true" :show-file-list="false" :multiple="false" :limit="2"
-                                           accept=".mp4" :on-success="onUploadSuccess" :on-error="onUploadError" :file-list="fileList">
-                                    <template #trigger>
-                                        <button class="form-upload-button" @click.prevent>选择文件</button>
-                                    </template>
-                                </el-upload>
+                                <input type="file" v-show="false" ref="ossFile" @change="onFileChange(formData,$event)" accept="video/*">
+                                <button class="form-upload-button" @click.prevent="onChooseFile(index)">选择文件</button>
                             </el-col>
                         </el-row>
+                        <el-progress :percentage="formData.percentage" :show-text="false" v-if="formData.status === 2" style="margin-top: 16px;"></el-progress>
                     </el-form-item>
                 </el-form>
             </div>
@@ -324,10 +322,14 @@
 <template th:replace="components/footer"></template>
 <template th:replace="components/foot-link"></template>
 
+<script charset="utf-8" type="text/javascript" src="/lib/aliyun-oss-sdk-6.17.1.min.js"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/lib/wangEditor.min.js}"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/lib/element-ui/element-ui.min.js}"></script>
+<script charset="utf-8" type="text/javascript" th:src="@{/lib/uuidv4.min.js}"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/js/center.js(v=${version})}"></script>
+<script charset="utf-8" type="text/javascript" th:src="@{/js/common/serviceapi/utils.service.js(v=${version})}"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/js/common/serviceapi/supplier.service.js(v=${version})}"></script>
+<script charset="utf-8" type="text/javascript" th:src="@{/js/oss-upload.js(v=${version})}"></script>
 <script charset="UTF-8" type="text/javascript" th:src="@{/js/supplier-center/encyclopedia/editor-component.js(v=${version})}"></script>
 <script charset="UTF-8" type="text/javascript" th:src="@{/js/supplier-center/encyclopedia/components.js(v=${version})}"></script>
 <script charset="UTF-8" type="text/javascript" th:src="@{/js/supplier-center/encyclopedia/instrument-edit.js(v=${version})}"></script>

+ 50 - 48
src/main/resources/templates/supplier-center/encyclopedia/product-edit.html

@@ -13,7 +13,7 @@
     <template th:replace="components/analysis"></template>
 </head>
 <body>
-<input type="hidden" th:value="${coreServer}" id="coreServer">
+<input type="hidden" th:value="${ossBucket}" id="ossBucket">
 <!-- 引用头部 -->
 <template th:replace="components/header"></template>
 
@@ -40,16 +40,16 @@
                             <div class="cm-big-label"><span class="cm-label">产品简述</span></div>
                             <el-form-item label="产品名称(必填)" prop="name" class="mint-filter">
                                 <el-input v-model="formData.name" placeholder="请输入产品名称"></el-input>
-                                <div class="mint-message">123</div>
+                                <div class="mint-message" v-if="formValidate.name">{{formValidate.name}}</div>
                             </el-form-item>
                             <el-form-item label="产品别名(必填)" prop="alias" class="mint-filter">
                                 <el-input v-model="formData.alias" placeholder="请输入英文名或其他名称"></el-input>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.alias">{{formValidate.alias}}</div>
                             </el-form-item>
                             <el-form-item label="产品概述(必填)" prop="discription" class="mint-filter">
                                 <el-input v-model="formData.discription" type="textarea" placeholder="请输入产品概述"
                                           :rows="5"></el-input>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.discription">{{formValidate.discription}}</div>
                             </el-form-item>
                             <el-form-item label="产品链接(必填)" prop="productLink">
                                 <el-input v-model="formData.productLink" placeholder="输入您采美商城的商品链接详情,便于用户精准找到"></el-input>
@@ -72,9 +72,10 @@
                             </el-form-item>
 
                             <!-- 相关视频 -->
-                            <div class="form-video-group-list">
+                            <div class="form-video-group-list mint-filter">
                                 <div class="cm-big-label"><span class="cm-label">相关视频(各视频大小不超过50M,最多上传6个)</span></div>
-                                <form-video-group :action="action" ></form-video-group>
+                                <form-video-group ref="formVideoGroup" @change="onVideoGroupChange"></form-video-group>
+                                <div class="mint-message" v-if="formValidate.videoList">{{formValidate.videoList}}</div>
                             </div>
 
                             <!-- 产品参数 -->
@@ -96,45 +97,45 @@
                                         >
                                     </el-row>
                                 </div>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.paramList">{{formValidate.paramList}}</div>
                             </el-form-item>
 
                             <!-- 产品优点 -->
                             <el-form-item label="产品优点" prop="advantage" class="cm-big-label-el mint-filter">
                                 <el-input v-model="formData.advantage" v-show="false"></el-input>
                                 <editor v-model="formData.advantage" placeholder="请输入产品优点"></editor>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.advantage">{{formValidate.advantage}}</div>
                             </el-form-item>
 
                             <!-- 产品缺点 -->
                             <el-form-item label="产品缺点" prop="disadvantage" class="cm-big-label-el mint-filter">
                                 <el-input v-model="formData.disadvantage" v-show="false"></el-input>
                                 <editor v-model="formData.disadvantage" placeholder="请输入产品缺点"></editor>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.disadvantage">{{formValidate.disadvantage}}</div>
                             </el-form-item>
 
                             <!-- 产品原理 -->
                             <el-form-item label="产品原理" prop="principle" class="cm-big-label-el mint-filter">
                                 <el-input v-model="formData.principle" v-show="false"></el-input>
                                 <editor v-model="formData.principle" placeholder="请输入产品原理"></editor>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.principle">{{formValidate.principle}}</div>
                             </el-form-item>
 
                             <!-- SEO关键词 -->
-                            <el-form-item label="SEO关键字" prop="seo" class="mint-filter">
+                            <el-form-item label="SEO关键字" prop="seoKeyword" class="mint-filter">
                                 <el-input v-model="formData.seoKeyword" placeholder="例如:名称,名称"></el-input>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.seoKeyword">{{formValidate.seoKeyword}}</div>
                             </el-form-item>
 
                             <!-- 产品档案 -->
                             <div class="cm-big-label"><span class="cm-label">产品档案</span></div>
                             <el-form-item label="品牌" prop="brand" class="mint-filter">
                                 <el-input v-model="formData.brand" placeholder="请输入产品品牌"></el-input>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.brand">{{formValidate.brand}}</div>
                             </el-form-item>
                             <el-form-item label="产地" prop="producePlace" class="mint-filter">
                                 <el-input v-model="formData.producePlace" placeholder="请输入产品产地"></el-input>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.producePlace">{{formValidate.producePlace}}</div>
                             </el-form-item>
                             <el-form-item label="上市时间" prop="marketTime">
                                 <el-date-picker class="max-width" v-model="formData.marketTime" :type="marketTimeType"
@@ -148,7 +149,7 @@
                             </el-form-item>
                             <el-form-item label="供应商" prop="company" class="mint-filter">
                                 <el-input v-model="formData.company" placeholder="请输入供应商"></el-input>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.company">{{formValidate.company}}</div>
                             </el-form-item>
                             <el-form-item label="NMPA认证时间" prop="nmpaTime">
                                 <el-date-picker class="max-width" v-model="formData.nmpaTime" :type="nmpaTimeType"
@@ -181,21 +182,21 @@
                             <el-form-item label="适应证" prop="adaptiveMan" class="cm-big-label-el mint-filter">
                                 <el-input v-model="formData.adaptiveMan" v-show="false"></el-input>
                                 <editor v-model="formData.adaptiveMan" placeholder="请输入适应证"></editor>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.adaptiveMan">{{formValidate.adaptiveMan}}</div>
                             </el-form-item>
 
                             <!-- 不适应人群 -->
                             <el-form-item label="不适应人群" prop="unAdaptiveMan" class="cm-big-label-el mint-filter">
                                 <el-input v-model="formData.unAdaptiveMan" v-show="false"></el-input>
                                 <editor v-model="formData.unAdaptiveMan" placeholder="请输入不适应人群"></editor>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.unAdaptiveMan">{{formValidate.unAdaptiveMan}}</div>
                             </el-form-item>
 
                             <!-- 注意事项 -->
                             <el-form-item label="注意事项" prop="aroundOperation" class="cm-big-label-el mint-filter">
                                 <el-input v-model="formData.aroundOperation" v-show="false"></el-input>
                                 <editor v-model="formData.aroundOperation" placeholder="请输入注意事项"></editor>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.aroundOperation">{{formValidate.aroundOperation}}</div>
                             </el-form-item>
 
                             <!-- 常见问题 -->
@@ -214,7 +215,7 @@
                                         >&times;</span>
                                     </div>
                                 </div>
-                                <div class="mint-message"></div>
+                                <div class="mint-message" v-if="formValidate.questionList">{{formValidate.questionList}}</div>
                             </el-form-item>
 
                             <el-form-item label="产品类别" prop="typeId" class="cm-big-label-el" props="typeId">
@@ -249,35 +250,32 @@
 </div>
 
 <script id="form-video-group" type="text/html">
-<div class="form-video-group" :style="{ paddingBottom:formList.length === 0 ? '35px' : 0  }">
-    <span class="add-one" @click="insertOne" v-if="addFlag">添加视频</span>
-    <template v-for="(formData,index) in formList">
-        <div class="form-video-section">
-            <span class="remove-btn" @click="removeOne(formData)">删除</span>
-            <div class="form-video-number">视频{{++index}}</div>
-            <el-form :model="formData" :rules="rules" :ref="formData.ref">
-                <el-form-item label="标题" prop="videoTitle">
-                    <el-input v-model="formData.videoTitle" placeholder="请输入视频标题"></el-input>
-                </el-form-item>
-                <el-form-item label="" prop="videoUrl">
-                    <el-row :gutter="12">
-                        <el-col :span="18">
-                            <el-input v-model="formData.videoUrl" disabled placeholder="请选择视频路径"></el-input>
-                        </el-col>
-                        <el-col :span="6">
-                            <el-upload :action="action" :auto-upload="true" :show-file-list="false" :multiple="false" :limit="2"
-                                       accept=".mp4" :on-success="onUploadSuccess" :on-error="onUploadError" :file-list="fileList">
-                                <template #trigger>
-                                    <button class="form-upload-button" @click.prevent>选择文件</button>
-                                </template>
-                            </el-upload>
-                        </el-col>
-                    </el-row>
-                </el-form-item>
-            </el-form>
-        </div>
-    </template>
-</div>
+    <div class="form-video-group" :style="{ paddingBottom:formList.length === 0 ? '35px' : 0  }">
+        <span class="add-one" @click="insertOne" v-if="addFlag">添加视频</span>
+        <template v-for="(formData,index) in formList">
+            <div class="form-video-section">
+                <span class="remove-btn" @click="removeOne(formData)">删除</span>
+                <div class="form-video-number">视频{{++index}}</div>
+                <el-form :model="formData" :rules="rules" :ref="formData.ref">
+                    <el-form-item label="标题" prop="videoTitle">
+                        <el-input v-model="formData.videoTitle" placeholder="请输入视频标题"></el-input>
+                    </el-form-item>
+                    <el-form-item label="" prop="videoUrl" class="mint-filter">
+                        <el-row :gutter="12">
+                            <el-col :span="18">
+                                <el-input v-model="formData.videoUrl" disabled placeholder="请选择视频路径" ></el-input>
+                            </el-col>
+                            <el-col :span="6">
+                                <input type="file" v-show="false" ref="ossFile" @change="onFileChange(formData,$event)" accept="video/*">
+                                <button class="form-upload-button" @click.prevent="onChooseFile(index)">选择文件</button>
+                            </el-col>
+                        </el-row>
+                        <el-progress :percentage="formData.percentage" :show-text="false" v-if="formData.status === 2" style="margin-top: 16px;"></el-progress>
+                    </el-form-item>
+                </el-form>
+            </div>
+        </template>
+    </div>
 </script>
 
 
@@ -287,10 +285,14 @@
 <template th:replace="components/footer"></template>
 <template th:replace="components/foot-link"></template>
 
+<script charset="utf-8" type="text/javascript" src="/lib/aliyun-oss-sdk-6.17.1.min.js"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/lib/wangEditor.min.js}"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/lib/element-ui/element-ui.min.js}"></script>
+<script charset="utf-8" type="text/javascript" th:src="@{/lib/uuidv4.min.js}"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/js/center.js(v=${version})}"></script>
+<script charset="utf-8" type="text/javascript" th:src="@{/js/common/serviceapi/utils.service.js(v=${version})}"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/js/common/serviceapi/supplier.service.js(v=${version})}"></script>
+<script charset="utf-8" type="text/javascript" th:src="@{/js/oss-upload.js(v=${version})}"></script>
 <script charset="UTF-8" type="text/javascript" th:src="@{/js/supplier-center/encyclopedia/editor-component.js(v=${version})}"></script>
 <script charset="UTF-8" type="text/javascript" th:src="@{/js/supplier-center/encyclopedia/components.js(v=${version})}"></script>
 <script charset="UTF-8" type="text/javascript" th:src="@{/js/supplier-center/encyclopedia/product-edit.js(v=${version})}"></script>

Някои файлове не бяха показани, защото твърде много файлове са промени