Explorar el Código

供应商采美百科编辑页面重构

喻文俊 hace 3 años
padre
commit
64e53cc859

+ 202 - 0
src/main/resources/static/css/supplier-center/encyclopedia/edit-page-style.css

@@ -0,0 +1,202 @@
+.cm-label {
+    margin-right: 24px;
+}
+
+.cm-label em {
+    color: #f56c6c;
+    margin-right: 4px;
+}
+
+.el-form-item__label, .cm-label{
+    color: #666;
+}
+
+.cm-big-label .cm-label,
+.cm-big-label-el .el-form-item__label{
+    font-weight: bold;
+    color: #333;
+}
+
+.max-width {
+    width: 100% !important;
+}
+
+.edit-page .row {
+    box-sizing: border-box;
+    padding: 24px 0;
+    background: #FFFFFF;
+    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.07)
+}
+
+.edit-page .top-tip {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    height: 60px;
+    text-align: center;
+    font-size: 12px;
+    line-height: 20px;
+    color: #E15616;
+    background: linear-gradient(90deg, #FFFFFF 0%, rgba(225, 86, 22, 0.1) 50%, #FFFFFF 100%)
+}
+
+
+.valide-form {
+    width: 500px;
+    margin: 0 auto;
+    margin-top: 40px;
+}
+
+.valide-form .btns{
+	display: flex;
+	justify-content: space-between;
+}
+
+.valide-form .btn {
+	width: 232px;
+	height: 50px;
+	text-align: center;
+	line-height: 50px;
+	font-size: 18px;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+	cursor: pointer
+}
+
+.valide-form .btn.break {
+	background: #FFE6DC;
+	border: 1px solid #E15616;
+	border-radius: 2px;
+	color: #E15616
+}
+
+.valide-form .btn.submit {
+	background: #E15616;
+	color: #FFFFFF
+}
+
+
+.cover-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+}
+
+.cover-uploader .el-upload:hover {
+    border-color: #409eff;
+}
+
+.cover-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 178px;
+    height: 178px;
+    line-height: 178px;
+    text-align: center;
+}
+
+.cover {
+    position: relative;
+    width: 178px;
+    height: 178px;
+    display: block;
+}
+
+.cover-uploader .el-upload::after {
+    content: '更换图片';
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 999;
+    background: rgba(0, 0, 0, 0.4);
+    color: #eee;
+    opacity: 0;
+    transition: all 0.2s;
+}
+
+.cover-uploader .el-upload:hover::after {
+    opacity: 1;
+}
+
+.hide-upload .el-upload {
+    display: none;
+}
+
+.form-params-group,
+.form-question-group {
+    position: relative;
+}
+
+.form-params-group .add-one,
+.form-question-group .add-one {
+    position: absolute;
+    right: 0;
+    top: -40px;
+    width: 50px;
+    height: 30px;
+    font-size: 12px;
+    line-height: 30px;
+    color: #e15616;
+    cursor: pointer;
+    text-decoration: underline;
+}
+
+.form-params-group .form-params-group-row {
+    position: relative;
+    margin-bottom: 12px;
+}
+
+.form-params-group .form-params-group-row:last-of-type {
+    margin-bottom: 0;
+}
+
+.form-params-group .form-params-group-row .remove,
+.form-question-group .form-question-group-row .remove {
+    position: absolute;
+    top: 0;
+    right: 4px;
+    width: 20px;
+    height: 20px;
+    background: #f94b4b;
+    opacity: 1;
+    border-radius: 0px 2px 0px 2px;
+    text-align: center;
+    line-height: 20px;
+    color: #fff;
+    cursor: pointer;
+    border-radius: 4px;
+}
+
+.form-question-group .form-question-group-row {
+    position: relative;
+    margin-bottom: 24px;
+}
+
+.form-question-group .form-question-group-row:last-of-type {
+    margin-bottom: 0;
+}
+
+.form-question-group .add-one {
+    top: -50px;
+}
+
+.form-question-group .form-question-group-row .remove {
+    right: 0;
+    top: 40px;
+}
+
+.el-upload-list--picture-card .el-upload-list__item,.el-upload--picture-card{
+    width: 110px;
+    height: 110px;
+}
+
+.el-upload--picture-card{
+    line-height: 120px;
+}

+ 99 - 0
src/main/resources/static/js/supplier-center/encyclopedia/editor-component.js

@@ -0,0 +1,99 @@
+//富文本框封装
+function createEditorComponent() {
+	window.editorCount = 0
+	const Editor = {
+		render: function render(h) {
+			return h('div', { class: { cm: true, editor: true }, attrs: { id: this.editorId } })
+		},
+		model: {
+			prop: 'value',
+			event: 'input',
+		},
+		props: {
+			value: {
+				type: String,
+				default: '',
+			},
+			placeholder: {
+				type: String,
+				default: '',
+			},
+			defaultTxt: {
+				type: String,
+				default: '',
+			},
+		},
+		data() {
+			return {
+				editorId: '',
+				editor: null,
+			}
+		},
+		watch: {
+			value(nVal, oldVal) {
+				if (nVal === oldVal) return
+				this.editor && this.editor.txt.html(nVal)
+			},
+		},
+
+		created: function created() {
+			window.editorCount++
+			this.editorId = 'editorId-' + window.editorCount
+			this.$nextTick(function () {
+				this.createEditor()
+			})
+		},
+		beforeDestroy: function beforeDestroy() {
+			this.editor.destroy()
+			this.editor = null
+		},
+		methods: {
+			// 创建编辑器
+			createEditor: function createEditor() {
+				const E = window.wangEditor
+				this.editor = new E('#' + this.editorId)
+				this.initEditorOptions()
+				this.editor.create()
+				this.editor.txt.html(this.value)
+			},
+			// 富文本框配置
+			initEditorOptions: function initEditorOptions() {
+				this.editor.config.zIndex = 333
+				this.editor.config.height = 200
+				this.editor.config.uploadImgMaxSize = 2 * 1024 * 1024
+				this.editor.config.uploadImgMaxLength = 9 // 一次最多上传 5 个图片
+				this.editor.config.placeholder = this.placeholder
+				var that = this
+				// 监听输入事件
+				this.editor.config.onchange = function (newHtml) {
+					that.$emit('input', newHtml)
+				}
+
+				this.editor.config.customUploadImg = function (resultFiles, insertImgFn) {
+					that.$emit('choose-image', resultFiles)
+					resultFiles.forEach(function (file) {
+						// resultFiles 是 input 中选中的文件列表
+						// insertImgFn 是获取图片 url 后,插入到编辑器的方法
+						that.uploadImage(file).then(function (res) {
+							insertImgFn(res)
+						})
+					})
+				}
+			},
+			// 上传图片
+			uploadImage: function uploadImage(file) {
+				var formData = new FormData()
+				formData.append('file', file)
+				return new Promise(function (resolve, reject) {
+					PublicApi.uploadimg(formData, function (res) {
+						if (res.code === 0) {
+							resolve(res.data)
+						}
+						reject()
+					})
+				})
+			},
+		},
+	}
+	return Editor
+}

+ 369 - 483
src/main/resources/static/js/supplier-center/encyclopedia/instrument-edit.js

@@ -1,372 +1,192 @@
-const Radio = createnRadio();
-const Select = createSelect();
-const Option = createOption();
-const UploadImage = createUploadImage();
-const Editor = createEditorComponent();
-const InputGroup = createInputGroup();
-const QuestionGroup = createQuestionGroup();
-
-new Vue({
-    el: '#productEdit',
-    mixins: [validFormMixin],
+const Editor = window.createEditorComponent()
+
+const app = new Vue({
     components: {
-        'cm-radio': Radio,
-        'cm-select': Select,
-        'cm-option': Option,
-        'cm-upload-image': UploadImage,
-        'cm-editor': Editor,
-        'cm-input-group': InputGroup,
-        'cm-question-group': QuestionGroup
+        Editor,
     },
-    data: {
-        // 商品类型 1: 产品  2: 仪器
-        productId: 0,
-        commodityType: 2,
-        shopId: GLOBAL_SHOP_ID,
-        formData: {
-            // 产品名称
-            name: '',
-            // 产品别名
-            alias: '',
-            // 产品概述
-            discription: '',
-            // 产品图片
-            image: '',
-            // 认证链接
-            authLink: '',
-            // 认证二维码
-            authQrCode: '',
-            // 产品参数
-            paramList: [],
-            // 产品优点
-            advantage: '',
-            // 产品缺点
-            disadvantage: '',
-            // 产品原理
-            principle: '',
-            // 品牌
-            brand: '',
-            // 产地
-            producePlace: '',
-            // 上市时间
-            marketTime: '',
-            // 公司/厂商
-            company: '',
-            // NMPA认证时间
-            nmpaTime: '',
-            // 产品认证
+
+    data() {
+        var validateQuestionList = (rule, value, callback) => {
+            if (!value) {
+                callback(new Error('问答列表不能为空'))
+            } else if (value < this.minLimitQuestions) {
+                callback(new Error(`请填写至少${this.minLimitQuestions}条问答`))
+            } else {
+                callback();
+            }
+        }
+
+        var validateParamList = (rule, value, callback) => {
+            if (!value) {
+                callback(new Error('参数列表不能为空'))
+            } else if (value < this.minLimitParams) {
+                callback(new Error(`请填写至少${this.minLimitParams}条参数`))
+            } else {
+                callback();
+            }
+        }
+
+        return {
+
+            productId: 0,
+            commodityType: 2, // 商品类型 1: 产品  2: 仪器
+            shopId: GLOBAL_SHOP_ID,
+
+            action: $('#coreServer').val() + '/tools/image/upload/multi',
+
+            formData: {
+                // 仪器名称
+                name: '',
+                // 仪器别名
+                alias: '',
+                // 仪器概述
+                discription: '',
+                // 仪器图片
+                image: '',
+                // 认证链接
+                authLink: '',
+                // 认证二维码
+                authQrCode: '',
+                // 仪器参数
+                paramList: '',
+                // 仪器优点
+                advantage: '',
+                // 仪器缺点
+                disadvantage: '',
+                // 仪器原理
+                principle: '',
+                // 品牌
+                brand: '',
+                // 产地
+                producePlace: '',
+                // 上市时间
+                marketTime: '',
+                // 公司/厂商
+                company: '',
+                // NMPA认证时间
+                nmpaTime: '',
+                // 仪器认证
+                authImageList: '',
+                // 适应人群
+                adaptiveMan: '',
+                // 不适应人群
+                unAdaptiveMan: '',
+                // 术前术后
+                aroundOperation: '',
+                // 效果展示图片列表
+                displayImageList: '',
+                // 常见问题
+                questionList: '',
+                // 仪器类别
+                typeId: '',
+                // 仪器状态
+                status: 1,
+            },
+            rules: {
+                // 仪器名称
+                name: [{required: true, message: '仪器名称不能为空', trigger: ['change', 'blur']}],
+                // 仪器别名
+                alias: [{required: true, message: '仪器别名不能为空', trigger: ['change', 'blur']}],
+                // 仪器概述
+                discription: [{required: true, message: '仪器概述不能为空', trigger: ['change', 'blur']}],
+                // 仪器图片
+                image: [{required: true, message: '请上传仪器图片', trigger: 'change'}],
+                // 认证链接
+                authLink: [{required: true, message: '请输入认证链接', trigger: ['change', 'blur']}],
+                // 认证二维码
+                authQrCode: [{required: true, message: '请上传证二维码', trigger: 'change'}],
+                // 产仪器参数
+                paramList: [{required: true, validator: validateParamList, trigger: 'change'}],
+                // 仪器优点
+                advantage: [{required: true, message: '仪器优点不能为空', trigger: 'change'}],
+                // 仪器缺点
+                disadvantage: [{required: true, message: '仪器缺点不能为空', trigger: 'change'}],
+                // 仪器原理
+                principle: [{required: true, message: '仪器原理不能为空', trigger: 'change'}],
+                // 品牌
+                brand: [{required: true, message: '请输入仪器品牌', trigger: ['change', 'blur']}],
+                // 产地
+                producePlace: [{required: true, message: '仪器产地不能为空', trigger: ['change', 'blur']}],
+                // 上市时间
+                marketTime: [{required: true, message: '请填写上市时间', trigger: 'change'}],
+                // 公司/厂商
+                company: [{required: true, message: '公司/厂商不能为空', trigger: ['change', 'blur']}],
+                // NMPA认证时间
+                nmpaTime: [{required: true, message: '请填写NMPA认证时间', trigger: 'change'}],
+                // 仪器认证
+                authImageList: [{required: true, message: '请上传仪器认证图片', trigger: 'change'}],
+                // 适应人群
+                adaptiveMan: [{required: true, message: '适应人群不能为空', trigger: 'change'}],
+                // 不适应人群
+                unAdaptiveMan: [{required: true, message: '不适应人群不能为空', trigger: 'change'}],
+                // 术前术后
+                aroundOperation: [{required: true, message: '术前术后不能为空', trigger: 'change'}],
+                // 效果展示图片列表
+                displayImageList: [{required: true, message: '请上传效果展示图片', trigger: 'change'}],
+                // 常见问题
+                questionList: [{required: true, validator: validateQuestionList, trigger: 'change'}],
+                // 仪器类别
+                typeId: [{required: true, message: '请选择仪器类别', trigger: 'change'}],
+                // 仪器状态
+                status: [{required: true, message: '请选择仪器状态', trigger: 'change'}],
+            },
+
+            // 仪器类别列表
+            typeList: [],
+
+            // 仪器参数
+            // paramList: [],
+            paramEmptyList: [], // 占位
+            minLimitParams: 2,
+            // 常见问题
+            questionEmptyList: [], // 占位
+            minLimitQuestions: 2,
+            // 仪器认证
             authImageList: [],
-            // 适应人群
-            adaptiveMan: '',
-            // 不适应人群
-            unAdaptiveMan: '',
-            // 术前术后
-            aroundOperation: '',
             // 效果展示图片列表
-            displayImageList: [],
-            // 常见问题
-            questionList: [],
-            // 产品类别
-            typeId: '',
-            // 产品状态
-            status: 1,
-        },
-        // 预览图片列表
-        imageList: [],
-        authImageList: [],
-        displayImageList: [],
-        authQrCodeList: [],
-        // 产品分类
-        typeList: [],
-
-        // 产品参数表单数据
-        paramsPlaceholderList: [{
-            label: '例如:名牌',
-            value: '请输入名牌信息'
-        }],
-        paramsMinLimit: 2,
-        paramskeyMap: {
-            key: 'name',
-            value: 'content'
-        },
-
-        // 问题数据表单列表
-        questionPlaceHolderList: [{
-            label: '请输入问题',
-            value: '请输入回答'
-        }],
-        questionMinLimit: 2,
-        questionkeyMap: {
-            key: 'question',
-            value: 'answer'
+            displayImageList: [],  // 初始化列表
+            dialogVisible: false,
+            dialogImageUrl: '',
+        }
+    },
+    computed: {
+        // 仪器参数
+        paramList() {
+            const filter = this.paramEmptyList.filter(param => param.content !== '' && param.name !== '')
+            if (filter.length > 0) return filter.map(param => ({name: param.name, content: param.content}))
+            return []
         },
-        // 表单校验规则
-        rules: {
-            // 产品名称
-            name: [{
-                type: 'string',
-                required: true,
-                message: '名称不能为空',
-                trigger: ['blur','change']
-            }],
-            // 产品别名
-            alias: [{
-                type: 'string',
-                required: true,
-                message: '别名不能为空',
-                trigger: ['blur','change']
-            }],
-            // 产品概述
-            discription: [{
-                type: 'string',
-                required: true,
-                message: '概述不能为空',
-                trigger: ['blur','change']
-            }],
-            // 产品图片
-            image: [{
-                type: 'string',
-                required: true,
-                message: '图片不能为空',
-                trigger: 'change'
-            }],
-            // 认证链接
-            authLink: [{
-                type: 'string',
-                required: true,
-                message: '认证链接不能为空',
-                trigger: ['change', 'blur']
-            }],
-            // 认证二维码
-            authQrCode: [{
-                type: 'string',
-                required: true,
-                message: '认证二维码不能为空',
-                trigger: 'change'
-            }],
-            // 产品参数
-            paramList: [{
-                type: 'array',
-                required: true,
-                message: '参数信息不能为空',
-                trigger: ['change', 'blur'],
-                valid: ['name', 'content']
-            }],
-            // 产品优点
-            advantage: [{
-                type: 'string',
-                required: true,
-                message: '优点不能为空',
-                trigger: 'change'
-            }],
-            // 产品缺点
-            disadvantage: [{
-                type: 'string',
-                required: true,
-                message: '缺点不能为空',
-                trigger: 'change'
-            }],
-            // 产品原理
-            principle: [{
-                type: 'string',
-                required: true,
-                message: '原理不能为空',
-                trigger: 'change'
-            }],
-            // 品牌
-            brand: [{
-                type: 'string',
-                required: true,
-                message: '品牌不能为空',
-                trigger: ['change','blur']
-            }],
-            // 产地
-            producePlace: [{
-                type: 'string',
-                required: true,
-                message: '产地不能为空',
-                trigger: ['change','blur']
-            }],
-            // 上市时间
-            marketTime: [{
-                type: 'string',
-                required: true,
-                message: '上市时间不能为空',
-                trigger: ['change','blur']
-            }],
-            // 公司/厂商
-            company: [{
-                type: 'string',
-                required: true,
-                message: '公司/厂商不能为空',
-                trigger: ['change','blur']
-            }],
-            // NMPA认证时间
-            nmpaTime: [{
-                type: 'string',
-                required: true,
-                message: 'NMPA认证时间不能为空',
-                trigger: ['change','blur']
-            }],
-            // 产品认证
-            authImageList: [{
-                type: 'array',
-                required: true,
-                message: '仪器认证图片不能为空',
-                trigger: 'change'
-            }],
-            // 适应人群
-            adaptiveMan: [{
-                type: 'string',
-                required: true,
-                message: '适应人群不能为空',
-                trigger: 'change'
-            }],
-            // 不适应人群
-            unAdaptiveMan: [{
-                type: 'string',
-                required: true,
-                message: '不适应人群不能为空',
-                trigger: 'change'
-            }],
-            // 术前术后
-            aroundOperation: [{
-                type: 'string',
-                required: true,
-                message: '术前术后内容不能为空',
-                trigger: 'change'
-            }],
-            // 效果展示
-            displayImageList: [{
-                type: 'array',
-                required: true,
-                message: '效果展示图片不能为空',
-                trigger: 'change'
-            }],
-            // 常见问题
-            questionList: [{
-                type: 'array',
-                required: true,
-                message: '常见问题不能为空',
-                trigger: ['change','blur'],
-                valid: ['question', 'answer']
-            }],
-            // 产品类别
-            typeId: [{
-                type: 'number',
-                required: true,
-                message: '仪器类别不能为空',
-                trigger: 'change'
-            }],
-            // 产品状态
-            status: [{
-               type: 'number',
-                required: true,
-                message: '状态不能为空',
-                trigger: 'change'
-            }],
+        // 常见问题
+        questionList() {
+            const filter = this.questionEmptyList.filter(item => item.question !== '' && item.answer !== '')
+            if (filter.length > 0) return filter.map(item => ({question: item.question, answer: item.answer}))
+            return []
         },
     },
     created() {
         this.getTypeList();
+        this.watchArrayStatus(['paramList', 'questionList', 'authImageList', 'displayImageList']);
         this.getProductFormData();
-        this.resetQuestionListLimit();
-        this.resetParamsListLimit();
-        this.registerForm(this.formData, this.rules);
-    },
-    mounted: function () {
-        $('.navLayout').find('.navList').removeClass("on").find('.con').hide().find('a').removeClass("on");
-        $('.navLayout').find('.navList').eq(3).addClass("on").find('.con').show().find('a').eq(1).addClass("on");
+
     },
-    methods: {
-        // 获取分类列表
-        getTypeList() {
-            const that = this;
-            SupplierApi.ShopBaikeProductTypeList({commodityType: this.commodityType}, function (res) {
-                that.typeList = res.data;
-                console.log(res);
-            })
-        },
 
-        // 初始化表单数据
-        initFormData(formData){
-            console.log(formData);
-            // 初始化this.formData
-            for (var key in this.formData) {
-                if (formData.hasOwnProperty(key)) {
-                    // this.$set(this.formData, key, formData[key]);
-                    this.formData[key] = formData[key];
-                }
-            }
+    methods: {
 
-            this.formData.marketTime = dateFormat(new Date(this.formData.marketTime), 'yyyy-MM-dd');
-            this.formData.nmpaTime = dateFormat(new Date(this.formData.nmpaTime), 'yyyy-MM-dd');
-
-            // 初始化图片列表 imageList  authImageList  displayImageList
-            this.imageList = this.initPreviewImageList([formData.image], { name: '授权图片' });
-            this.authImageList = this.initPreviewImageList(formData.authImageList, { name: '授权图片' });
-            this.displayImageList = this.initPreviewImageList(formData.displayImageList, { name: '效果图' });
-
-            // 初始化参数列表
-            if (formData.questionList.length < this.questionMinLimit) {
-                const newQuestionList = [];
-                for (var i = 0; i < this.questionMinLimit; i++) {
-                    if (formData.questionList[i]) {
-                        newQuestionList[i] = formData.questionList[i]
-                    } else {
-                        newQuestionList[i] = {question: '', answer: '',}
-                    }
-                }
-                this.formData.questionList = newQuestionList
-            }
-            // 初始化问题列表
-            if (formData.paramList.length < this.paramsMinLimit) {
-                const newParamList = [];
-                for (var i = 0; i < this.paramsMinLimit; i++) {
-                    if (formData.paramList[i]) {
-                        newParamList[i] = formData.paramList[i]
-                    } else {
-                        newParamList[i] = {name: '', content: '',}
-                    }
-                }
-                this.formData.paramList = newParamList
-            }
+        // 返回文章列表页面
+        handleBack: function handleBack() {
+            localStorage.removeItem('target-name');
+            window.open('/supplier/encyclopedia/instrument-list.html', 'supplier-instrument-list');
+            window.close();
         },
-
-        // 初始化图片
-        initPreviewImageList(imageList, options){
-            if(!options){
-                options.name = '图片'
-            }
-
-            return imageList.map(function(item){
-                return {
-                    name: options.name,
-                    url: item
-                }
-            });
+        // 保存事件
+        handleSave() {
+            this.$refs.ruleForm.validate(valide => {
+                console.log(valide);
+                if (!valide) return;
+                this.saveFormData()
+            })
         },
 
-
-        // 获取表单数据
-        getProductFormData() {
-            this.productId = localStorage.getItem('productId');
-            localStorage.removeItem('productId');
-
-            if(!this.productId) return;
-
-            const that = this;
-            SupplierApi.GetShopBaikeProductForm({ productId: this.productId }, function(res){
-                if(res.code === 0){
-                    that.initFormData(res.data);
-                }else{
-                    CAIMEI.dialog('获取产品数据失败', false);
-                    setTimeout(function () {
-                        that.handleBack();
-                    }, 2000);
-                }
-            });
-        },
         // 保存表单数据
         saveFormData() {
             const that = this;
@@ -374,177 +194,243 @@ new Vue({
                 ...this.formData,
                 shopId: this.shopId,
                 commodityType: this.commodityType,
-                paramList: JSON.stringify(this.formData.paramList),
-                questionList: JSON.stringify(this.formData.questionList)
+                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))
             };
 
-            if(this.productId) params.productId = this.productId;
-
-            SupplierApi.ShopBaikeProductSave(params, function(res){
-                if(res.code === 0) {
+            if (this.productId) params.productId = this.productId;
+            console.log(params);
+            SupplierApi.ShopBaikeProductSave(params, function (res) {
+                if (res.code === 0) {
                     CAIMEI.dialog('保存成功', false);
                     setTimeout(function () {
                         that.handleBack();
                     }, 2000);
-                }else{
+                } else {
                     CAIMEI.Alert(res.msg, '确认', false)
                 }
             })
         },
 
-        // 返回文章列表页面
-        handleBack: function handleBack() {
-            localStorage.removeItem('target-name');
-            window.open('/supplier/encyclopedia/instrument-list.html', 'supplier-instrument-list');
-            window.close();
+		initFormData: function(formData){
+			console.log(formData);
+			// 初始化this.formData
+            for (var key in this.formData) {
+                if (formData.hasOwnProperty(key)) {
+                	// 如果是数组 就取值length
+                	if(formData[key] instanceof  Array){
+                		const len = formData[key].length
+                		this.formData[key] = len > 0 ? len : ''
+                	} else if(['marketTime', 'nmpaTime'].includes(key)){
+                		this.formData[key] = new Date(formData[key])
+                	}
+                	else {
+                		this.formData[key] = formData[key];
+                	}
+                }
+            }
+            // 处理参数
+			this.resetEmptyListData(formData.paramList, formData.questionList);
+            // 处理图片
+            this.authImageList = formData.authImageList.map(image => ({ url: image, name: 'authImage'}))
+            this.displayImageList = formData.displayImageList.map(image => ({ url: image, name: 'authImage'}))
+		},
+
+
+		// 获取表单数据
+        getProductFormData() {
+            this.productId = localStorage.getItem('productId') || 0;
+            localStorage.removeItem('productId');
+            if (this.productId > 0) {
+				const that = this;
+				SupplierApi.GetShopBaikeProductForm({productId: this.productId}, function (res) {
+					if (res.code === 0) {
+						that.initFormData(res.data);
+					} else {
+						CAIMEI.dialog('获取仪器数据失败', false);
+						setTimeout(function () {
+							that.handleBack();
+						}, 2000);
+					}
+				});
+            }else {
+            	this.resetEmptyListData([],[])
+            }
         },
 
-        // 保存事件
-        handleSave() {
+        // 获取分类列表
+        getTypeList() {
             const that = this;
-            // that.saveFormData();
-            this.validFormData(this.formData, this.rules).then(res=>{
+            SupplierApi.ShopBaikeProductTypeList({commodityType: this.commodityType}, function (res) {
+                that.typeList = res.data;
                 console.log(res);
-                that.saveFormData()
-            }).catch(()=>{
-                CAIMEI.dialog('必填项不能为空', false)
             })
         },
 
-        // 上传封面图片
-        handleUploadProductImage(files){
-            this.uploadImage(files[0]).then(res=>{
-                this.formData.image = res;
-                this.imageList.push({ url: res , name: '封面'})
-            }).catch(err=>{
-                console.log(err)
+        //添加一条参数
+        addParam() {
+            this.paramEmptyList.push({
+                name: '',
+                content: '',
+                p1: '参数名',
+                p2: '参数信息',
             })
         },
 
-        // 删除上传的封面图片
-        handleRemoveProductImage(){
-            this.formData.image = '';
-            this.imageList = [];
+        // 删除一条参数
+        removeParam(index) {
+            this.paramEmptyList.splice(index, 1)
         },
 
-        // 上传授权图片
-        handleUploadAuthImage(files){
-            const that = this;
-            files.forEach(function (file) {
-                if(file.type){
-                    // resultFiles 是 input 中选中的文件列表
-                    // insertImgFn 是获取图片 url 后,插入到编辑器的方法
-                    that.uploadImage(file).then(function (res) {
-                        that.formData.authImageList.push(res);
-                        that.authImageList.push({ url: res, name: '图片' })
-                    });
-                }
-            });
-        },
-        // 删除上传的授权图片
-        handleRemoveAuthImage(index){
-             this.formData.authImageList.splice(index, 1);
-             this.authImageList.splice(index, 1);
-             console.log(this.formData.authImageList);
-             console.log(this.authImageList);
+        //添加一条问答
+        addQuestion() {
+            this.questionEmptyList.push({
+                question: '',
+                answer: '',
+                p1: '请输入问题内容',
+                p2: '请输入问题解答内容',
+            })
         },
 
-        // 上传效果展示图片
-        handleUploadDisplayImageList(files){
-            const that = this;
-            files.forEach(function (file) {
-                if(file.type){
-                    // resultFiles 是 input 中选中的文件列表
-                    // insertImgFn 是获取图片 url 后,插入到编辑器的方法
-                    that.uploadImage(file).then(function (res) {
-                        that.formData.displayImageList.push(res);
-                        that.displayImageList.push({ url: res, name: '图片' })
-                    });
-                }
-            });
+        // 删除一条问答
+        removeQuestion(index) {
+            this.questionEmptyList.splice(index, 1)
         },
-        // 删除上传的效果展示图片
-        handleRemoveDisplayImageList(index){
-             this.formData.displayImageList.splice(index, 1);
-             this.displayImageList.splice(index, 1);
-        },
-
 
-        // 上传封面图片
-        handleUploadAuthQrCode(files){
-            this.uploadImage(files[0]).then(res=>{
-                this.formData.authQrCode = res;
-                this.authQrCodeList.push({ url: res , name: '封面'})
-            }).catch(err=>{
-                console.log(err)
+        // 初始化可变表单数据
+        resetEmptyListData(paramSource, questionSource) {
+            this.makeEmptyList({
+                target: this.paramEmptyList,
+                source: paramSource,
+                limit: this.minLimitParams,
+                key: 'name',
+                value: 'content',
+            })
+            this.makeEmptyList({
+                target: this.questionEmptyList,
+                source: questionSource,
+                limit: this.minLimitQuestions,
+                key: 'question',
+                value: 'answer',
             })
         },
 
-        // 删除上传的封面图片
-        handleRemoveAuthQrCode(){
-            this.formData.authQrCode = '';
-            this.authQrCodeList = [];
+        // 创建可变表单占位列表
+        makeEmptyList(options) {
+            options = {
+                target: [], // 目标数组
+                source: [], // 数据源数组
+                key: '',
+                value: '',
+                limit: 0, // 最小条数
+                argsList: ['参数', '品牌'], // placeholder文本
+                ...options,
+            }
+            let {target, source, limit, argsList, key, value} = options
+            let len = 0
+
+            target.push(
+                ...source.map(v => {
+                    v.p1 = `例如:${argsList[0]}`
+                    v.p2 = `请输入:${argsList[0]}信息`
+                    return v
+                })
+            )
+
+            len = limit - target.length
+            for (let i = 0; i < len; i++) {
+                const obj = {}
+                obj[key] = ''
+                obj[value] = ''
+                if (i <= argsList.length - 1) {
+                    obj.p1 = `例如:${argsList[i]}`
+                    obj.p2 = `请输入:${argsList[i]}信息`
+                } else {
+                    obj.p1 = `例如:${argsList[0]}`
+                    obj.p2 = `请输入:${argsList[0]}信息`
+                }
+                target.push(obj)
+            }
         },
 
+        handleAuthQrCodeSuccess(response){
+            this.$refs.authQrCodeUploader.clearFiles();
+        	this.formData.authQrCode = response.data
+        },
 
-        // 上传图片
-        uploadImage: function uploadImage(file) {
-            var formData = new FormData();
-            formData.append('file', file);
-            return new Promise(function (resolve, reject) {
-                PublicApi.uploadimg(formData, function (res) {
-                    if (res.code === 0) {
-                        resolve(res.data);
-                    }
-                    reject();
-                });
-            });
+        // 仪器图片上传成功的回调
+        handleImageSuccess(response) {
+        	this.$refs.coverUploader.clearFiles();
+        	this.formData.image = response.data
         },
 
-        // 初始化问题表单个数
-        resetParamsListLimit() {
-            for (let i = 0; i < this.paramsMinLimit; i++) {
-                this.formData.paramList.push({
-                    name: '',
-                    content: ''
-                });
-            }
+        // 认证图片上传成功的回调
+        handleAuthImageSuccess(response, file, fileList) {
+        	this.authImageList = fileList
         },
-        // 移除参数
-        handleRemoveParams(params) {
-            console.log(params);
-            this.formData.paramList.splice(params.index, 1);
+
+        // 移除认证图片
+        handleAuthImageRemove(file, fileList) {
+        	// console.log(fileList)
+            this.authImageList = fileList
         },
-        // 添加参数
-        handleAddParams() {
-            this.formData.paramList.push({
-                name: '',
-                content: ''
-            });
-            this.registerForm(this.formData, this.rules);
+
+        // 效果图片上传成功的回调
+        handleDisplayImageSuccess(response, file, fileList) {
+        	this.displayImageList = fileList
         },
 
+        // 移除效果图片
+        handleDisplayImageRemove(file, fileList) {
+            this.displayImageList = fileList
+        },
 
-        // 初始化问题表单个数
-        resetQuestionListLimit() {
-            for (let i = 0; i < this.questionMinLimit; i++) {
-                this.formData.questionList.push({
-                    question: '',
-                    answer: '',
-                });
+        // 图片上传前的回调
+        beforeImageUpload(file) {
+            const isLt2M = file.size / 1024 / 1024 < 2
+            if (!isLt2M) {
+                this.$message.error('上传头像图片大小不能超过 2MB!')
             }
+            return isLt2M
         },
-        // 移除问题
-        handleRemoveQuestion(question) {
-            this.formData.questionList.splice(question.index, 1);
+
+        // 预览图片
+        handlePictureCardPreview(file) {
+            this.dialogImageUrl = file.url
+            this.dialogVisible = true
         },
-        // 添加问题
-        handleAddQuestion() {
-            this.formData.questionList.push({
-                question: '',
-                answer: '',
-            });
-            this.registerForm(this.formData, this.rules);
+
+        // 预览图片弹窗
+        handlePictureCardPreview(file) {
+            this.dialogImageUrl = file.url
+            this.dialogVisible = true
         },
-    }
-});
+
+        // 监听formData中类型为数组的数据状态
+        watchArrayStatus(args = []) {
+            args.forEach(arg => {
+                if (this[arg] instanceof Array) {
+                    this.$watch(
+                        arg,
+                        (nval, oval) => {
+                        	console.log(arg, nval.length);
+                        	console.log(this[arg]);
+                        	if(nval.length > 0){
+                        		this.formData[arg] = nval.length
+                        	} else{
+                        		this.formData[arg] = ''
+                        	}
+                        },
+                        {deep: true}
+                    )
+                }
+            })
+        },
+    },
+})
+
+app.$mount('#instrumentEdit')

+ 537 - 0
src/main/resources/static/js/supplier-center/encyclopedia/product-edit-1.js

@@ -0,0 +1,537 @@
+const Radio = createnRadio();
+const Select = createSelect();
+const Option = createOption();
+const UploadImage = createUploadImage();
+const Editor = createEditorComponent();
+const InputGroup = createInputGroup();
+const QuestionGroup = createQuestionGroup()
+
+new Vue({
+    el: '#productEdit',
+    mixins: [validFormMixin],
+    components: {
+        'cm-radio': Radio,
+        'cm-select': Select,
+        'cm-option': Option,
+        'cm-upload-image': UploadImage,
+        'cm-editor': Editor,
+        'cm-input-group': InputGroup,
+        'cm-question-group': QuestionGroup
+    },
+    data: {
+        // 商品类型 1: 产品  2: 仪器
+        productId: 0,
+        commodityType: 1,
+        shopId: GLOBAL_SHOP_ID,
+        formData: {
+            // 产品名称
+            name: '',
+            // 产品别名
+            alias: '',
+            // 产品概述
+            discription: '',
+            // 产品图片
+            image: '',
+            // 产品参数
+            paramList: [],
+            // 产品优点
+            advantage: '',
+            // 产品缺点
+            disadvantage: '',
+            // 产品原理
+            principle: '',
+            // 品牌
+            brand: '',
+            // 产地
+            producePlace: '',
+            // 上市时间
+            marketTime: '',
+            // 公司/厂商
+            company: '',
+            // NMPA认证时间
+            nmpaTime: '',
+            // 产品认证
+            authImageList: [],
+            // 适应人群
+            adaptiveMan: '',
+            // 不适应人群
+            unAdaptiveMan: '',
+            // 术前术后
+            aroundOperation: '',
+            // 效果展示图片列表
+            displayImageList: [],
+            // 常见问题
+            questionList: [],
+            // 产品类别
+            typeId: '',
+            // 产品状态
+            status: 1,
+        },
+        // 预览图片列表
+        imageList: [],
+        authImageList: [],
+        displayImageList: [],
+        // 产品分类
+        typeList: [],
+
+        // 产品参数表单数据
+        paramsPlaceholderList: [{
+            label: '例如:名牌',
+            value: '请输入名牌信息'
+        }],
+        paramsMinLimit: 2,
+        paramskeyMap: {
+            key: 'name',
+            value: 'content'
+        },
+
+        // 问题数据表单列表
+        questionPlaceHolderList: [{
+            label: '请输入问题',
+            value: '请输入回答'
+        }],
+        questionMinLimit: 2,
+        questionkeyMap: {
+            key: 'question',
+            value: 'answer'
+        },
+        // 表单校验规则
+        rules: {
+            // 产品名称
+            name: [{
+                type: 'string',
+                required: true,
+                message: '名称不能为空',
+                trigger: ['blur', 'change']
+            }],
+            // 产品别名
+            alias: [{
+                type: 'string',
+                required: true,
+                message: '别名不能为空',
+                trigger: ['blur', 'change']
+            }],
+            // 产品概述
+            discription: [{
+                type: 'string',
+                required: true,
+                message: '概述不能为空',
+                trigger: ['blur', 'change']
+            }],
+            // 产品图片
+            image: [{
+                type: 'string',
+                required: true,
+                message: '图片不能为空',
+                trigger: 'change'
+            }],
+            // 产品参数
+            paramList: [{
+                type: 'array',
+                required: true,
+                message: '参数信息不能为空',
+                trigger: ['change', 'blur'],
+                valid: ['name', 'content']
+            }],
+            // 产品优点
+            advantage: [{
+                type: 'string',
+                required: true,
+                message: '优点不能为空',
+                trigger: 'change'
+            }],
+            // 产品缺点
+            disadvantage: [{
+                type: 'string',
+                required: true,
+                message: '缺点不能为空',
+                trigger: 'change'
+            }],
+            // 产品原理
+            principle: [{
+                type: 'string',
+                required: true,
+                message: '原理不能为空',
+                trigger: 'change'
+            }],
+            // 品牌
+            brand: [{
+                type: 'string',
+                required: true,
+                message: '品牌不能为空',
+                trigger: ['change', 'blur']
+            }],
+            // 产地
+            producePlace: [{
+                type: 'string',
+                required: true,
+                message: '产地不能为空',
+                trigger: ['change', 'blur']
+            }],
+
+            // 上市时间
+            marketTime: [{
+                type: 'string',
+                required: true,
+                message: '上市时间不能为空',
+                trigger: ['change', 'blur'],
+                pattern: {
+                    reg: /^\d{4}/g,
+                    regMessage: '时间格式不正确,年月日请以"-"连接'
+                },
+            }],
+            // 公司/厂商
+            company: [{
+                type: 'string',
+                required: true,
+                message: '公司/厂商不能为空',
+                trigger: ['change', 'blur']
+            }],
+            // NMPA认证时间
+            nmpaTime: [{
+                type: 'string',
+                required: true,
+                message: 'NMPA认证时间不能为空',
+                trigger: ['change', 'blur']
+            }],
+            // 产品认证
+            authImageList: [{
+                type: 'array',
+                required: true,
+                message: '产品认证图片不能为空',
+                trigger: 'change'
+            }],
+            // 适应人群
+            adaptiveMan: [{
+                type: 'string',
+                required: true,
+                message: '适应人群不能为空',
+                trigger: 'change'
+            }],
+            // 不适应人群
+            unAdaptiveMan: [{
+                type: 'string',
+                required: true,
+                message: '不适应人群不能为空',
+                trigger: 'change'
+            }],
+            // 术前术后
+            aroundOperation: [{
+                type: 'string',
+                required: true,
+                message: '术前术后内容不能为空',
+                trigger: 'change'
+            }],
+            // 效果展示
+            displayImageList: [{
+                type: 'array',
+                required: true,
+                message: '效果展示图片不能为空',
+                trigger: 'change'
+            }],
+            // 常见问题
+            questionList: [{
+                type: 'array',
+                required: true,
+                message: '常见问题不能为空',
+                trigger: ['change', 'blur'],
+                valid: ['question', 'answer']
+            }],
+            // 产品类别
+            typeId: [{
+                type: 'number',
+                required: true,
+                message: '产品类别不能为空',
+                trigger: 'change'
+            }],
+            // 产品状态
+            status: [{
+                type: 'number',
+                required: true,
+                message: '状态不能为空',
+                trigger: 'change'
+            }],
+        },
+    },
+    created() {
+        this.getTypeList();
+        this.getProductFormData();
+        this.resetQuestionListLimit();
+        this.resetParamsListLimit();
+        this.registerForm(this.formData, this.rules);
+    },
+    mounted: function () {
+        $('.navLayout').find('.navList').removeClass("on").find('.con').hide().find('a').removeClass("on");
+        $('.navLayout').find('.navList').eq(3).addClass("on").find('.con').show().find('a').eq(0).addClass("on");
+    },
+    methods: {
+        // 获取分类列表
+        getTypeList() {
+            const that = this;
+            SupplierApi.ShopBaikeProductTypeList({commodityType: this.commodityType}, function (res) {
+                that.typeList = res.data;
+                console.log(res);
+            })
+        },
+
+        // 初始化表单数据
+        initFormData: function(formData) {
+            console.log(formData);
+            // 初始化this.formData
+            for (var key in this.formData) {
+                if (formData.hasOwnProperty(key)) {
+                    // this.$set(this.formData, key, formData[key]);
+                    this.formData[key] = formData[key];
+                }
+            }
+
+            this.formData.marketTime = dateFormat(new Date(this.formData.marketTime), 'yyyy-MM-dd');
+            this.formData.nmpaTime = dateFormat(new Date(this.formData.nmpaTime), 'yyyy-MM-dd');
+
+            // 初始化图片列表 imageList  authImageList  displayImageList
+            this.imageList = this.initPreviewImageList([formData.image], {name: '授权图片'});
+            this.authImageList = this.initPreviewImageList(formData.authImageList, {name: '授权图片'});
+            this.displayImageList = this.initPreviewImageList(formData.displayImageList, {name: '效果图'});
+
+
+            // 初始化参数列表
+            if (formData.questionList.length < this.questionMinLimit) {
+                const newQuestionList = [];
+                for (var i = 0; i < this.questionMinLimit; i++) {
+                    if (formData.questionList[i]) {
+                        newQuestionList[i] = formData.questionList[i]
+                    } else {
+                        newQuestionList[i] = {question: '', answer: '',}
+                    }
+                }
+                this.formData.questionList = newQuestionList
+            }
+            // 初始化问题列表
+            if (formData.paramList.length < this.paramsMinLimit) {
+                const newParamList = [];
+                for (var i = 0; i < this.paramsMinLimit; i++) {
+                    if (formData.paramList[i]) {
+                        newParamList[i] = formData.paramList[i]
+                    } else {
+                        newParamList[i] = {name: '', content: '',}
+                    }
+                }
+                this.formData.paramList = newParamList
+            }
+        },
+
+        // 初始化图片
+        initPreviewImageList(imageList, options) {
+            if (!options) {
+                options.name = '图片'
+            }
+
+            return imageList.map(function (item) {
+                return {
+                    name: options.name,
+                    url: item
+                }
+            });
+        },
+
+
+        // 获取表单数据
+        getProductFormData() {
+            this.productId = localStorage.getItem('productId');
+            // localStorage.removeItem('productId');
+
+            // if (!this.productId) return;
+
+            const that = this;
+            SupplierApi.GetShopBaikeProductForm({productId: this.productId}, function (res) {
+                if (res.code === 0) {
+                    that.initFormData(res.data);
+                } else {
+                    CAIMEI.dialog('获取产品数据失败', false);
+                    setTimeout(function () {
+                        that.handleBack();
+                    }, 2000);
+                }
+            });
+        },
+        // 保存表单数据
+        saveFormData() {
+            const that = this;
+            const params = {
+                ...this.formData,
+                shopId: this.shopId,
+                commodityType: this.commodityType,
+                paramList: JSON.stringify(this.formData.paramList),
+                questionList: JSON.stringify(this.formData.questionList)
+            };
+
+            if (this.productId) params.productId = this.productId;
+
+            SupplierApi.ShopBaikeProductSave(params, function (res) {
+                if (res.code === 0) {
+                    CAIMEI.dialog('保存成功', false);
+                    setTimeout(function () {
+                        that.handleBack();
+                    }, 2000);
+                } else {
+                    CAIMEI.Alert(res.msg, '确认', false)
+                }
+            })
+        },
+
+        // 返回文章列表页面
+        handleBack: function handleBack() {
+            localStorage.removeItem('target-name');
+            window.open('/supplier/encyclopedia/product-list.html', 'supplier-product-list');
+            window.close();
+        },
+
+        // 保存事件
+        handleSave() {
+            console.log(this.formData);
+            const that = this;
+            // that.saveFormData();
+            this.validFormData(this.formData, this.rules).then(res => {
+                that.saveFormData()
+            }).catch(() => {
+                // CAIMEI.dialog('必填项不能为空', false);
+                // console.log(this.validMessage)
+                this.scorllToValid(this.validMessage);
+            })
+        },
+
+        scorllToValid: function(validData){
+            var currentKey = '';
+            for(var key in validData){
+                var validValue = validData[key];
+                if(!validValue.valid) {
+                    currentKey = key;
+                    continue;
+                }
+            }
+
+            $('html, body').animate({
+                scrollTop: $(`[props=${currentKey}]`).offset().top - $('#globalHead').height() - 40
+            }, 1000);
+        },
+
+
+        // 上传封面图片
+        handleUploadProductImage(files) {
+            this.uploadImage(files[0]).then(res => {
+                this.formData.image = res;
+                this.imageList.push({url: res, name: '封面'})
+            }).catch(err => {
+                console.log(err)
+            })
+        },
+
+        // 删除上传的封面图片
+        handleRemoveProductImage() {
+            this.formData.image = ''
+        },
+
+        // 上传授权图片
+        handleUploadAuthImage(files) {
+            const that = this;
+            files.forEach(function (file) {
+                if (file.type) {
+                    // resultFiles 是 input 中选中的文件列表
+                    // insertImgFn 是获取图片 url 后,插入到编辑器的方法
+                    that.uploadImage(file).then(function (res) {
+                        that.formData.authImageList.push(res);
+                        that.authImageList.push({url: res, name: '图片'})
+                    });
+                }
+            });
+        },
+        // 删除上传的授权图片
+        handleRemoveAuthImage(index) {
+            this.formData.authImageList.splice(index, 1);
+            this.authImageList.splice(index, 1);
+            console.log(this.formData.authImageList);
+            console.log(this.authImageList);
+        },
+
+        // 上传效果展示图片
+        handleUploadDisplayImageList(files) {
+            const that = this;
+            files.forEach(function (file) {
+                if (file.type) {
+                    // resultFiles 是 input 中选中的文件列表
+                    // insertImgFn 是获取图片 url 后,插入到编辑器的方法
+                    that.uploadImage(file).then(function (res) {
+                        that.formData.displayImageList.push(res);
+                        that.displayImageList.push({url: res, name: '图片'})
+                    });
+                }
+            });
+        },
+        // 删除上传的效果展示图片
+        handleRemoveDisplayImageList(index) {
+            this.formData.displayImageList.splice(index, 1);
+            this.displayImageList.splice(index, 1);
+        },
+
+
+        // 上传图片
+        uploadImage: function uploadImage(file) {
+            var formData = new FormData();
+            formData.append('file', file);
+            return new Promise(function (resolve, reject) {
+                PublicApi.uploadimg(formData, function (res) {
+                    if (res.code === 0) {
+                        resolve(res.data);
+                    }
+                    reject();
+                });
+            });
+        },
+
+        // 初始化问题表单个数
+        resetParamsListLimit() {
+            for (let i = 0; i < this.paramsMinLimit; i++) {
+                this.formData.paramList.push({
+                    name: '',
+                    content: ''
+                });
+            }
+        },
+        // 移除参数
+        handleRemoveParams(params) {
+            console.log(params);
+            this.formData.paramList.splice(params.index, 1);
+        },
+        // 添加参数
+        handleAddParams() {
+            this.formData.paramList.push({
+                name: '',
+                content: ''
+            });
+            this.registerForm(this.formData, this.rules);
+        },
+
+
+        // 初始化问题表单个数
+        resetQuestionListLimit() {
+            for (let i = 0; i < this.questionMinLimit; i++) {
+                this.formData.questionList.push({
+                    question: '',
+                    answer: '',
+                });
+            }
+        },
+        // 移除问题
+        handleRemoveQuestion(question) {
+            this.formData.questionList.splice(question.index, 1);
+        },
+        // 添加问题
+        handleAddQuestion() {
+            this.formData.questionList.push({
+                question: '',
+                answer: '',
+            });
+            this.registerForm(this.formData, this.rules);
+        },
+    }
+});

+ 353 - 467
src/main/resources/static/js/supplier-center/encyclopedia/product-edit.js

@@ -1,359 +1,184 @@
-const Radio = createnRadio();
-const Select = createSelect();
-const Option = createOption();
-const UploadImage = createUploadImage();
-const Editor = createEditorComponent();
-const InputGroup = createInputGroup();
-const QuestionGroup = createQuestionGroup()
-
-new Vue({
-    el: '#productEdit',
-    mixins: [validFormMixin],
+const Editor = window.createEditorComponent()
+
+const app = new Vue({
     components: {
-        'cm-radio': Radio,
-        'cm-select': Select,
-        'cm-option': Option,
-        'cm-upload-image': UploadImage,
-        'cm-editor': Editor,
-        'cm-input-group': InputGroup,
-        'cm-question-group': QuestionGroup
+        Editor,
     },
-    data: {
-        // 商品类型 1: 产品  2: 仪器
-        productId: 0,
-        commodityType: 1,
-        shopId: GLOBAL_SHOP_ID,
-        formData: {
-            // 产品名称
-            name: '',
-            // 产品别名
-            alias: '',
-            // 产品概述
-            discription: '',
-            // 产品图片
-            image: '',
+
+    data() {
+        var validateQuestionList = (rule, value, callback) => {
+            if (!value) {
+                callback(new Error('问答列表不能为空'))
+            } else if (value < this.minLimitQuestions) {
+                callback(new Error(`请填写至少${this.minLimitQuestions}条问答`))
+            } else {
+                callback();
+            }
+        }
+
+        var validateParamList = (rule, value, callback) => {
+            if (!value) {
+                callback(new Error('参数列表不能为空'))
+            } else if (value < this.minLimitParams) {
+                callback(new Error(`请填写至少${this.minLimitParams}条参数`))
+            } else {
+                callback();
+            }
+        }
+
+        return {
+
+            productId: 0,
+            commodityType: 1, // 商品类型 1: 产品  2: 仪器
+            shopId: GLOBAL_SHOP_ID,
+
+            action: $('#coreServer').val() + '/tools/image/upload/multi',
+
+            formData: {
+                // 产品名称
+                name: '',
+                // 产品别名
+                alias: '',
+                // 产品概述
+                discription: '',
+                // 产品图片
+                image: '',
+                // 产品参数
+                paramList: '',
+                // 产品优点
+                advantage: '',
+                // 产品缺点
+                disadvantage: '',
+                // 产品原理
+                principle: '',
+                // 品牌
+                brand: '',
+                // 产地
+                producePlace: '',
+                // 上市时间
+                marketTime: '',
+                // 公司/厂商
+                company: '',
+                // NMPA认证时间
+                nmpaTime: '',
+                // 产品认证
+                authImageList: '',
+                // 适应人群
+                adaptiveMan: '',
+                // 不适应人群
+                unAdaptiveMan: '',
+                // 术前术后
+                aroundOperation: '',
+                // 效果展示图片列表
+                displayImageList: '',
+                // 常见问题
+                questionList: '',
+                // 产品类别
+                typeId: '',
+                // 产品状态
+                status: 1,
+            },
+            rules: {
+                // 产品名称
+                name: [{required: true, message: '产品名称不能为空', trigger: ['change', 'blur']}],
+                // 产品别名
+                alias: [{required: true, message: '产品别名不能为空', trigger: ['change', 'blur']}],
+                // 产品概述
+                discription: [{required: true, message: '产品概述不能为空', trigger: ['change', 'blur']}],
+                // 产品图片
+                image: [{required: true, message: '请上传产品图片', trigger: 'change'}],
+                // 产品参数
+                paramList: [{required: true, validator: validateParamList, trigger: 'change'}],
+                // 产品优点
+                advantage: [{required: true, message: '产品优点不能为空', trigger: 'change'}],
+                // 产品缺点
+                disadvantage: [{required: true, message: '产品缺点不能为空', trigger: 'change'}],
+                // 产品原理
+                principle: [{required: true, message: '产品原理不能为空', trigger: 'change'}],
+                // 品牌
+                brand: [{required: true, message: '请输入产品品牌', trigger: ['change', 'blur']}],
+                // 产地
+                producePlace: [{required: true, message: '产品产地不能为空', trigger: ['change', 'blur']}],
+                // 上市时间
+                marketTime: [{required: true, message: '请填写上市时间', trigger: 'change'}],
+                // 公司/厂商
+                company: [{required: true, message: '公司/厂商不能为空', trigger: ['change', 'blur']}],
+                // NMPA认证时间
+                nmpaTime: [{required: true, message: '请填写NMPA认证时间', trigger: 'change'}],
+                // 产品认证
+                authImageList: [{required: true, message: '请上传产品认证图片', trigger: 'change'}],
+                // 适应人群
+                adaptiveMan: [{required: true, message: '适应人群不能为空', trigger: 'change'}],
+                // 不适应人群
+                unAdaptiveMan: [{required: true, message: '不适应人群不能为空', trigger: 'change'}],
+                // 术前术后
+                aroundOperation: [{required: true, message: '术前术后不能为空', trigger: 'change'}],
+                // 效果展示图片列表
+                displayImageList: [{required: true, message: '请上传效果展示图片', trigger: 'change'}],
+                // 常见问题
+                questionList: [{required: true, validator: validateQuestionList, trigger: 'change'}],
+                // 产品类别
+                typeId: [{required: true, message: '请选择产品类别', trigger: 'change'}],
+                // 产品状态
+                status: [{required: true, message: '请选择产品状态', trigger: 'change'}],
+            },
+
+            // 产品类别列表
+            typeList: [],
+
             // 产品参数
-            paramList: [],
-            // 产品优点
-            advantage: '',
-            // 产品缺点
-            disadvantage: '',
-            // 产品原理
-            principle: '',
-            // 品牌
-            brand: '',
-            // 产地
-            producePlace: '',
-            // 上市时间
-            marketTime: '',
-            // 公司/厂商
-            company: '',
-            // NMPA认证时间
-            nmpaTime: '',
+            // paramList: [],
+            paramEmptyList: [], // 占位
+            minLimitParams: 2,
+            // 常见问题
+            questionEmptyList: [], // 占位
+            minLimitQuestions: 2,
             // 产品认证
             authImageList: [],
-            // 适应人群
-            adaptiveMan: '',
-            // 不适应人群
-            unAdaptiveMan: '',
-            // 术前术后
-            aroundOperation: '',
             // 效果展示图片列表
-            displayImageList: [],
-            // 常见问题
-            questionList: [],
-            // 产品类别
-            typeId: '',
-            // 产品状态
-            status: 1,
-        },
-        // 预览图片列表
-        imageList: [],
-        authImageList: [],
-        displayImageList: [],
-        // 产品分类
-        typeList: [],
-
-        // 产品参数表单数据
-        paramsPlaceholderList: [{
-            label: '例如:名牌',
-            value: '请输入名牌信息'
-        }],
-        paramsMinLimit: 2,
-        paramskeyMap: {
-            key: 'name',
-            value: 'content'
-        },
-
-        // 问题数据表单列表
-        questionPlaceHolderList: [{
-            label: '请输入问题',
-            value: '请输入回答'
-        }],
-        questionMinLimit: 2,
-        questionkeyMap: {
-            key: 'question',
-            value: 'answer'
+            displayImageList: [],  // 初始化列表
+            dialogVisible: false,
+            dialogImageUrl: '',
+        }
+    },
+    computed: {
+        // 产品参数
+        paramList() {
+            const filter = this.paramEmptyList.filter(param => param.content !== '' && param.name !== '')
+            if (filter.length > 0) return filter.map(param => ({name: param.name, content: param.content}))
+            return []
         },
-        // 表单校验规则
-        rules: {
-            // 产品名称
-            name: [{
-                type: 'string',
-                required: true,
-                message: '名称不能为空',
-                trigger: ['blur', 'change']
-            }],
-            // 产品别名
-            alias: [{
-                type: 'string',
-                required: true,
-                message: '别名不能为空',
-                trigger: ['blur', 'change']
-            }],
-            // 产品概述
-            discription: [{
-                type: 'string',
-                required: true,
-                message: '概述不能为空',
-                trigger: ['blur', 'change']
-            }],
-            // 产品图片
-            image: [{
-                type: 'string',
-                required: true,
-                message: '图片不能为空',
-                trigger: 'change'
-            }],
-            // 产品参数
-            paramList: [{
-                type: 'array',
-                required: true,
-                message: '参数信息不能为空',
-                trigger: ['change', 'blur'],
-                valid: ['name', 'content']
-            }],
-            // 产品优点
-            advantage: [{
-                type: 'string',
-                required: true,
-                message: '优点不能为空',
-                trigger: 'change'
-            }],
-            // 产品缺点
-            disadvantage: [{
-                type: 'string',
-                required: true,
-                message: '缺点不能为空',
-                trigger: 'change'
-            }],
-            // 产品原理
-            principle: [{
-                type: 'string',
-                required: true,
-                message: '原理不能为空',
-                trigger: 'change'
-            }],
-            // 品牌
-            brand: [{
-                type: 'string',
-                required: true,
-                message: '品牌不能为空',
-                trigger: ['change', 'blur']
-            }],
-            // 产地
-            producePlace: [{
-                type: 'string',
-                required: true,
-                message: '产地不能为空',
-                trigger: ['change', 'blur']
-            }],
-
-            // 上市时间
-            marketTime: [{
-                type: 'string',
-                required: true,
-                message: '上市时间不能为空',
-                trigger: ['change', 'blur'],
-                pattern: {
-                    reg: /^\d{4}/g,
-                    regMessage: '时间格式不正确,年月日请以"-"连接'
-                },
-            }],
-            // 公司/厂商
-            company: [{
-                type: 'string',
-                required: true,
-                message: '公司/厂商不能为空',
-                trigger: ['change', 'blur']
-            }],
-            // NMPA认证时间
-            nmpaTime: [{
-                type: 'string',
-                required: true,
-                message: 'NMPA认证时间不能为空',
-                trigger: ['change', 'blur']
-            }],
-            // 产品认证
-            authImageList: [{
-                type: 'array',
-                required: true,
-                message: '产品认证图片不能为空',
-                trigger: 'change'
-            }],
-            // 适应人群
-            adaptiveMan: [{
-                type: 'string',
-                required: true,
-                message: '适应人群不能为空',
-                trigger: 'change'
-            }],
-            // 不适应人群
-            unAdaptiveMan: [{
-                type: 'string',
-                required: true,
-                message: '不适应人群不能为空',
-                trigger: 'change'
-            }],
-            // 术前术后
-            aroundOperation: [{
-                type: 'string',
-                required: true,
-                message: '术前术后内容不能为空',
-                trigger: 'change'
-            }],
-            // 效果展示
-            displayImageList: [{
-                type: 'array',
-                required: true,
-                message: '效果展示图片不能为空',
-                trigger: 'change'
-            }],
-            // 常见问题
-            questionList: [{
-                type: 'array',
-                required: true,
-                message: '常见问题不能为空',
-                trigger: ['change', 'blur'],
-                valid: ['question', 'answer']
-            }],
-            // 产品类别
-            typeId: [{
-                type: 'number',
-                required: true,
-                message: '产品类别不能为空',
-                trigger: 'change'
-            }],
-            // 产品状态
-            status: [{
-                type: 'number',
-                required: true,
-                message: '状态不能为空',
-                trigger: 'change'
-            }],
+        // 常见问题
+        questionList() {
+            const filter = this.questionEmptyList.filter(item => item.question !== '' && item.answer !== '')
+            if (filter.length > 0) return filter.map(item => ({question: item.question, answer: item.answer}))
+            return []
         },
     },
     created() {
         this.getTypeList();
+        this.watchArrayStatus(['paramList', 'questionList', 'authImageList', 'displayImageList']);
         this.getProductFormData();
-        this.resetQuestionListLimit();
-        this.resetParamsListLimit();
-        this.registerForm(this.formData, this.rules);
-    },
-    mounted: function () {
-        $('.navLayout').find('.navList').removeClass("on").find('.con').hide().find('a').removeClass("on");
-        $('.navLayout').find('.navList').eq(3).addClass("on").find('.con').show().find('a').eq(0).addClass("on");
-    },
-    methods: {
-        // 获取分类列表
-        getTypeList() {
-            const that = this;
-            SupplierApi.ShopBaikeProductTypeList({commodityType: this.commodityType}, function (res) {
-                that.typeList = res.data;
-                console.log(res);
-            })
-        },
 
-        // 初始化表单数据
-        initFormData: function(formData) {
-            console.log(formData);
-            // 初始化this.formData
-            for (var key in this.formData) {
-                if (formData.hasOwnProperty(key)) {
-                    // this.$set(this.formData, key, formData[key]);
-                    this.formData[key] = formData[key];
-                }
-            }
-
-            this.formData.marketTime = dateFormat(new Date(this.formData.marketTime), 'yyyy-MM-dd');
-            this.formData.nmpaTime = dateFormat(new Date(this.formData.nmpaTime), 'yyyy-MM-dd');
-
-            // 初始化图片列表 imageList  authImageList  displayImageList
-            this.imageList = this.initPreviewImageList([formData.image], {name: '授权图片'});
-            this.authImageList = this.initPreviewImageList(formData.authImageList, {name: '授权图片'});
-            this.displayImageList = this.initPreviewImageList(formData.displayImageList, {name: '效果图'});
+    },
 
+    methods: {
 
-            // 初始化参数列表
-            if (formData.questionList.length < this.questionMinLimit) {
-                const newQuestionList = [];
-                for (var i = 0; i < this.questionMinLimit; i++) {
-                    if (formData.questionList[i]) {
-                        newQuestionList[i] = formData.questionList[i]
-                    } else {
-                        newQuestionList[i] = {question: '', answer: '',}
-                    }
-                }
-                this.formData.questionList = newQuestionList
-            }
-            // 初始化问题列表
-            if (formData.paramList.length < this.paramsMinLimit) {
-                const newParamList = [];
-                for (var i = 0; i < this.paramsMinLimit; i++) {
-                    if (formData.paramList[i]) {
-                        newParamList[i] = formData.paramList[i]
-                    } else {
-                        newParamList[i] = {name: '', content: '',}
-                    }
-                }
-                this.formData.paramList = newParamList
-            }
+        // 返回文章列表页面
+        handleBack: function handleBack() {
+            localStorage.removeItem('target-name');
+            window.open('/supplier/encyclopedia/product-list.html', 'supplier-product-list');
+            window.close();
         },
-
-        // 初始化图片
-        initPreviewImageList(imageList, options) {
-            if (!options) {
-                options.name = '图片'
-            }
-
-            return imageList.map(function (item) {
-                return {
-                    name: options.name,
-                    url: item
-                }
-            });
+        // 保存事件
+        handleSave() {
+            this.$refs.ruleForm.validate(valide => {
+                console.log(valide);
+                if (!valide) return;
+                this.saveFormData()
+            })
         },
 
-
-        // 获取表单数据
-        getProductFormData() {
-            this.productId = localStorage.getItem('productId');
-            // localStorage.removeItem('productId');
-
-            // if (!this.productId) return;
-
-            const that = this;
-            SupplierApi.GetShopBaikeProductForm({productId: this.productId}, function (res) {
-                if (res.code === 0) {
-                    that.initFormData(res.data);
-                } else {
-                    CAIMEI.dialog('获取产品数据失败', false);
-                    setTimeout(function () {
-                        that.handleBack();
-                    }, 2000);
-                }
-            });
-        },
         // 保存表单数据
         saveFormData() {
             const that = this;
@@ -361,12 +186,16 @@ new Vue({
                 ...this.formData,
                 shopId: this.shopId,
                 commodityType: this.commodityType,
-                paramList: JSON.stringify(this.formData.paramList),
-                questionList: JSON.stringify(this.formData.questionList)
+                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))
             };
 
             if (this.productId) params.productId = this.productId;
-
+            console.log(params);
             SupplierApi.ShopBaikeProductSave(params, function (res) {
                 if (res.code === 0) {
                     CAIMEI.dialog('保存成功', false);
@@ -379,159 +208,216 @@ new Vue({
             })
         },
 
-        // 返回文章列表页面
-        handleBack: function handleBack() {
-            localStorage.removeItem('target-name');
-            window.open('/supplier/encyclopedia/product-list.html', 'supplier-product-list');
-            window.close();
+		initFormData: function(formData){
+			console.log(formData);
+			// 初始化this.formData
+            for (var key in this.formData) {
+                if (formData.hasOwnProperty(key)) {
+                	// 如果是数组 就取值length
+                	if(formData[key] instanceof  Array){
+                		const len = formData[key].length
+                		this.formData[key] = len > 0 ? len : ''
+                	} else if(['marketTime', 'nmpaTime'].includes(key)){
+                		this.formData[key] = new Date(formData[key])
+                	}
+                	else {
+                		this.formData[key] = formData[key];
+                	}
+                }
+            }
+            // 处理参数
+			this.resetEmptyListData(formData.paramList, formData.questionList);
+            // 处理图片
+            this.authImageList = formData.authImageList.map(image => ({ url: image, name: 'authImage'}))
+            this.displayImageList = formData.displayImageList.map(image => ({ url: image, name: 'authImage'}))
+		},
+
+
+		// 获取表单数据
+        getProductFormData() {
+            this.productId = localStorage.getItem('productId') || 0;
+            localStorage.removeItem('productId');
+            if (this.productId > 0) {
+				const that = this;
+				SupplierApi.GetShopBaikeProductForm({productId: this.productId}, function (res) {
+					if (res.code === 0) {
+						that.initFormData(res.data);
+					} else {
+						CAIMEI.dialog('获取产品数据失败', false);
+						setTimeout(function () {
+							that.handleBack();
+						}, 2000);
+					}
+				});
+            }else {
+            	this.resetEmptyListData([],[])
+            }
         },
 
-        // 保存事件
-        handleSave() {
-            console.log(this.formData);
+        // 获取分类列表
+        getTypeList() {
             const that = this;
-            // that.saveFormData();
-            this.validFormData(this.formData, this.rules).then(res => {
-                that.saveFormData()
-            }).catch(() => {
-                // CAIMEI.dialog('必填项不能为空', false);
-                // console.log(this.validMessage)
-                this.scorllToValid(this.validMessage);
+            SupplierApi.ShopBaikeProductTypeList({commodityType: this.commodityType}, function (res) {
+                that.typeList = res.data;
+                console.log(res);
             })
         },
 
-        scorllToValid: function(validData){
-            var currentKey = '';
-            for(var key in validData){
-                var validValue = validData[key];
-                if(!validValue.valid) {
-                    currentKey = key;
-                    continue;
-                }
-            }
-
-            $('html, body').animate({
-                scrollTop: $(`[props=${currentKey}]`).offset().top - $('#globalHead').height() - 40
-            }, 1000);
+        //添加一条参数
+        addParam() {
+            this.paramEmptyList.push({
+                name: '',
+                content: '',
+                p1: '参数名',
+                p2: '参数信息',
+            })
         },
 
+        // 删除一条参数
+        removeParam(index) {
+            this.paramEmptyList.splice(index, 1)
+        },
 
-        // 上传封面图片
-        handleUploadProductImage(files) {
-            this.uploadImage(files[0]).then(res => {
-                this.formData.image = res;
-                this.imageList.push({url: res, name: '封面'})
-            }).catch(err => {
-                console.log(err)
+        //添加一条问答
+        addQuestion() {
+            this.questionEmptyList.push({
+                question: '',
+                answer: '',
+                p1: '请输入问题内容',
+                p2: '请输入问题解答内容',
             })
         },
 
-        // 删除上传的封面图片
-        handleRemoveProductImage() {
-            this.formData.image = ''
+        // 删除一条问答
+        removeQuestion(index) {
+            this.questionEmptyList.splice(index, 1)
         },
 
-        // 上传授权图片
-        handleUploadAuthImage(files) {
-            const that = this;
-            files.forEach(function (file) {
-                if (file.type) {
-                    // resultFiles 是 input 中选中的文件列表
-                    // insertImgFn 是获取图片 url 后,插入到编辑器的方法
-                    that.uploadImage(file).then(function (res) {
-                        that.formData.authImageList.push(res);
-                        that.authImageList.push({url: res, name: '图片'})
-                    });
-                }
-            });
-        },
-        // 删除上传的授权图片
-        handleRemoveAuthImage(index) {
-            this.formData.authImageList.splice(index, 1);
-            this.authImageList.splice(index, 1);
-            console.log(this.formData.authImageList);
-            console.log(this.authImageList);
+        // 初始化可变表单数据
+        resetEmptyListData(paramSource, questionSource) {
+            this.makeEmptyList({
+                target: this.paramEmptyList,
+                source: paramSource,
+                limit: this.minLimitParams,
+                key: 'name',
+                value: 'content',
+            })
+            this.makeEmptyList({
+                target: this.questionEmptyList,
+                source: questionSource,
+                limit: this.minLimitQuestions,
+                key: 'question',
+                value: 'answer',
+            })
         },
 
-        // 上传效果展示图片
-        handleUploadDisplayImageList(files) {
-            const that = this;
-            files.forEach(function (file) {
-                if (file.type) {
-                    // resultFiles 是 input 中选中的文件列表
-                    // insertImgFn 是获取图片 url 后,插入到编辑器的方法
-                    that.uploadImage(file).then(function (res) {
-                        that.formData.displayImageList.push(res);
-                        that.displayImageList.push({url: res, name: '图片'})
-                    });
+        // 创建可变表单占位列表
+        makeEmptyList(options) {
+            options = {
+                target: [], // 目标数组
+                source: [], // 数据源数组
+                key: '',
+                value: '',
+                limit: 0, // 最小条数
+                argsList: ['参数', '品牌'], // placeholder文本
+                ...options,
+            }
+            let {target, source, limit, argsList, key, value} = options
+            let len = 0
+
+            target.push(
+                ...source.map(v => {
+                    v.p1 = `例如:${argsList[0]}`
+                    v.p2 = `请输入:${argsList[0]}信息`
+                    return v
+                })
+            )
+
+            len = limit - target.length
+            for (let i = 0; i < len; i++) {
+                const obj = {}
+                obj[key] = ''
+                obj[value] = ''
+                if (i <= argsList.length - 1) {
+                    obj.p1 = `例如:${argsList[i]}`
+                    obj.p2 = `请输入:${argsList[i]}信息`
+                } else {
+                    obj.p1 = `例如:${argsList[0]}`
+                    obj.p2 = `请输入:${argsList[0]}信息`
                 }
-            });
-        },
-        // 删除上传的效果展示图片
-        handleRemoveDisplayImageList(index) {
-            this.formData.displayImageList.splice(index, 1);
-            this.displayImageList.splice(index, 1);
+                target.push(obj)
+            }
         },
 
-
-        // 上传图片
-        uploadImage: function uploadImage(file) {
-            var formData = new FormData();
-            formData.append('file', file);
-            return new Promise(function (resolve, reject) {
-                PublicApi.uploadimg(formData, function (res) {
-                    if (res.code === 0) {
-                        resolve(res.data);
-                    }
-                    reject();
-                });
-            });
+        // 产品图片上传成功的回调
+        handleImageSuccess(response) {
+        	this.$refs.coverUploader.clearFiles();
+        	this.formData.image = response.data
         },
 
-        // 初始化问题表单个数
-        resetParamsListLimit() {
-            for (let i = 0; i < this.paramsMinLimit; i++) {
-                this.formData.paramList.push({
-                    name: '',
-                    content: ''
-                });
-            }
+        // 认证图片上传成功的回调
+        handleAuthImageSuccess(response, file, fileList) {
+        	this.authImageList = fileList
         },
-        // 移除参数
-        handleRemoveParams(params) {
-            console.log(params);
-            this.formData.paramList.splice(params.index, 1);
+
+        // 移除认证图片
+        handleAuthImageRemove(file, fileList) {
+        	// console.log(fileList)
+            this.authImageList = fileList
         },
-        // 添加参数
-        handleAddParams() {
-            this.formData.paramList.push({
-                name: '',
-                content: ''
-            });
-            this.registerForm(this.formData, this.rules);
+
+        // 效果图片上传成功的回调
+        handleDisplayImageSuccess(response, file, fileList) {
+        	this.displayImageList = fileList
         },
 
+        // 移除效果图片
+        handleDisplayImageRemove(file, fileList) {
+            this.displayImageList = fileList
+        },
 
-        // 初始化问题表单个数
-        resetQuestionListLimit() {
-            for (let i = 0; i < this.questionMinLimit; i++) {
-                this.formData.questionList.push({
-                    question: '',
-                    answer: '',
-                });
+        // 图片上传前的回调
+        beforeImageUpload(file) {
+            const isLt2M = file.size / 1024 / 1024 < 2
+            if (!isLt2M) {
+                this.$message.error('上传头像图片大小不能超过 2MB!')
             }
+            return isLt2M
         },
-        // 移除问题
-        handleRemoveQuestion(question) {
-            this.formData.questionList.splice(question.index, 1);
+
+        // 预览图片
+        handlePictureCardPreview(file) {
+            this.dialogImageUrl = file.url
+            this.dialogVisible = true
         },
-        // 添加问题
-        handleAddQuestion() {
-            this.formData.questionList.push({
-                question: '',
-                answer: '',
-            });
-            this.registerForm(this.formData, this.rules);
+
+        // 预览图片弹窗
+        handlePictureCardPreview(file) {
+            this.dialogImageUrl = file.url
+            this.dialogVisible = true
         },
-    }
-});
+
+        // 监听formData中类型为数组的数据状态
+        watchArrayStatus(args = []) {
+            args.forEach(arg => {
+                if (this[arg] instanceof Array) {
+                    this.$watch(
+                        arg,
+                        (nval, oval) => {
+                        	console.log(arg, nval.length);
+                        	console.log(this[arg]);
+                        	if(nval.length > 0){
+                        		this.formData[arg] = nval.length
+                        	} else{
+                        		this.formData[arg] = ''
+                        	}
+                        },
+                        {deep: true}
+                    )
+                }
+            })
+        },
+    },
+})
+
+app.$mount('#productEdit')

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
src/main/resources/static/lib/element-ui-min.css


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
src/main/resources/static/lib/element-ui.min.js


BIN
src/main/resources/static/lib/fonts/element-icons.ttf


BIN
src/main/resources/static/lib/fonts/element-icons.woff


+ 205 - 162
src/main/resources/templates/supplier-center/encyclopedia/instrument-edit.html

@@ -6,10 +6,10 @@
     <template th:replace="components/head-link"></template>
     <link th:href="@{/css/base/center.css(v=${version})}" rel="stylesheet" type="text/css">
     <link th:if="${pageId==1026}" th:href="@{/css/base/form.css(v=${version})}" rel="stylesheet" type="text/css">
-    <!--  组件样式  -->
-    <link th:href="@{/css/supplier-center/encyclopedia/form-component-style.css(v=${version})}" rel="stylesheet" type="text/css">
-    <!--  编辑页面样式  -->
-    <link th:href="@{/css/supplier-center/encyclopedia/edit-page.css(v=${version})}" charset="UTF-8" rel="stylesheet" type="text/css">
+    <!--element ui 样式表-->
+    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" />
+    <link th:href="@{/lib/element-ui-min.css}" rel="stylesheet" type="text/css">
+    <link th:href="@{/css/supplier-center/encyclopedia/edit-page-style.css}" rel="stylesheet" type="text/css">
     <template th:replace="components/analysis"></template>
 </head>
 <body>
@@ -18,7 +18,7 @@
 <template th:replace="components/header"></template>
 
 <!-- 我的采美 -->
-<div id="productEdit" class="product-edit">
+<div id="instrumentEdit" class="edit-page">
     <div class="navLayout" v-cloak>
         <div class="crumbs" v-if="isPC">
             <span>我的采美</span>
@@ -34,173 +34,216 @@
                 <div class="row">
                     <div class="top-tip">温馨提示:发布百科文章有利于曝光您的店铺商品,更有利于客户对产品与仪器有更深的认识度,提高成交率<br />发布并且审核通过后,可在采美百科搜索您的百科文章</div>
                     <!-- 带验证的表单 -->
-                    <form class="valid-form">
-                        <h2><em>*</em>产品简述</h2>
-                        <!-- 产品名称 -->
-                        <div class="form-item" required props="name">
-                            <div class="form-label"><em>*</em><span>仪器名称</span></div>
-                            <input type="text" class="cm input max border valid-control" placeholder="请输入仪器名称" v-model="formData.name"/>
-                            <div class="valid-message" v-if="!validMessage['name'].valid">{{ validMessage['name'].message }}</div>
-                        </div>
-                        <!-- 产品别名 -->
-                        <div class="form-item" required props="alias">
-                            <div class="form-label"><em>*</em><span>仪器别名</span></div>
-                            <input type="text" class="cm input max border valid-control" placeholder="请输入英文名或其他名称" v-model="formData.alias"/>
-                            <div class="valid-message" v-if="!validMessage['alias'].valid">{{ validMessage['alias'].message }}</div>
-                        </div>
-                        <!-- 产品概述 -->
-                        <div class="form-item" required props="discription">
-                            <div class="form-label"><em>*</em><span>仪器概述</span></div>
-                            <textarea class="cm textarea border max no-resize valid-control" rows="3" v-model="formData.discription"></textarea>
-                            <div class="valid-message" v-if="!validMessage['discription'].valid">{{ validMessage['discription'].message }}</div>
-                        </div>
-                        <!-- 产品图片 -->
-                        <div class="form-item" required props="image">
-                            <div class="form-label"><em>*</em><span>仪器图片</span></div>
-                            <cm-upload-image @change="handleUploadProductImage" @remove="handleRemoveProductImage" :img-list="imageList"></cm-upload-image>
-                            <div class="valid-message" v-if="!validMessage['image'].valid">{{ validMessage['image'].message }}</div>
-                        </div>
-                        <h2><em>*</em>正品识别</h2>
-                        <div class="form-item" required props="authLink">
-                            <div class="form-label"><em>*</em><span>认证链接</span></div>
-                            <input type="text" class="cm input max border valid-control" placeholder="请输认证链接" v-model="formData.authLink"/>
-                            <div class="valid-message" v-if="!validMessage['authLink'].valid">{{ validMessage['authLink'].message }}</div>
-                        </div>
+                    <div class="valide-form">
+                        <el-form :model="formData" :rules="rules" ref="ruleForm" label-position="top">
+                            <!-- 仪器简述 -->
+                            <div class="cm-big-label"><span class="cm-label">仪器简述</span></div>
+                            <el-form-item label="仪器名称" prop="name">
+                                <el-input v-model="formData.name" placeholder="请输入仪器名称"></el-input>
+                            </el-form-item>
+                            <el-form-item label="仪器别名" prop="alias">
+                                <el-input v-model="formData.alias" placeholder="请输入英文名或其他名称"></el-input>
+                            </el-form-item>
+                            <el-form-item label="仪器概述" prop="discription">
+                                <el-input v-model="formData.discription" type="textarea" placeholder="请输入仪器概述"
+                                          :rows="5"></el-input>
+                            </el-form-item>
+                            <el-form-item label="仪器图片" prop="image">
+                                <el-input v-model="formData.image" v-show="false"></el-input>
+                                <el-upload
+                                        class="cover-uploader"
+                                        ref="coverUploader"
+                                        :action="action"
+                                        :show-file-list="false"
+                                        :on-success="handleImageSuccess"
+                                        :before-upload="beforeImageUpload"
+                                        :limit="1"
+                                >
+                                    <img v-if="formData.image" :src="formData.image" class="cover"/>
+                                    <i v-else class="el-icon-plus cover-uploader-icon"></i>
+                                </el-upload>
+                            </el-form-item>
 
-                        <div class="form-item" required props="authQrCode">
-                            <div class="form-label"><em>*</em><span>认证二维码</span></div>
-                            <cm-upload-image @change="handleUploadAuthQrCode" @remove="handleRemoveAuthQrCode" :img-list="authQrCodeList"></cm-upload-image>
-                            <div class="valid-message" v-if="!validMessage['authQrCode'].valid">{{ validMessage['authQrCode'].message }}</div>
-                        </div>
+                            <!-- 正品识别 -->
+                            <div class="cm-big-label"><span class="cm-label">正品识别</span></div>
+                            <el-form-item label="认证链接" prop="authLink">
+                                <el-input v-model="formData.authLink" placeholder="请输入认证链接"></el-input>
+                            </el-form-item>
+                            <el-form-item label="认证二维码" prop="authQrCode">
+                                <el-input v-model="formData.authQrCode" v-show="false"></el-input>
+                                <el-upload
+                                        class="cover-uploader"
+                                        ref="authQrCodeUploader"
+                                        :action="action"
+                                        :show-file-list="false"
+                                        :on-success="handleAuthQrCodeSuccess"
+                                        :before-upload="beforeImageUpload"
+                                        :limit="1"
+                                >
+                                    <img v-if="formData.authQrCode" :src="formData.authQrCode" class="cover"/>
+                                    <i v-else class="el-icon-plus cover-uploader-icon"></i>
+                                </el-upload>
+                            </el-form-item>
 
+                            <!-- 仪器参数 -->
+                            <el-form-item label="仪器参数" prop="paramList" class="cm-big-label-el">
+                                <el-input v-model="formData.paramList" v-show="false"></el-input>
+                                <div class="form-params-group">
+                                    <span class="add-one" @click="addParam">添加参数</span>
+                                    <el-row class="form-params-group-row" :gutter="8"
+                                            v-for="(param, index) in paramEmptyList" :key="index">
+                                        <el-col :span="8">
+                                            <el-input v-model="param.name" :placeholder="param.p1"></el-input>
+                                        </el-col>
+                                        <el-col :span="16">
+                                            <el-input v-model="param.content" :placeholder="param.p2"></el-input>
+                                        </el-col>
+                                        <span class="remove" v-if="paramEmptyList.length > minLimitParams"
+                                              @click="removeParam(index)"
+                                        >&times;</span
+                                        >
+                                    </el-row>
+                                </div>
+                            </el-form-item>
 
-                        <h2><em>*</em>仪器参数</h2>
-                        <div class="form-item" required props="paramList">
-                            <cm-input-group
-                                    :list="formData.paramList"
-                                    :placeholder-list="paramsPlaceholderList"
-                                    :min-limit="paramsMinLimit"
-                                    :key-map="paramskeyMap"
-                                    add-text = '添加一条'
-                                    @remove="handleRemoveParams"
-                                    @add="handleAddParams"
-                            ></cm-input-group>
-                            <div class="valid-message" v-if="!validMessage['paramList'].valid">{{ validMessage['paramList'].message }}</div>
-                        </div>
-                        <h2><em>*</em>仪器优点</h2>
-                        <div class="form-item" required props="advantage">
-                            <cm-editor v-model="formData.advantage" :text="formData.advantage"></cm-editor>
-                            <div class="valid-message" v-if="!validMessage['advantage'].valid">{{ validMessage['advantage'].message }}</div>
-                        </div>
-                        <h2><em>*</em>仪器缺点</h2>
-                        <div class="form-item" required props="disadvantage">
-                            <cm-editor v-model="formData.disadvantage" :text="formData.disadvantage"></cm-editor>
-                            <div class="valid-message" v-if="!validMessage['disadvantage'].valid">{{ validMessage['disadvantage'].message }}</div>
-                        </div>
-                        <h2><em>*</em>仪器原理</h2>
-                        <div class="form-item" required props="principle">
-                            <cm-editor v-model="formData.principle" :text="formData.principle"></cm-editor>
-                            <div class="valid-message" v-if="!validMessage['principle'].valid">{{ validMessage['principle'].message }}</div>
-                        </div>
-                        <h2><em>*</em>仪器档案</h2>
-                        <!-- 品牌 -->
-                        <div class="form-item" required props="brand">
-                            <div class="form-label"><em>*</em><span>品牌</span></div>
-                            <input type="text" class="cm input max border valid-control" placeholder="请输入品牌" v-model="formData.brand"/>
-                            <div class="valid-message" v-if="!validMessage['brand'].valid">{{ validMessage['brand'].message }}</div>
-                        </div>
-                        <!-- 产地 -->
-                        <div class="form-item" required props="producePlace">
-                            <div class="form-label"><em>*</em><span>产地</span></div>
-                            <input type="text" class="cm input max border valid-control" placeholder="请输入产地" v-model="formData.producePlace"/>
-                            <div class="valid-message" v-if="!validMessage['producePlace'].valid">{{ validMessage['producePlace'].message }}</div>
-                        </div>
-                        <!-- 上市时间 -->
-                        <div class="form-item" required props="marketTime">
-                            <div class="form-label"><em>*</em><span>上市时间</span></div>
-                            <input type="date" class="cm input max border valid-control" placeholder="请选择上市时间" v-model="formData.marketTime"/>
-                            <div class="valid-message" v-if="!validMessage['marketTime'].valid">{{ validMessage['marketTime'].message }}</div>
-                        </div>
-                        <!-- 公司/厂商 -->
-                        <div class="form-item" required props="company">
-                            <div class="form-label"><em>*</em><span>公司/厂商</span></div>
-                            <input type="text" class="cm input max border valid-control" placeholder="请输入公司/厂商" v-model="formData.company"/>
-                            <div class="valid-message" v-if="!validMessage['company'].valid">{{ validMessage['company'].message }}</div>
-                        </div>
-                        <!-- NMPA认证时间 -->
-                        <div class="form-item" required props="nmpaTime">
-                            <div class="form-label"><em>*</em><span>NMPA认证时间</span></div>
-                            <input type="date" class="cm input max border valid-control" placeholder="请选择NMPA认证时间" v-model="formData.nmpaTime"/>
-                            <div class="valid-message" v-if="!validMessage['nmpaTime'].valid">{{ validMessage['nmpaTime'].message }}</div>
-                        </div>
-                        <!-- 产品认证 -->
-                        <div class="form-item" required props="authImageList">
-                            <div class="form-label"><em>*</em><span>仪器认证</span></div>
-                            <cm-upload-image @change="handleUploadAuthImage" @remove="handleRemoveAuthImage" :multiple="true" :img-list="authImageList"></cm-upload-image>
-                            <div class="valid-message" v-if="!validMessage['authImageList'].valid">{{ validMessage['authImageList'].message }}</div>
-                        </div>
-                        <h2><em>*</em>适应人群</h2>
-                        <div class="form-item" required props="adaptiveMan">
-                            <cm-editor v-model="formData.adaptiveMan" :text="formData.adaptiveMan"></cm-editor>
-                            <div class="valid-message" v-if="!validMessage['adaptiveMan'].valid">{{ validMessage['adaptiveMan'].message }}</div>
-                        </div>
-                        <h2><em>*</em>不适应人群</h2>
-                        <div class="form-item" required props="unAdaptiveMan">
-                            <cm-editor v-model="formData.unAdaptiveMan" :text="formData.unAdaptiveMan"></cm-editor>
-                            <div class="valid-message" v-if="!validMessage['unAdaptiveMan'].valid">{{ validMessage['unAdaptiveMan'].message }}</div>
-                        </div>
-                        <h2><em>*</em>术前术后</h2>
-                        <div class="form-item" required props="aroundOperation">
-                            <cm-editor v-model="formData.aroundOperation" :text="formData.aroundOperation"></cm-editor>
-                            <div class="valid-message" v-if="!validMessage['aroundOperation'].valid">{{ validMessage['aroundOperation'].message }}</div>
-                        </div>
-                        <!-- 效果展示 -->
-                        <h2><em>*</em>效果展示</h2>
-                        <div class="form-item" required props="displayImageList">
-                            <cm-upload-image @change="handleUploadDisplayImageList" @remove="handleRemoveDisplayImageList" :multiple="true" :img-list="displayImageList"></cm-upload-image>
-                            <div class="valid-message" v-if="!validMessage['displayImageList'].valid">{{ validMessage['displayImageList'].message }}</div>
-                        </div>
+                            <!-- 仪器优点 -->
+                            <el-form-item label="仪器优点" prop="advantage" class="cm-big-label-el">
+                                <el-input v-model="formData.advantage" v-show="false"></el-input>
+                                <editor v-model="formData.advantage"></editor>
+                            </el-form-item>
 
-                        <h2><em>*</em>常见问题</h2>
-                        <div class="form-item" required props="questionList">
-                            <cm-question-group
-                                    :list="formData.questionList"
-                                    :placeholder-list="questionPlaceHolderList"
-                                    :min-limit="questionMinLimit"
-                                    add-text='添加一条'
-                                    :key-map="questionkeyMap"
-                                    @remove="handleRemoveQuestion"
-                                    @add="handleAddQuestion"
-                            ></cm-question-group>
-                            <div class="valid-message" v-if="!validMessage['questionList'].valid">{{ validMessage['questionList'].message }}</div>
-                        </div>
-                        <!-- 产品类别 -->
-                        <div class="form-item" required>
-                            <div class="form-label"><em>*</em><span>仪器类别</span></div>
-                            <cm-select v-model="formData.typeId" placeholder="请选择" class="cm-select">
-                                <cm-option v-for="(item, index) in typeList" :key="index" :label="item.typeName" :value="item.typeId"></cm-option>
-                            </cm-select>
-                            <div class="valid-message" v-if="!validMessage['typeId'].valid">{{ validMessage['typeId'].message }}</div>
-                        </div>
-                        <!-- 产品状态 -->
-                        <div class="form-item vertical" required props="status">
-                            <div class="form-label"><em>*</em><span>状态</span></div>
-                            <div class="form-group">
-                                <cm-radio class="cm-radio" :label="1" v-model="formData.status">启用</cm-radio>
-                                <cm-radio class="cm-radio" :label="0" v-model="formData.status">停用</cm-radio>
-                            </div>
-                            <div class="valid-message" v-if="!validMessage['status'].valid">{{ validMessage['status'].message }}</div>
-                        </div>
+                            <!-- 仪器缺点 -->
+                            <el-form-item label="仪器缺点" prop="disadvantage" class="cm-big-label-el">
+                                <el-input v-model="formData.disadvantage" v-show="false"></el-input>
+                                <editor v-model="formData.disadvantage"></editor>
+                            </el-form-item>
+
+                            <!-- 仪器原理 -->
+                            <el-form-item label="仪器原理" prop="principle" class="cm-big-label-el">
+                                <el-input v-model="formData.principle" v-show="false"></el-input>
+                                <editor v-model="formData.principle"></editor>
+                            </el-form-item>
+
+                            <!-- 仪器档案 -->
+                            <div class="cm-big-label"><span class="cm-label">仪器档案</span></div>
+                            <el-form-item label="品牌" prop="brand">
+                                <el-input v-model="formData.brand"></el-input>
+                            </el-form-item>
+                            <el-form-item label="产地" prop="producePlace">
+                                <el-input v-model="formData.producePlace"></el-input>
+                            </el-form-item>
+                            <el-form-item label="上市时间" prop="marketTime">
+                                <el-date-picker class="max-width" v-model="formData.marketTime" type="date"
+                                                placeholder="上市时间">
+                                </el-date-picker>
+                            </el-form-item>
+                            <el-form-item label="公司/厂商" prop="company">
+                                <el-input v-model="formData.company"></el-input>
+                            </el-form-item>
+                            <el-form-item label="NMPA认证时间" prop="nmpaTime">
+                                <el-date-picker class="max-width" v-model="formData.nmpaTime" type="date"
+                                                placeholder="NMPA认证时间">
+                                </el-date-picker>
+                            </el-form-item>
+                            <el-form-item label="仪器认证" prop="authImageList">
+                                <el-input v-model="formData.authImageList" v-show="false"></el-input>
+                                <el-upload
+                                        :class="{ 'hide-upload': authImageList.length >= 4 }"
+                                        :action="action"
+                                        list-type="picture-card"
+                                        :on-preview="handlePictureCardPreview"
+                                        :on-remove="handleAuthImageRemove"
+                                        :on-success="handleAuthImageSuccess"
+                                        :file-list="authImageList"
+                                        :limit="4"
+                                >
+                                    <i class="el-icon-plus"></i>
+                                </el-upload>
+                            </el-form-item>
+
+                            <!-- 适应人群 -->
+                            <el-form-item label="适应人群" prop="adaptiveMan" class="cm-big-label-el">
+                                <el-input v-model="formData.adaptiveMan" v-show="false"></el-input>
+                                <editor v-model="formData.adaptiveMan"></editor>
+                            </el-form-item>
+
+                            <!-- 不适应人群 -->
+                            <el-form-item label="不适应人群" prop="unAdaptiveMan" class="cm-big-label-el">
+                                <el-input v-model="formData.unAdaptiveMan" v-show="false"></el-input>
+                                <editor v-model="formData.unAdaptiveMan"></editor>
+                            </el-form-item>
+
+                            <!-- 术前术后 -->
+                            <el-form-item label="术前术后" prop="aroundOperation" class="cm-big-label-el">
+                                <el-input v-model="formData.aroundOperation" v-show="false"></el-input>
+                                <editor v-model="formData.aroundOperation"></editor>
+                            </el-form-item>
+
+                            <!-- 效果展示 -->
+                            <el-form-item label="效果展示" prop="displayImageList" class="cm-big-label-el">
+                                <el-input v-model="formData.displayImageList" v-show="false"></el-input>
+                                <el-upload
+                                        :class="{ 'hide-upload': displayImageList.length >= 8 }"
+                                        :action="action"
+                                        list-type="picture-card"
+                                        :on-preview="handlePictureCardPreview"
+                                        :on-remove="handleDisplayImageRemove"
+                                        :on-success="handleDisplayImageSuccess"
+                                        :file-list="displayImageList"
+                                        :limit="8"
+                                >
+                                    <i class="el-icon-plus"></i>
+                                </el-upload>
+                            </el-form-item>
+
+                            <!-- 常见问题 -->
+                            <el-form-item label="常见问题" prop="questionList" class="cm-big-label-el">
+                                <el-input v-model="formData.questionList" v-show="false"></el-input>
+                                <div class="form-question-group">
+                                    <span class="add-one" @click="addQuestion">添加问答</span>
+                                    <div class="form-question-group-row" v-for="(item, index) in questionEmptyList">
+                                        <div class="cm-label"><em>*</em>问题{{ index + 1}}:</div>
+                                        <el-input placeholder="请输入问题内容" v-model="item.question"></el-input>
+                                        <div class="cm-label"><em>*</em>答:</div>
+                                        <el-input type="textarea" v-model="item.answer" placeholder="请输入问题解答内容"
+                                                  :rows="4"></el-input>
+                                        <span class="remove" v-if="questionEmptyList.length > minLimitQuestions"
+                                              @click="removeQuestion(index)"
+                                        >&times;</span
+                                        >
+                                    </div>
+                                </div>
+                            </el-form-item>
+
+                            <el-form-item label="仪器类别" prop="typeId" class="cm-big-label-el">
+                                <el-select class="max-width" v-model="formData.typeId" placeholder="请选择仪器类别">
+                                    <el-option v-for="item in typeList" :key="item.typeId" :label="item.typeName"
+                                               :value="item.typeId">
+                                    </el-option>
+                                </el-select>
+                            </el-form-item>
+                            <el-form-item label="" prop="status" label-position="left">
+                                <span class="cm-label"><em>*</em>仪器状态:</span>
+                                <el-radio-group v-model="formData.status">
+                                    <el-radio :label="1">启用</el-radio>
+                                    <el-radio :label="0">停用</el-radio>
+                                </el-radio-group>
+                            </el-form-item>
+                        </el-form>
 
-                        <div class="form-item vertical btns">
+                        <div class="btns">
                             <button class="btn break" @click.prevent="handleBack">返回</button>
                             <button class="btn submit" @click.prevent="handleSave">保存</button>
                         </div>
-                    </form>
+                    </div>
                 </div>
             </div>
         </div>
     </div>
+    <!-- 图片预览 -->
+    <el-dialog :visible.sync="dialogVisible">
+        <img width="100%" :src="dialogImageUrl" alt=""/>
+    </el-dialog>
 </div>
 <!-- 引入底部 -->
 <template th:replace="components/footer"></template>
@@ -209,10 +252,10 @@
 <template th:replace="supplier-center/encyclopedia/components/form-component"></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.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/supplier.service.js(v=${version})}"></script>
-<script charset="UTF-8" type="text/javascript" th:src="@{/js/supplier-center/encyclopedia/form-component.js(v=${version})}"></script>
-<script charset="UTF-8" type="text/javascript" th:src="@{/js/supplier-center/encyclopedia/validFormMixin.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/instrument-edit.js(v=${version})}"></script>
 </body>
 </html>

+ 204 - 0
src/main/resources/templates/supplier-center/encyclopedia/product-edit-1.html

@@ -0,0 +1,204 @@
+<!DOCTYPE html>
+<html lang="zh-CN" xmlns:th="https://www.thymeleaf.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xsi:schemaLocation="https://www.thymeleaf.org ">
+<head>
+    <title>采美365网-百科文库-添加产品百科</title>
+    <template th:replace="components/head-link"></template>
+    <link th:href="@{/css/base/center.css(v=${version})}" rel="stylesheet" type="text/css">
+    <link th:if="${pageId==1026}" th:href="@{/css/base/form.css(v=${version})}" rel="stylesheet" type="text/css">
+    <!--  组件样式  -->
+    <link th:href="@{/css/supplier-center/encyclopedia/form-component-style.css(v=${version})}" rel="stylesheet" type="text/css">
+    <!--  编辑页面样式  -->
+    <link th:href="@{/css/supplier-center/encyclopedia/edit-page.css(v=${version})}" charset="UTF-8" rel="stylesheet" type="text/css">
+    <template th:replace="components/analysis"></template>
+</head>
+<body>
+<input type="hidden" th:value="${coreServer}" id="coreServer">
+<!-- 引用头部 -->
+<template th:replace="components/header"></template>
+
+<!-- 我的采美 -->
+<div id="productEdit" class="product-edit">
+    <div class="navLayout" v-cloak>
+        <div class="crumbs" v-if="isPC">
+            <span>我的采美</span>
+            <span>&gt;</span>
+            <span>百科文库</span>
+            <span>&gt;</span>
+            <span>添加产品百科</span>
+        </div>
+        <div class="wrap clear">
+            <!--左侧导航-->
+            <template th:replace="supplier-center/components/tableft"></template>
+            <div class="right-box right">
+                <div class="row">
+                    <div class="top-tip">温馨提示:发布百科文章有利于曝光您的店铺商品,更有利于客户对产品与仪器有更深的认识度,提高成交率<br />发布并且审核通过后,可在采美百科搜索您的百科文章</div>
+                    <!-- 带验证的表单 -->
+                    <form class="valid-form">
+                        <h2><em>*</em>产品简述</h2>
+                        <!-- 产品名称 -->
+                        <div class="form-item" required props="name">
+                            <div class="form-label"><em>*</em><span>产品名称</span></div>
+                            <input type="text" class="cm input max border valid-control" placeholder="请输入产品名称" v-model="formData.name"/>
+                            <div class="valid-message" v-if="!validMessage['name'].valid">{{ validMessage['name'].message }}</div>
+                        </div>
+                        <!-- 产品别名 -->
+                        <div class="form-item" required props="alias">
+                            <div class="form-label"><em>*</em><span>产品别名</span></div>
+                            <input type="text" class="cm input max border valid-control" placeholder="请输入英文名或其他名称" v-model="formData.alias"/>
+                            <div class="valid-message" v-if="!validMessage['alias'].valid">{{ validMessage['alias'].message }}</div>
+                        </div>
+                        <!-- 产品概述 -->
+                        <div class="form-item" required props="discription">
+                            <div class="form-label"><em>*</em><span>产品概述</span></div>
+                            <textarea class="cm textarea border max no-resize valid-control" rows="3" v-model="formData.discription"></textarea>
+                            <div class="valid-message" v-if="!validMessage['discription'].valid">{{ validMessage['discription'].message }}</div>
+                        </div>
+                        <!-- 产品图片 -->
+                        <div class="form-item" required props="image">
+                            <div class="form-label"><em>*</em><span>产品图片</span></div>
+                            <cm-upload-image @change="handleUploadProductImage" @remove="handleRemoveProductImage" :img-list="imageList"></cm-upload-image>
+                            <div class="valid-message" v-if="!validMessage['image'].valid">{{ validMessage['image'].message }}</div>
+                        </div>
+                        <h2><em>*</em>产品参数</h2>
+                        <div class="form-item" required props="paramList">
+                            <cm-input-group
+                                    :list="formData.paramList"
+                                    :placeholder-list="paramsPlaceholderList"
+                                    :min-limit="paramsMinLimit"
+                                    :key-map="paramskeyMap"
+                                    add-text = '添加一条'
+                                    @remove="handleRemoveParams"
+                                    @add="handleAddParams"
+                            ></cm-input-group>
+                            <div class="valid-message" v-if="!validMessage['paramList'].valid">{{ validMessage['paramList'].message }}</div>
+                        </div>
+                        <h2><em>*</em>产品优点</h2>
+                        <div class="form-item" required props="advantage">
+                            <cm-editor v-model="formData.advantage" :text="formData.advantage"></cm-editor>
+                            <div class="valid-message" v-if="!validMessage['advantage'].valid">{{ validMessage['advantage'].message }}</div>
+                        </div>
+                        <h2><em>*</em>产品缺点</h2>
+                        <div class="form-item" required props="disadvantage">
+                            <cm-editor v-model="formData.disadvantage" :text="formData.disadvantage"></cm-editor>
+                            <div class="valid-message" v-if="!validMessage['disadvantage'].valid">{{ validMessage['disadvantage'].message }}</div>
+                        </div>
+                        <h2><em>*</em>产品原理</h2>
+                        <div class="form-item" required props="principle">
+                            <cm-editor v-model="formData.principle" :text="formData.principle"></cm-editor>
+                            <div class="valid-message" v-if="!validMessage['principle'].valid">{{ validMessage['principle'].message }}</div>
+                        </div>
+                        <h2><em>*</em>产品档案</h2>
+                        <!-- 品牌 -->
+                        <div class="form-item" required props="brand">
+                            <div class="form-label"><em>*</em><span>品牌</span></div>
+                            <input type="text" class="cm input max border valid-control" placeholder="请输入品牌" v-model="formData.brand"/>
+                            <div class="valid-message" v-if="!validMessage['brand'].valid">{{ validMessage['brand'].message }}</div>
+                        </div>
+                        <!-- 产地 -->
+                        <div class="form-item" required props="producePlace">
+                            <div class="form-label"><em>*</em><span>产地</span></div>
+                            <input type="text" class="cm input max border valid-control" placeholder="请输入产地" v-model="formData.producePlace"/>
+                            <div class="valid-message" v-if="!validMessage['producePlace'].valid">{{ validMessage['producePlace'].message }}</div>
+                        </div>
+                        <!-- 上市时间 -->
+                        <div class="form-item" required props="marketTime">
+                            <div class="form-label"><em>*</em><span>上市时间</span></div>
+                            <input type="date" class="cm input max border valid-control" placeholder="请选择上市时间" v-model="formData.marketTime"/>
+                            <div class="valid-message" v-if="!validMessage['marketTime'].valid">{{ validMessage['marketTime'].message }}</div>
+                        </div>
+                        <!-- 公司/厂商 -->
+                        <div class="form-item" required props="company">
+                            <div class="form-label"><em>*</em><span>公司/厂商</span></div>
+                            <input type="text" class="cm input max border valid-control" placeholder="请输入公司/厂商" v-model="formData.company"/>
+                            <div class="valid-message" v-if="!validMessage['company'].valid">{{ validMessage['company'].message }}</div>
+                        </div>
+                        <!-- NMPA认证时间 -->
+                        <div class="form-item" required props="nmpaTime">
+                            <div class="form-label"><em>*</em><span>NMPA认证时间</span></div>
+                            <input type="date" class="cm input max border valid-control" placeholder="请选择NMPA认证时间" v-model="formData.nmpaTime"/>
+                            <div class="valid-message" v-if="!validMessage['nmpaTime'].valid">{{ validMessage['nmpaTime'].message }}</div>
+                        </div>
+                        <!-- 产品认证 -->
+                        <div class="form-item" required props="authImageList">
+                            <div class="form-label"><em>*</em><span>产品认证</span></div>
+                            <cm-upload-image @change="handleUploadAuthImage" @remove="handleRemoveAuthImage" :multiple="true" :img-list="authImageList"></cm-upload-image>
+                            <div class="valid-message" v-if="!validMessage['authImageList'].valid">{{ validMessage['authImageList'].message }}</div>
+                        </div>
+                        <h2><em>*</em>适应人群</h2>
+                        <div class="form-item" required props="adaptiveMan">
+                            <cm-editor v-model="formData.adaptiveMan" :text="formData.adaptiveMan"></cm-editor>
+                            <div class="valid-message" v-if="!validMessage['adaptiveMan'].valid">{{ validMessage['adaptiveMan'].message }}</div>
+                        </div>
+                        <h2><em>*</em>不适应人群</h2>
+                        <div class="form-item" required props="unAdaptiveMan">
+                            <cm-editor v-model="formData.unAdaptiveMan" :text="formData.unAdaptiveMan"></cm-editor>
+                            <div class="valid-message" v-if="!validMessage['unAdaptiveMan'].valid">{{ validMessage['unAdaptiveMan'].message }}</div>
+                        </div>
+                        <h2><em>*</em>术前术后</h2>
+                        <div class="form-item" required props="aroundOperation">
+                            <cm-editor v-model="formData.aroundOperation" :text="formData.aroundOperation"></cm-editor>
+                            <div class="valid-message" v-if="!validMessage['aroundOperation'].valid">{{ validMessage['aroundOperation'].message }}</div>
+                        </div>
+                        <!-- 效果展示 -->
+                        <h2><em>*</em>效果展示</h2>
+                        <div class="form-item" required props="displayImageList">
+                            <cm-upload-image @change="handleUploadDisplayImageList" @remove="handleRemoveDisplayImageList" :multiple="true" :img-list="displayImageList"></cm-upload-image>
+                            <div class="valid-message" v-if="!validMessage['displayImageList'].valid">{{ validMessage['displayImageList'].message }}</div>
+                        </div>
+
+                        <h2><em>*</em>常见问题</h2>
+                        <div class="form-item" required props="questionList">
+                            <cm-question-group
+                                    :list="formData.questionList"
+                                    :placeholder-list="questionPlaceHolderList"
+                                    :min-limit="questionMinLimit"
+                                    add-text='添加一条'
+                                    :key-map="questionkeyMap"
+                                    @remove="handleRemoveQuestion"
+                                    @add="handleAddQuestion"
+                            ></cm-question-group>
+                            <div class="valid-message" v-if="!validMessage['questionList'].valid">{{ validMessage['questionList'].message }}</div>
+                        </div>
+                        <!-- 产品类别 -->
+                        <div class="form-item" required>
+                            <div class="form-label"><em>*</em><span>产品类别</span></div>
+                            <cm-select v-model="formData.typeId" placeholder="请选择" class="cm-select">
+                                <cm-option v-for="(item, index) in typeList" :key="index" :label="item.typeName" :value="item.typeId"></cm-option>
+                            </cm-select>
+                            <div class="valid-message" v-if="!validMessage['typeId'].valid">{{ validMessage['typeId'].message }}</div>
+                        </div>
+                        <!-- 产品状态 -->
+                        <div class="form-item vertical" required props="status">
+                            <div class="form-label"><em>*</em><span>产品状态</span></div>
+                            <div class="form-group">
+                                <cm-radio class="cm-radio" :label="1" v-model="formData.status">启用</cm-radio>
+                                <cm-radio class="cm-radio" :label="0" v-model="formData.status">停用</cm-radio>
+                            </div>
+                            <div class="valid-message" v-if="!validMessage['status'].valid">{{ validMessage['status'].message }}</div>
+                        </div>
+
+                        <div class="form-item vertical btns">
+                            <button class="btn break" @click.prevent="handleBack">返回</button>
+                            <button class="btn submit" @click.prevent="handleSave">保存</button>
+                        </div>
+                    </form>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<!-- 引入底部 -->
+<template th:replace="components/footer"></template>
+<template th:replace="components/foot-link"></template>
+<!-- 引入vue组件 -->
+<template th:replace="supplier-center/encyclopedia/components/form-component"></template>
+
+<script charset="utf-8" type="text/javascript" th:src="@{/lib/wangEditor.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/supplier.service.js(v=${version})}"></script>
+<script charset="UTF-8" type="text/javascript" th:src="@{/js/supplier-center/encyclopedia/form-component.js(v=${version})}"></script>
+<script charset="UTF-8" type="text/javascript" th:src="@{/js/supplier-center/encyclopedia/validFormMixin.js(v=${version})}"></script>
+<script charset="UTF-8" type="text/javascript" th:src="@{/js/supplier-center/encyclopedia/product-edit.js(v=${version})}"></script>
+</body>
+</html>

+ 187 - 151
src/main/resources/templates/supplier-center/encyclopedia/product-edit.html

@@ -6,10 +6,10 @@
     <template th:replace="components/head-link"></template>
     <link th:href="@{/css/base/center.css(v=${version})}" rel="stylesheet" type="text/css">
     <link th:if="${pageId==1026}" th:href="@{/css/base/form.css(v=${version})}" rel="stylesheet" type="text/css">
-    <!--  组件样式  -->
-    <link th:href="@{/css/supplier-center/encyclopedia/form-component-style.css(v=${version})}" rel="stylesheet" type="text/css">
-    <!--  编辑页面样式  -->
-    <link th:href="@{/css/supplier-center/encyclopedia/edit-page.css(v=${version})}" charset="UTF-8" rel="stylesheet" type="text/css">
+    <!--element ui 样式表-->
+    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" />
+    <link th:href="@{/lib/element-ui-min.css}" rel="stylesheet" type="text/css">
+    <link th:href="@{/css/supplier-center/encyclopedia/edit-page-style.css}" rel="stylesheet" type="text/css">
     <template th:replace="components/analysis"></template>
 </head>
 <body>
@@ -18,7 +18,7 @@
 <template th:replace="components/header"></template>
 
 <!-- 我的采美 -->
-<div id="productEdit" class="product-edit">
+<div id="productEdit" class="edit-page">
     <div class="navLayout" v-cloak>
         <div class="crumbs" v-if="isPC">
             <span>我的采美</span>
@@ -34,159 +34,195 @@
                 <div class="row">
                     <div class="top-tip">温馨提示:发布百科文章有利于曝光您的店铺商品,更有利于客户对产品与仪器有更深的认识度,提高成交率<br />发布并且审核通过后,可在采美百科搜索您的百科文章</div>
                     <!-- 带验证的表单 -->
-                    <form class="valid-form">
-                        <h2><em>*</em>产品简述</h2>
-                        <!-- 产品名称 -->
-                        <div class="form-item" required props="name">
-                            <div class="form-label"><em>*</em><span>产品名称</span></div>
-                            <input type="text" class="cm input max border valid-control" placeholder="请输入产品名称" v-model="formData.name"/>
-                            <div class="valid-message" v-if="!validMessage['name'].valid">{{ validMessage['name'].message }}</div>
-                        </div>
-                        <!-- 产品别名 -->
-                        <div class="form-item" required props="alias">
-                            <div class="form-label"><em>*</em><span>产品别名</span></div>
-                            <input type="text" class="cm input max border valid-control" placeholder="请输入英文名或其他名称" v-model="formData.alias"/>
-                            <div class="valid-message" v-if="!validMessage['alias'].valid">{{ validMessage['alias'].message }}</div>
-                        </div>
-                        <!-- 产品概述 -->
-                        <div class="form-item" required props="discription">
-                            <div class="form-label"><em>*</em><span>产品概述</span></div>
-                            <textarea class="cm textarea border max no-resize valid-control" rows="3" v-model="formData.discription"></textarea>
-                            <div class="valid-message" v-if="!validMessage['discription'].valid">{{ validMessage['discription'].message }}</div>
-                        </div>
-                        <!-- 产品图片 -->
-                        <div class="form-item" required props="image">
-                            <div class="form-label"><em>*</em><span>产品图片</span></div>
-                            <cm-upload-image @change="handleUploadProductImage" @remove="handleRemoveProductImage" :img-list="imageList"></cm-upload-image>
-                            <div class="valid-message" v-if="!validMessage['image'].valid">{{ validMessage['image'].message }}</div>
-                        </div>
-                        <h2><em>*</em>产品参数</h2>
-                        <div class="form-item" required props="paramList">
-                            <cm-input-group
-                                    :list="formData.paramList"
-                                    :placeholder-list="paramsPlaceholderList"
-                                    :min-limit="paramsMinLimit"
-                                    :key-map="paramskeyMap"
-                                    add-text = '添加一条'
-                                    @remove="handleRemoveParams"
-                                    @add="handleAddParams"
-                            ></cm-input-group>
-                            <div class="valid-message" v-if="!validMessage['paramList'].valid">{{ validMessage['paramList'].message }}</div>
-                        </div>
-                        <h2><em>*</em>产品优点</h2>
-                        <div class="form-item" required props="advantage">
-                            <cm-editor v-model="formData.advantage" :text="formData.advantage"></cm-editor>
-                            <div class="valid-message" v-if="!validMessage['advantage'].valid">{{ validMessage['advantage'].message }}</div>
-                        </div>
-                        <h2><em>*</em>产品缺点</h2>
-                        <div class="form-item" required props="disadvantage">
-                            <cm-editor v-model="formData.disadvantage" :text="formData.disadvantage"></cm-editor>
-                            <div class="valid-message" v-if="!validMessage['disadvantage'].valid">{{ validMessage['disadvantage'].message }}</div>
-                        </div>
-                        <h2><em>*</em>产品原理</h2>
-                        <div class="form-item" required props="principle">
-                            <cm-editor v-model="formData.principle" :text="formData.principle"></cm-editor>
-                            <div class="valid-message" v-if="!validMessage['principle'].valid">{{ validMessage['principle'].message }}</div>
-                        </div>
-                        <h2><em>*</em>产品档案</h2>
-                        <!-- 品牌 -->
-                        <div class="form-item" required props="brand">
-                            <div class="form-label"><em>*</em><span>品牌</span></div>
-                            <input type="text" class="cm input max border valid-control" placeholder="请输入品牌" v-model="formData.brand"/>
-                            <div class="valid-message" v-if="!validMessage['brand'].valid">{{ validMessage['brand'].message }}</div>
-                        </div>
-                        <!-- 产地 -->
-                        <div class="form-item" required props="producePlace">
-                            <div class="form-label"><em>*</em><span>产地</span></div>
-                            <input type="text" class="cm input max border valid-control" placeholder="请输入产地" v-model="formData.producePlace"/>
-                            <div class="valid-message" v-if="!validMessage['producePlace'].valid">{{ validMessage['producePlace'].message }}</div>
-                        </div>
-                        <!-- 上市时间 -->
-                        <div class="form-item" required props="marketTime">
-                            <div class="form-label"><em>*</em><span>上市时间</span></div>
-                            <input type="date" class="cm input max border valid-control" placeholder="请选择上市时间" v-model="formData.marketTime"/>
-                            <div class="valid-message" v-if="!validMessage['marketTime'].valid">{{ validMessage['marketTime'].message }}</div>
-                        </div>
-                        <!-- 公司/厂商 -->
-                        <div class="form-item" required props="company">
-                            <div class="form-label"><em>*</em><span>公司/厂商</span></div>
-                            <input type="text" class="cm input max border valid-control" placeholder="请输入公司/厂商" v-model="formData.company"/>
-                            <div class="valid-message" v-if="!validMessage['company'].valid">{{ validMessage['company'].message }}</div>
-                        </div>
-                        <!-- NMPA认证时间 -->
-                        <div class="form-item" required props="nmpaTime">
-                            <div class="form-label"><em>*</em><span>NMPA认证时间</span></div>
-                            <input type="date" class="cm input max border valid-control" placeholder="请选择NMPA认证时间" v-model="formData.nmpaTime"/>
-                            <div class="valid-message" v-if="!validMessage['nmpaTime'].valid">{{ validMessage['nmpaTime'].message }}</div>
-                        </div>
-                        <!-- 产品认证 -->
-                        <div class="form-item" required props="authImageList">
-                            <div class="form-label"><em>*</em><span>产品认证</span></div>
-                            <cm-upload-image @change="handleUploadAuthImage" @remove="handleRemoveAuthImage" :multiple="true" :img-list="authImageList"></cm-upload-image>
-                            <div class="valid-message" v-if="!validMessage['authImageList'].valid">{{ validMessage['authImageList'].message }}</div>
-                        </div>
-                        <h2><em>*</em>适应人群</h2>
-                        <div class="form-item" required props="adaptiveMan">
-                            <cm-editor v-model="formData.adaptiveMan" :text="formData.adaptiveMan"></cm-editor>
-                            <div class="valid-message" v-if="!validMessage['adaptiveMan'].valid">{{ validMessage['adaptiveMan'].message }}</div>
-                        </div>
-                        <h2><em>*</em>不适应人群</h2>
-                        <div class="form-item" required props="unAdaptiveMan">
-                            <cm-editor v-model="formData.unAdaptiveMan" :text="formData.unAdaptiveMan"></cm-editor>
-                            <div class="valid-message" v-if="!validMessage['unAdaptiveMan'].valid">{{ validMessage['unAdaptiveMan'].message }}</div>
-                        </div>
-                        <h2><em>*</em>术前术后</h2>
-                        <div class="form-item" required props="aroundOperation">
-                            <cm-editor v-model="formData.aroundOperation" :text="formData.aroundOperation"></cm-editor>
-                            <div class="valid-message" v-if="!validMessage['aroundOperation'].valid">{{ validMessage['aroundOperation'].message }}</div>
-                        </div>
-                        <!-- 效果展示 -->
-                        <h2><em>*</em>效果展示</h2>
-                        <div class="form-item" required props="displayImageList">
-                            <cm-upload-image @change="handleUploadDisplayImageList" @remove="handleRemoveDisplayImageList" :multiple="true" :img-list="displayImageList"></cm-upload-image>
-                            <div class="valid-message" v-if="!validMessage['displayImageList'].valid">{{ validMessage['displayImageList'].message }}</div>
-                        </div>
+                    <div class="valide-form">
+                        <el-form :model="formData" :rules="rules" ref="ruleForm" label-position="top">
+                            <!-- 产品简述 -->
+                            <div class="cm-big-label"><span class="cm-label">产品简述</span></div>
+                            <el-form-item label="产品名称" prop="name">
+                                <el-input v-model="formData.name" placeholder="请输入产品名称"></el-input>
+                            </el-form-item>
+                            <el-form-item label="产品别名" prop="alias">
+                                <el-input v-model="formData.alias" placeholder="请输入英文名或其他名称"></el-input>
+                            </el-form-item>
+                            <el-form-item label="产品概述" prop="discription">
+                                <el-input v-model="formData.discription" type="textarea" placeholder="请输入产品概述"
+                                          :rows="5"></el-input>
+                            </el-form-item>
+                            <el-form-item label="产品图片" prop="image">
+                                <el-input v-model="formData.image" v-show="false"></el-input>
+                                <el-upload
+                                        class="cover-uploader"
+                                        ref="coverUploader"
+                                        :action="action"
+                                        :show-file-list="false"
+                                        :on-success="handleImageSuccess"
+                                        :before-upload="beforeImageUpload"
+                                        :limit="1"
+                                >
+                                    <img v-if="formData.image" :src="formData.image" class="cover"/>
+                                    <i v-else class="el-icon-plus cover-uploader-icon"></i>
+                                </el-upload>
+                            </el-form-item>
 
-                        <h2><em>*</em>常见问题</h2>
-                        <div class="form-item" required props="questionList">
-                            <cm-question-group
-                                    :list="formData.questionList"
-                                    :placeholder-list="questionPlaceHolderList"
-                                    :min-limit="questionMinLimit"
-                                    add-text='添加一条'
-                                    :key-map="questionkeyMap"
-                                    @remove="handleRemoveQuestion"
-                                    @add="handleAddQuestion"
-                            ></cm-question-group>
-                            <div class="valid-message" v-if="!validMessage['questionList'].valid">{{ validMessage['questionList'].message }}</div>
-                        </div>
-                        <!-- 产品类别 -->
-                        <div class="form-item" required>
-                            <div class="form-label"><em>*</em><span>产品类别</span></div>
-                            <cm-select v-model="formData.typeId" placeholder="请选择" class="cm-select">
-                                <cm-option v-for="(item, index) in typeList" :key="index" :label="item.typeName" :value="item.typeId"></cm-option>
-                            </cm-select>
-                            <div class="valid-message" v-if="!validMessage['typeId'].valid">{{ validMessage['typeId'].message }}</div>
-                        </div>
-                        <!-- 产品状态 -->
-                        <div class="form-item vertical" required props="status">
-                            <div class="form-label"><em>*</em><span>产品状态</span></div>
-                            <div class="form-group">
-                                <cm-radio class="cm-radio" :label="1" v-model="formData.status">启用</cm-radio>
-                                <cm-radio class="cm-radio" :label="0" v-model="formData.status">停用</cm-radio>
-                            </div>
-                            <div class="valid-message" v-if="!validMessage['status'].valid">{{ validMessage['status'].message }}</div>
-                        </div>
+                            <!-- 产品参数 -->
+                            <el-form-item label="产品参数" prop="paramList" class="cm-big-label-el">
+                                <el-input v-model="formData.paramList" v-show="false"></el-input>
+                                <div class="form-params-group">
+                                    <span class="add-one" @click="addParam">添加参数</span>
+                                    <el-row class="form-params-group-row" :gutter="8"
+                                            v-for="(param, index) in paramEmptyList" :key="index">
+                                        <el-col :span="8">
+                                            <el-input v-model="param.name" :placeholder="param.p1"></el-input>
+                                        </el-col>
+                                        <el-col :span="16">
+                                            <el-input v-model="param.content" :placeholder="param.p2"></el-input>
+                                        </el-col>
+                                        <span class="remove" v-if="paramEmptyList.length > minLimitParams"
+                                              @click="removeParam(index)"
+                                        >&times;</span
+                                        >
+                                    </el-row>
+                                </div>
+                            </el-form-item>
+
+                            <!-- 产品优点 -->
+                            <el-form-item label="产品优点" prop="advantage" class="cm-big-label-el">
+                                <el-input v-model="formData.advantage" v-show="false"></el-input>
+                                <editor v-model="formData.advantage"></editor>
+                            </el-form-item>
+
+                            <!-- 产品缺点 -->
+                            <el-form-item label="产品缺点" prop="disadvantage" class="cm-big-label-el">
+                                <el-input v-model="formData.disadvantage" v-show="false"></el-input>
+                                <editor v-model="formData.disadvantage"></editor>
+                            </el-form-item>
+
+                            <!-- 产品原理 -->
+                            <el-form-item label="产品原理" prop="principle" class="cm-big-label-el">
+                                <el-input v-model="formData.principle" v-show="false"></el-input>
+                                <editor v-model="formData.principle"></editor>
+                            </el-form-item>
+
+                            <!-- 产品档案 -->
+                            <div class="cm-big-label"><span class="cm-label">产品档案</span></div>
+                            <el-form-item label="品牌" prop="brand">
+                                <el-input v-model="formData.brand"></el-input>
+                            </el-form-item>
+                            <el-form-item label="产地" prop="producePlace">
+                                <el-input v-model="formData.producePlace"></el-input>
+                            </el-form-item>
+                            <el-form-item label="上市时间" prop="marketTime">
+                                <el-date-picker class="max-width" v-model="formData.marketTime" type="date"
+                                                placeholder="上市时间">
+                                </el-date-picker>
+                            </el-form-item>
+                            <el-form-item label="公司/厂商" prop="company">
+                                <el-input v-model="formData.company"></el-input>
+                            </el-form-item>
+                            <el-form-item label="NMPA认证时间" prop="nmpaTime">
+                                <el-date-picker class="max-width" v-model="formData.nmpaTime" type="date"
+                                                placeholder="NMPA认证时间">
+                                </el-date-picker>
+                            </el-form-item>
+                            <el-form-item label="产品认证" prop="authImageList">
+                                <el-input v-model="formData.authImageList" v-show="false"></el-input>
+                                <el-upload
+                                        :class="{ 'hide-upload': authImageList.length >= 4 }"
+                                        :action="action"
+                                        list-type="picture-card"
+                                        :on-preview="handlePictureCardPreview"
+                                        :on-remove="handleAuthImageRemove"
+                                        :on-success="handleAuthImageSuccess"
+                                        :file-list="authImageList"
+                                        :limit="4"
+                                >
+                                    <i class="el-icon-plus"></i>
+                                </el-upload>
+                            </el-form-item>
+
+                            <!-- 适应人群 -->
+                            <el-form-item label="适应人群" prop="adaptiveMan" class="cm-big-label-el">
+                                <el-input v-model="formData.adaptiveMan" v-show="false"></el-input>
+                                <editor v-model="formData.adaptiveMan"></editor>
+                            </el-form-item>
+
+                            <!-- 不适应人群 -->
+                            <el-form-item label="不适应人群" prop="unAdaptiveMan" class="cm-big-label-el">
+                                <el-input v-model="formData.unAdaptiveMan" v-show="false"></el-input>
+                                <editor v-model="formData.unAdaptiveMan"></editor>
+                            </el-form-item>
+
+                            <!-- 术前术后 -->
+                            <el-form-item label="术前术后" prop="aroundOperation" class="cm-big-label-el">
+                                <el-input v-model="formData.aroundOperation" v-show="false"></el-input>
+                                <editor v-model="formData.aroundOperation"></editor>
+                            </el-form-item>
+
+                            <!-- 效果展示 -->
+                            <el-form-item label="效果展示" prop="displayImageList" class="cm-big-label-el">
+                                <el-input v-model="formData.displayImageList" v-show="false"></el-input>
+                                <el-upload
+                                        :class="{ 'hide-upload': displayImageList.length >= 8 }"
+                                        :action="action"
+                                        list-type="picture-card"
+                                        :on-preview="handlePictureCardPreview"
+                                        :on-remove="handleDisplayImageRemove"
+                                        :on-success="handleDisplayImageSuccess"
+                                        :file-list="displayImageList"
+                                        :limit="8"
+                                >
+                                    <i class="el-icon-plus"></i>
+                                </el-upload>
+                            </el-form-item>
+
+                            <!-- 常见问题 -->
+                            <el-form-item label="常见问题" prop="questionList" class="cm-big-label-el">
+                                <el-input v-model="formData.questionList" v-show="false"></el-input>
+                                <div class="form-question-group">
+                                    <span class="add-one" @click="addQuestion">添加问答</span>
+                                    <div class="form-question-group-row" v-for="(item, index) in questionEmptyList">
+                                        <div class="cm-label"><em>*</em>问题{{ index + 1}}:</div>
+                                        <el-input placeholder="请输入问题内容" v-model="item.question"></el-input>
+                                        <div class="cm-label"><em>*</em>答:</div>
+                                        <el-input type="textarea" v-model="item.answer" placeholder="请输入问题解答内容"
+                                                  :rows="4"></el-input>
+                                        <span class="remove" v-if="questionEmptyList.length > minLimitQuestions"
+                                              @click="removeQuestion(index)"
+                                        >&times;</span
+                                        >
+                                    </div>
+                                </div>
+                            </el-form-item>
+
+                            <el-form-item label="产品类别" prop="typeId" class="cm-big-label-el">
+                                <el-select class="max-width" v-model="formData.typeId" placeholder="请选择产品类别">
+                                    <el-option v-for="item in typeList" :key="item.typeId" :label="item.typeName"
+                                               :value="item.typeId">
+                                    </el-option>
+                                </el-select>
+                            </el-form-item>
+                            <el-form-item label="" prop="status" label-position="left">
+                                <span class="cm-label"><em>*</em>产品状态:</span>
+                                <el-radio-group v-model="formData.status">
+                                    <el-radio :label="1">启用</el-radio>
+                                    <el-radio :label="0">停用</el-radio>
+                                </el-radio-group>
+                            </el-form-item>
+                        </el-form>
 
-                        <div class="form-item vertical btns">
+                        <div class="btns">
                             <button class="btn break" @click.prevent="handleBack">返回</button>
                             <button class="btn submit" @click.prevent="handleSave">保存</button>
                         </div>
-                    </form>
+                    </div>
                 </div>
             </div>
         </div>
     </div>
+    <!-- 图片预览 -->
+    <el-dialog :visible.sync="dialogVisible">
+        <img width="100%" :src="dialogImageUrl" alt=""/>
+    </el-dialog>
 </div>
 <!-- 引入底部 -->
 <template th:replace="components/footer"></template>
@@ -195,10 +231,10 @@
 <template th:replace="supplier-center/encyclopedia/components/form-component"></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.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/supplier.service.js(v=${version})}"></script>
-<script charset="UTF-8" type="text/javascript" th:src="@{/js/supplier-center/encyclopedia/form-component.js(v=${version})}"></script>
-<script charset="UTF-8" type="text/javascript" th:src="@{/js/supplier-center/encyclopedia/validFormMixin.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/product-edit.js(v=${version})}"></script>
 </body>
 </html>

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio