ソースを参照

采美百科页面接口调试

yuwenjun1997 2 年 前
コミット
c0783aedbd

+ 14 - 0
src/main/java/com/caimei/www/controller/unlimited/EncyclopediaController.java

@@ -37,6 +37,17 @@ public class EncyclopediaController extends BaseController {
         this.productService = productService;
     }
 
+    @GetMapping("/list.html")
+    public String getEncyclopediaHome(){
+        //分类集合
+        List<BaikeTypeVo> typeList = productService.geTypeList();
+        Integer typeId = null;
+        if(null != typeList && typeList.size() > 0){
+            typeId = typeList.get(0).getTypeId();
+        }
+        return "redirect:/encyclopedia/list-"+ typeId +".html";
+    }
+
     /*
      * 百科首页
      * */
@@ -81,6 +92,9 @@ public class EncyclopediaController extends BaseController {
         List<BaikeHotSearch> hotSeracherWords=productService.getHotWords();
         model.addAttribute("hotSeracherWords", hotSeracherWords);
         model.addAttribute("baikeproduct", baikeproduct);
+        //分类集合
+        List<BaikeTypeVo> typeList = productService.geTypeList();
+        model.addAttribute("TypeList", typeList);
         return ENCYCLOPEDIA_DETAIL;
     }
 

+ 17 - 0
src/main/resources/static/css/encyclopedia/detail.css

@@ -1,4 +1,5 @@
 @media screen and (min-width:768px){main{background:#FAFAFA}
+    img.scapegoat{vertical-align: -4px;margin:0 2px; cursor: pointer;}
     .bk-banner{height:320px;position:relative;z-index:10;overflow:hidden}
     .bk-banner img{display:block;height:320px;position:absolute;left:50%;top:0;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}
     .bk-banner .bk-container{position:relative}
@@ -22,10 +23,22 @@
     .bk-literature .bk-title .line{height:1px;background:#BEBEBE;margin-top:16px}
     .bk-literature .bk-literature-list{margin-top:24px}
     .bk-literature .bk-literature-list li{font-size:14px;color:#999999;margin-top:14px;line-height:24px}
+    .bk-literature .bk-literature-list li em{font-style: normal;}
+    .bk-literature .bk-literature-list li i{display: inline-block;width: 16px; height: 16px; background:#F7F7F7 url("/img/encyclopedia/assets/pc-icon-arrowup.png") no-repeat center; background-size: 12px; }
+    .bk-literature .bk-literature-list li a{color: #333;}
+    .bk-literature .bk-literature-list li a.link::after{content: ""; display: inline-block; width: 16px;height: 16px; background: url("/img/encyclopedia/assets/pc-icon-link.png") no-repeat center; background-size: 16px;}
+    .bk-literature .bk-literature-list li a.image::after{content: ""; display: inline-block; width: 16px;height: 16px; background: url("/img/encyclopedia/assets/pc-icon-img.png") no-repeat center; background-size: 16px;}
+    .bk-literature .bk-literature-list li a:after{margin: 0 2px}
+    .bk-literature .bk-literature-list li i,
+    .bk-literature .bk-literature-list li a:after{vertical-align: -3px}
+    .bk-literature .bk-literature-list li a.link:hover{color: #F57C40; text-decoration: underline}
+    .bk-literature .bk-literature-list li a.link:hover::after{background-image: url("/img/encyclopedia/assets/pc-icon-link-hover.png")}
+    .bk-literature .bk-literature-list li a.image:hover::after{background-image: url("/img/encyclopedia/assets/pc-icon-img-hover.png")}
     .bk-pv{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;text-align:right;background:#fff;margin-top:64px;-webkit-column-gap:32px;-moz-column-gap:32px;column-gap:32px}
     .bk-pv .bk-pv-item{font-size:14px;color:#999999}
     .bk-detail-right .bk-album,.bk-detail-right .bk-company{width:280px;height:280px;background:#FAFAFA;margin-bottom:25px}
     .bk-detail-right .bk-album img,.bk-detail-right .bk-company img{display:block;width:280px;height:220px}
+    .bk-detail-right .bk-album video{display:block;width:280px;height:220px}
     .bk-detail-right .bk-album .swiper-container{height:220px}
     .bk-detail-right .bk-album .bk-title,.bk-detail-right .bk-company .bk-title{font-size:18px;color:#333;text-align:center;line-height:58px;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid #DEDEDE;border-top-style:dashed}
     .bk-detail-right .bk-directory{width:280px;background:#FAFAFA;-webkit-box-sizing:border-box;box-sizing:border-box;padding:32px 24px;margin-top:100px;position:sticky;top:280px}
@@ -38,6 +51,7 @@
 }
 
 @media screen and (max-width:768px){.bk-banner{height:3.4rem;position:relative;z-index:10;overflow:hidden}
+    img.scapegoat{vertical-align: -4px;margin:0 2px; cursor: pointer;}
     .bk-banner img{display:block;height:3.4rem;position:absolute;left:50%;top:0;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}
     .bk-detail{-webkit-box-sizing:border-box;box-sizing:border-box;font-size:0.28rem;line-height:0.48rem;background:#F5F5F5}
     .bk-entry-name{padding:0.4rem 0.32rem 0.32rem;background:#fff}
@@ -67,6 +81,7 @@
     .bk-relevant .bk-album .bk-album-list .bk-album-item:first-child{margin-left:0.32rem}
     .bk-relevant .bk-album .bk-album-list .bk-album-item:last-child{margin-right:0.32rem}
     .bk-relevant .bk-album .bk-album-list .bk-album-item img{display:block;width:100%;height:100%}
+    .bk-relevant .bk-album .bk-album-list .bk-album-item video{display:block;width:100%;height:100%}
     .bk-relevant .bk-company{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:1.6rem;padding:0 0.2rem;margin:0 0.32rem 0.8rem;-webkit-box-sizing:border-box;box-sizing:border-box;border:0.01rem solid #DEDEDE;border-radius:0.08rem;background:#FAFAFA}
     .bk-relevant .bk-company .bk-cover{width:1.2rem;height:1.2rem;border-radius:0.08rem;border:0.01rem solid #DEDEDE}
     .bk-relevant .bk-company .bk-cover img{display:block;width:100%;height:100%}
@@ -80,4 +95,6 @@
     .bk-relevant .bk-directory .bk-directory-list li{-ms-flex-negative:0;flex-shrink:0}
     .bk-relevant .bk-directory .bk-directory-list li a{display:block;height:0.6rem;color:#333333;font-size:0.28rem;padding:0 0.16rem;line-height:0.6rem;background:#fff}
     .bk-relevant .bk-directory .bk-directory-list li:last-child{margin-right:0.32rem}
+    .bk-literature .bk-literature-list li em{font-style: normal;}
+    .bk-literature .bk-literature-list li a.link{color: #F57C40; text-decoration: underline}
 }

+ 2 - 0
src/main/resources/static/css/encyclopedia/list.css

@@ -7,6 +7,7 @@
     .bk-list .bk-list-item .bk-info{position:relative;z-index:2;-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-negative:0;flex-shrink:0;margin-left:24px}
     .bk-list .bk-list-item .bk-info h2{font-size:18px;color:#333333;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;-webkit-transition:all .4s;-o-transition:all .4s;transition:all .4s}
     .bk-list .bk-list-item .bk-info p{font-size:14px;color:#666666;margin-top:16px;height:48px;line-height:24px;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
+    .bk-list .bk-list-item .bk-info img{display: none}
     .bk-list .bk-list-item .bk-info .bk-info-footer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:14px;color:#B2B2B2;margin-top:40px}
     .bk-list .bk-list-item::after{content:"";position:absolute;width:1248px;height:216px;border:3px solid #F57C40;left:50%;top:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);z-index:-1;opacity:0;-webkit-transition:all .4s;-o-transition:all .4s;transition:all .4s}
     .bk-list .bk-list-item:hover{cursor:pointer}
@@ -23,5 +24,6 @@
     .bk-list .bk-list-item .bk-info{position:relative;z-index:2;-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-negative:0;flex-shrink:0;margin-left:0.24rem}
     .bk-list .bk-list-item .bk-info h2{font-size:0.32rem;color:#333333;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical}
     .bk-list .bk-list-item .bk-info p{font-size:0.26rem;color:#666666;margin-top:0.16rem;height:0.75rem;line-height:0.375rem;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
+    .bk-list .bk-list-item .bk-info img{display: none}
     .bk-list .bk-list-item .bk-info .bk-info-footer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:0.22rem;color:#B2B2B2;margin-top:0.32rem}
 }

+ 40 - 1
src/main/resources/static/css/supplier-center/encyclopedia/edit.css

@@ -11,7 +11,17 @@
 .valide-form .el-form-item{margin-bottom:24px}
 .valide-form .el-form-item.is-required{margin-bottom:32px}
 .valide-form .el-textarea .el-input__count{line-height:initial}
-.valide-form .bk-label{font-size:14px;color:#4A4F58;font-weight:bold;margin:16px 0 8px}
+.valide-form .bk-label{font-size:14px;color:#4A4F58;font-weight:bold;margin:16px 0 8px;position: relative}
+.valide-form .bk-label .bk-info-add{
+    position: absolute;
+    font-size: 12px;
+    color: #E15616;
+    right: 0;
+    top: 50%;
+    transform: translateY(-50%);
+    text-decoration: underline;
+    cursor: pointer;
+}
 .valide-form .bk-label span,.valide-form .bk-label i{font-weight:normal;font-style:normal}
 .valide-form .bk-label em {color: #f56c6c; font-style: normal}
 .valide-form .bk-label i{color:#FFB496}
@@ -160,6 +170,35 @@
     padding-top: 8px;
     padding-bottom: 8px;
 }
+
+.valide-form .bk-form-item-group{
+    position: relative;
+    display: flex;
+    align-items: center;
+    column-gap: 16px;
+}
+
+.valide-form .bk-form-item-group .el-form-item:first-child{
+    width: 30%;
+    flex-shrink: 0;
+}
+
+.valide-form .bk-form-item-group .el-form-item:last-child{
+    flex: 1;
+    flex-shrink: 0;
+}
+
+.valide-form .bk-form-item-group .bk-info-remove{
+    position: absolute;
+    right: 0;
+    top: 12px;
+    transform: translateX(140%);
+    color: #F94B4B;
+    font-size: 12px;
+    cursor: pointer;
+}
+
+
 .bk-file-upload{
     display: flex;
     align-items: center;

+ 1 - 1
src/main/resources/static/js/common/serviceapi/shopBaike.service.js

@@ -92,7 +92,7 @@ var shopBikeApi = {
     // 保存资料(添加编辑的资料保存按钮
     SaveEntrySumbit: function (params, callback) {
         Http.AjaxService({
-            url: '/commodity/save/referenceInfo',
+            url: '/commodity/save/entry/info',
             type: 'post',
             data: params,
             json: false,

+ 17 - 6
src/main/resources/static/js/encyclopedia/detail.js

@@ -1,10 +1,14 @@
 function directory(container, flag = true) {
+    let h2Index = 0
     $('.bk-section').each(function (index, el) {
-        const hId = 'heading-' + index;
-        $(el).find('h2').attr('id', hId);
-        const name = flag ?  index + 1 + '、' + $(el).find('h2').text() : $(el).find('h2').text();
-        const li = $('<li><a href="javascript:void(0)" data-id="' + hId + '">' + name + '</a></li>');
-        $(container).append(li);
+        if ($(el).find('h2').length > 0) {
+            h2Index+=1
+            const hId = 'heading-' + h2Index;
+            $(el).find('h2').attr('id', hId);
+            const name = flag ? h2Index + '、' + $(el).find('h2').text() : $(el).find('h2').text();
+            const li = $('<li><a href="javascript:void(0)" data-id="' + hId + '">' + name + '</a></li>');
+            $(container).append(li);
+        }
         if (flag && $(el).find('h3').length > 0) {
             const sUl = $(`<ul></ul>`)
             $(li).append(sUl);
@@ -21,7 +25,7 @@ function directory(container, flag = true) {
 $(function () {
     directory('#bk-directory-pc', true)
     directory('#bk-directory-mobile', false)
-    $('.bk-directory-list').find('a').on('click', function(){
+    $('.bk-directory-list').find('a').on('click', function () {
         const id = '#' + $(this).attr('data-id');
         const scrollTop = innerWidth > 768 ? $(id).offset().top - $('header').height() : $(id).offset().top - $('header').height() - $('.bk-directory').height();
         $("html, body").animate({
@@ -29,4 +33,11 @@ $(function () {
         }, {duration: 500, easing: "swing"});
         return false;
     })
+
+    $('img.scapegoat').on('click', function(){
+        const id = $(this).attr('data-ctrid')
+        $("html, body").animate({
+            scrollTop: $('#'+ id).offset().top
+        }, {duration: 500, easing: "swing"});
+    })
 })

+ 138 - 147
src/main/resources/static/js/supplier-center/encyclopedia/components/content-edit/content-edit.js

@@ -1,39 +1,41 @@
-function debounce(func, wait = 100, immediate = false) {
-    let timeout, result
-    return function () {
-        const context = this
-        const args = arguments
-        if (timeout) clearTimeout(timeout)
-        if (immediate) {
-            const callNow = !timeout
-            timeout = setTimeout(function () {
-                timeout = null
-            }, wait)
-            if (callNow) result = func.apply(context, args)
-        } else {
-            timeout = setTimeout(function () {
-                func.apply(context, args)
-            }, wait)
+/** 生成uuid的方法 */
+function uuid(len = 16, radix = 16) {
+    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
+    const value = []
+    let i = 0
+    radix = radix || chars.length
+    if (len) {
+        for (i = 0; i < len; i++) value[i] = chars[0 | (Math.random() * radix)]
+    } else {
+        let r
+        value[8] = value[13] = value[18] = value[23] = '-'
+        value[14] = '4'
+        for (i = 0; i < 36; i++) {
+            if (!value[i]) {
+                r = 0 | (Math.random() * 16)
+                value[i] = chars[i === 19 ? (r & 0x3) | 0x8 : r]
+            }
         }
-        return result
     }
+    return value.join('')
 }
 
-let markCount = 0;
+let markCount = 1
 
-class SelectionManager {
+class ContentEdit {
     constructor(options) {
+        this.options = options
         this.container = document.querySelector(options.el)
         this.hiddenMark = options.hiddenMark
-        this.mouseDownEvn = null
         this.selection = null
         this.range = null
-        // this.markCount = 0 // 标记数量
         this.ctrid = '' // 当前标记id
         this.ctridList = []
         this.registEventListener()
-        this.observe = new MutationObserver(options.observe || function () {});
-        this.observe.observe(this.container, {childList: true, attributes: true, subtree: true});
+    }
+
+    get innerHTML() {
+        return this.container.innerHTML
     }
 
     /** 开始节点 */
@@ -53,8 +55,9 @@ class SelectionManager {
 
     /** 开始节点与结束接单公共父节点 */
     get commonNode() {
-        const {commonAncestorContainer} = this.range
-        return this.isTextNode(commonAncestorContainer) ? commonAncestorContainer.parentNode : commonAncestorContainer
+        return this.isTextNode(this.range.commonAncestorContainer)
+            ? this.range.commonAncestorContainer.parentNode
+            : this.range.commonAncestorContainer
     }
 
     /** 开始节点的最外层节点 */
@@ -74,23 +77,71 @@ class SelectionManager {
         return this.nextUntil(this.startNode, this.endNode)
     }
 
+    initCtridList(){
+        const nodeList = this.container.querySelectorAll('.scapegoat')
+        nodeList.forEach((node) => {
+            const id = node.getAttribute('data-ctrid')
+            if (!this.ctridList.includes(id)){
+                this.ctridList.push(id)
+            }
+        })
+    }
+
+    /** 文本选中变动 */
+    selectionChange() {
+        this.selection = document.getSelection()
+        if (this.selection.type.toLowerCase() !== 'range') return
+        this.range = this.selection.getRangeAt(0)
+    }
+
     /** 包裹 */
-    parcel(ctrid) {
-        markCount++
-        this.ctrid = ctrid ? ctrid : this.uuid()
+    parcel(ctrid, index) {
+        this.ctrid = ctrid ? ctrid : uuid()
+        this.markNum = index
+        this.ctridList.push(this.ctrid)
         try {
-            this.ctridList.push(this.ctrid)
             this.parcelNode(this.commonNode, this.centerNodes)
             this.parcelStartNode(this.startContainer)
             this.parcelEndNode(this.endContainer)
             this.parcelNodeContent()
             this.selection.removeAllRanges()
+            this.options.change && this.options.change(this.innerHTML)
+            if(!this.markNum){
+                markCount++
+            }
             return this.ctrid
         } catch (e) {
             return this.ctrid
         }
     }
 
+    /** 包裹元素 */
+    parcelNode(container, nodeList = []) {
+        if (nodeList.length === 0) return
+        const parcel = this.createParcel()
+        container.insertBefore(parcel, nodeList[0])
+        nodeList.forEach((node) => {
+            container.removeChild(node)
+            parcel.appendChild(node)
+        })
+    }
+
+    /** 包裹开始元素 */
+    parcelStartNode(node) {
+        if (node === this.commonNode) return
+        if (node === this.startNode) return
+        this.parcelNode(node.parentNode, this.nextAll(node))
+        this.parcelStartNode(node.parentNode)
+    }
+
+    /** 包裹结束元素 */
+    parcelEndNode(node) {
+        if (node === this.commonNode) return
+        if (node === this.endNode) return
+        this.parcelNode(node.parentNode, this.prevAll(node))
+        this.parcelEndNode(node.parentNode)
+    }
+
     /** 包裹开始结束节点内容 */
     parcelNodeContent() {
         const mark = this.createMark()
@@ -125,90 +176,39 @@ class SelectionManager {
         }
     }
 
-    /** 包裹开始元素 */
-    parcelStartNode(node) {
-        if (node === this.commonNode) return
-        if (node === this.startNode) return
-        this.parcelNode(node.parentNode, this.nextAll(node))
-        this.parcelStartNode(node.parentNode)
-    }
-
-    /** 包裹结束元素 */
-    parcelEndNode(node) {
-        if (node === this.commonNode) return
-        if (node === this.endNode) return
-        this.parcelNode(node.parentNode, this.prevAll(node))
-        this.parcelEndNode(node.parentNode)
-    }
-
-    /** 包裹元素 */
-    parcelNode(container, nodeList = []) {
-        if (nodeList.length === 0) return
-        const parcel = this.createParcel()
-        container.insertBefore(parcel, nodeList[0])
+    /** 标记清除 */
+    unParcel(ctrid) {
+        this.ctridList = this.ctridList.filter((item) => item !== ctrid)
+        const nodeList = this.container.querySelectorAll('.scapegoat')
         nodeList.forEach((node) => {
-            container.removeChild(node)
-            parcel.appendChild(node)
+            const id = node.getAttribute('data-ctrid')
+            if (id !== ctrid) return
+            const parentNode = node.parentNode
+            if (node.nodeName === 'IMG') {
+                parentNode.removeChild(node)
+            } else if (node.nodeName === 'SPAN') {
+                const fragment = this.createFragment(node.childNodes)
+                parentNode.replaceChild(fragment, node)
+            }
+            // 清除空节点
+            parentNode.normalize()
         })
-    }
-
-    /** 文本选中变动 */
-    selectionChange = debounce((e) => {
-        this.selection = document.getSelection()
-        if (this.selection.type.toLowerCase() !== 'range') return
-        this.range = this.selection.getRangeAt(0)
-    })
-
-    /** 获取节点元素 */
-    getTopNode(parent, node) {
-        if (parent === node.parentNode) return node
-        return this.getTopNode(parent, node.parentNode)
-    }
-
-    /** 开始节点与结束节点之间的节点列表 */
-    nextUntil(startNode, endNode) {
-        if (startNode.nextSibling === endNode) return []
-        return [startNode.nextSibling, ...this.nextUntil(startNode.nextSibling, endNode)]
-    }
-
-    /** 获取紧接着之后兄弟节点 */
-    nextAll(node) {
-        if (!node.nextSibling) return []
-        return [node.nextSibling, ...this.nextAll(node.nextSibling)]
-    }
-
-    /** 获取紧接着之前的兄弟节点 */
-    prevAll(node) {
-        if (!node.previousSibling) return []
-        return [node.previousSibling, ...this.prevAll(node.previousSibling)]
-    }
-
-    /** 是文本节点 */
-    isTextNode(node) {
-        return node.nodeType === 3
-    }
-
-    /** 创建包裹元素 */
-    createParcel() {
-        const parcel = document.createElement('span')
-        parcel.classList.add('scapegoat')
-        parcel.setAttribute('data-ctrid', this.ctrid)
-        return parcel
+        this.options.change && this.options.change(this.innerHTML)
+        this.ctridList = this.ctridList.filter(item => item !== ctrid)
     }
 
     /** 创建标记 */
     createMark() {
+        if (this.hiddenMark) return document.createDocumentFragment()
         const img = document.createElement('img')
+        const index = this.markNum || markCount
         img.classList.add('scapegoat')
         img.setAttribute('height', 20)
         img.setAttribute('data-ctrid', this.ctrid)
-        img.setAttribute('src', `https://baikebcs.bdimg.com/cms/wiki-react-editor/ref/${markCount}.svg`)
+        img.setAttribute('src', `https://baikebcs.bdimg.com/cms/wiki-react-editor/ref/${index}.svg`)
         img.addEventListener('mouseover', (e) => this.markMouseOver(e))
         img.addEventListener('mouseleave', (e) => this.markMouseLeave(e))
         img.addEventListener('click', (e) => this.markMouseClick(e))
-        if (this.hiddenMark) {
-            img.style.display = 'none';
-        }
         return img
     }
 
@@ -245,61 +245,52 @@ class SelectionManager {
         })
     }
 
-    /** 标记点击事件 */
-    markMouseClick(e) {
-        const ctrid = e.target.getAttribute('data-ctrid')
-        this.markRemove(ctrid)
-    }
-
-    /** 标记清除 */
-    markRemove(ctrid) {
-        markCount--
-        this.ctridList = this.ctridList.filter(item => item !== ctrid);
-        const nodeList = this.container.querySelectorAll('.scapegoat')
-        nodeList.forEach((node) => {
-            const id = node.getAttribute('data-ctrid')
-            if (id !== ctrid) return
-            const parentNode = node.parentNode
-            if(node.nodeName === 'IMG'){
-                parentNode.removeChild(node)
-            }else if(node.nodeName === 'SPAN'){
-                const fragment = this.createFragment(node.childNodes)
-                parentNode.replaceChild(fragment, node)
-            }
-            parentNode.normalize() // 清除空节点
-        })
-    }
-
     /* 注册事件监听 */
     registEventListener() {
         // 获取文本选中
         this.container.addEventListener('focus', () => {
-            document.addEventListener('selectionchange', this.selectionChange)
+            document.addEventListener('selectionchange', () => this.selectionChange())
         })
         this.container.addEventListener('blur', () => {
-            document.removeEventListener('selectionchange', this.selectionChange)
+            this.options.change && this.options.change(this.innerHTML)
+            document.removeEventListener('selectionchange', () => this.selectionChange())
         })
     }
 
-    /** 生成uuid的方法 */
-    uuid(len = 8, radix = 16) {
-        const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
-        const value = []
-        let i = 0
-        radix = radix || chars.length
-        if (len) {
-            for (i = 0; i < len; i++) value[i] = chars[0 | (Math.random() * radix)]
-        } else {
-            let r
-            value[8] = value[13] = value[18] = value[23] = '-'
-            value[14] = '4'
-            for (i = 0; i < 36; i++) {
-                if (!value[i]) {
-                    r = 0 | (Math.random() * 16)
-                    value[i] = chars[i === 19 ? (r & 0x3) | 0x8 : r]
-                }
-            }
-        }
-        return value.join('')
+    /** 获取节点元素 */
+    getTopNode(parent, node) {
+        if (parent === node.parentNode) return node
+        return this.getTopNode(parent, node.parentNode)
+    }
+
+    /** 开始节点与结束节点之间的节点列表 */
+    nextUntil(startNode, endNode) {
+        if (startNode.nextSibling === endNode) return []
+        return [startNode.nextSibling, ...this.nextUntil(startNode.nextSibling, endNode)]
+    }
+
+    /** 获取紧接着之后兄弟节点 */
+    nextAll(node) {
+        if (!node.nextSibling) return []
+        return [node.nextSibling, ...this.nextAll(node.nextSibling)]
+    }
+
+    /** 获取紧接着之前的兄弟节点 */
+    prevAll(node) {
+        if (!node.previousSibling) return []
+        return [node.previousSibling, ...this.prevAll(node.previousSibling)]
+    }
+
+    /** 是文本节点 */
+    isTextNode(node) {
+        return node.nodeType === 3
+    }
+
+    /** 创建包裹元素 */
+    createParcel() {
+        const parcel = document.createElement('span')
+        parcel.classList.add('scapegoat')
+        parcel.setAttribute('data-ctrid', this.ctrid)
+        return parcel
     }
 }

+ 26 - 32
src/main/resources/static/js/supplier-center/encyclopedia/components/content-edit/index.js

@@ -4,8 +4,8 @@ const contentEdit = {
     template: `
     <div class="el-input" :id="editId">
         <div class="bk-toolbar" @click="handleToolBarClick" v-show="isFocus"></div>
-        <div class="bk-bubble" @click="handleBubbleClick" v-if="bubbleNum>0">{{bubbleNum}}</div>
-        <div class="el-input__inner bk-input" contenteditable="true" @focus="onFocus" @blur="onBlur" @input="onInput"></div>
+        <div class="bk-bubble" @click="handleBubbleClick" v-show="bubbleNum>0">{{bubbleNum}}</div>
+        <div class="el-input__inner bk-input" contenteditable="true" @focus="isFocus = true" @blur="onBlur" v-html="value"></div>
         <ul class="bk-literature" v-show="showBubble && bubbleNum>0">
             <li v-for="item in refList" :key="item.ctrlId">
                 <div>{{item | reference}}</div>
@@ -25,6 +25,10 @@ const contentEdit = {
             return data.referenceDescription + '.' + data.imageDescription
         }
     },
+    model: {
+        event: 'change',
+        prop: 'value'
+    },
     props: {
         referenceList: {
             type: Array,
@@ -33,27 +37,23 @@ const contentEdit = {
         value: {
             type: String,
             default: ''
-        }
-    },
-    model: {
-        event: 'change',
-        prop: 'value'
-    },
-    computed: {
-        refList() {
-            if (!this.sm) return []
-            return this.referenceList.filter(item => this.sm.ctridList.includes(item.ctrlId))
         },
-        bubbleNum() {
-            return this.refList.length
-        }
     },
     data() {
         return {
             editId: `myEdit` + ++editIdIndex,
             isFocus: false,
             showBubble: false,
-            sm: null
+            contentEdit: null
+        }
+    },
+    computed: {
+        refList() {
+            if (!this.contentEdit) return []
+            return this.referenceList.filter(item => this.contentEdit.ctridList.includes(item.ctrlId))
+        },
+        bubbleNum() {
+            return this.refList.length
         }
     },
     mounted() {
@@ -62,18 +62,16 @@ const contentEdit = {
     methods: {
         // 初始化
         initEdit() {
-            this.sm = new SelectionManager({
+            this.contentEdit = new ContentEdit({
                 el: `#${this.editId} .bk-input`,
-                hiddenMark: true,
-                observe: () => {
-                    console.log(this.sm.container.innerHTML)
-                    this.$emit('change', this.sm.container.innerHTML);
+                hiddenMark: false,
+                change: (html) => {
+                    this.$emit('change', html)
                 }
             })
-        },
-        // 获取焦点
-        onFocus() {
-            this.isFocus = true
+            setTimeout(()=>{
+                this.contentEdit.initCtridList()
+            }, 1000)
         },
         // 失去焦点
         onBlur() {
@@ -83,20 +81,16 @@ const contentEdit = {
         },
         // 工具栏点击
         handleToolBarClick() {
-            this.$emit('toolbar', this.sm)
-        },
-        // 用户输入事件
-        onInput(e) {
-            this.$emit('change', e.target.innerHTML);
+            this.$emit('toolbar', this.contentEdit)
         },
         // 气泡点击
         handleBubbleClick() {
             if (this.bubbleNum === 0) return
-            this.showBubble = true
+            this.showBubble = !this.showBubble
         },
         // 删除标记点
         handleDeleteReference(item) {
-            this.sm.markRemove(item.ctrlId);
+            this.contentEdit.unParcel(item.ctrlId)
         }
     }
 }

+ 277 - 69
src/main/resources/static/js/supplier-center/encyclopedia/edit.js

@@ -119,79 +119,62 @@ const edit = new Vue({
     },
     data: {
         isPC: window.innerWidth > 768,
-        referenceType: 1,
-        dateType: 1,
-        referenceDialog: false,
-        referenceEditType: 'add',
-        sm: null,
+        referenceType: 1, // 添加 | 引用参考资料类型
+        referenceDialog: false, // 参考资料表单弹窗
+        referenceEditType: 'add', // 参考资料编辑类型 add 添加 edit 编辑
+        contentEdit: null, // 编辑器
+        // 提交表单数据
         formData: {
+            authUserId:'',
             id: '', // 词条id
             name: '', // 词条名称
             alias: '', // 义项名
-            description: '', // 词条概述
-            img: '', // 头图地址
+            discription: '', // 词条概述
+            image: '', // 头图地址
             typeId: '', // 分类id
             seoKeyword: '', // seo关键字
             status: 0, // 状态0保存草稿箱  1已发布
-            imageList: [], // 概述图册集合
             infoList: [], //  信息栏集合
             referenceList: [], // 参考资料集合
+            textInfoList: [],
+            imageList: [], // 概述图册集合
             videoList: [], // 视频集合
         },
+        // 提交表单校验
         rules: {
             name: [{required: true, message: '词条名称不能为空', trigger: ['blur']}],
             alias: [{required: true, message: '词条名称不能为空', trigger: ['change']}],
-            description: [{required: true, message: '词条名称不能为空', trigger: ['change']}],
+            discription: [{required: true, message: '词条名称不能为空', trigger: ['change']}],
             img: [{required: true, message: '请上传词条头图', trigger: ['change']}],
+            typeId: [{required: true, message: '请选择词条分类', trigger: ['change']}],
+            status: [{required: true, message: '请选择词条发布状态', trigger: ['change']}],
         },
-        referenceList: [{
-            id: 1,
-            ctrlId: 'SDAJKLJ4642', // 关联id
-            /* (网络资料) */
-            referenceType: 1, // '参考类型资料(1.网络;2.著作;3.其他)'
-            website: '网址',
-            articleName: '文章名称',
-            websiteName: '网址名称',
-            publishTimeStr: '发表时间',
-            acitationTimeStr: '引文时间',
-            /* 著作资料)*/
-            author: '作者',
-            workName: '著作名',
-            publicationPlace: '出版地',
-            press: '出版社',
-            publicationYearStr: '出版年',
-            acitationWeb: '引文编码',
-            /* (其他资料) */
-            referenceDescription: '参考资料说明',
-            imageDescription: '图片描述',
-            imageUrl: '图片地址',
-            entryId: '词条id',
-            entryType: '词条类型(先不传)'
-        }],
+        // 参考资料信息表单
         referenceData: {
             id: 1,
             ctrlId: '', // 关联id
             /* (网络资料) */
             referenceType: 1, // '参考类型资料(1.网络;2.著作;3.其他)'
-            website: '网址',
-            articleName: '文章名称',
-            websiteName: '网址名称',
-            publishTimeStr: '发表时间',
-            acitationTimeStr: '引文时间',
+            website: '',
+            articleName: '',
+            websiteName: '',
+            publishTimeStr: '',
+            acitationTimeStr: '',
             /* 著作资料)*/
-            author: '作者',
-            workName: '著作名',
-            publicationPlace: '出版地',
-            press: '出版社',
-            publicationYearStr: '出版年',
-            acitationWeb: '引文编码',
+            author: '',
+            workName: '',
+            publicationPlace: '',
+            press: '',
+            publicationYearStr: '',
+            acitationWeb: '',
             /* (其他资料) */
-            referenceDescription: '参考资料说明',
-            imageDescription: '图片描述',
-            imageUrl: '图片地址',
-            entryId: '词条id',
-            entryType: '词条类型(先不传)'
+            referenceDescription: '',
+            imageDescription: '',
+            imageUrl: '',
+            entryId: '',
+            entryType: ''
         },
+        // 参考资料表单规则校验
         referenceRule: {
             referenceType: [{required: true, message: '请选择参考类型资料', trigger: ['change']}],
             website: [{required: true, message: '请输入网址', trigger: ['blur']}],
@@ -203,46 +186,216 @@ const edit = new Vue({
             publicationYearStr: [{required: true, message: '请输入出版年', trigger: ['blur']}],
             referenceDescription: [{required: true, message: '请输入参考资料说明', trigger: ['blur']}],
         },
+        // 上传文件列表
         fileList: [],
-        coverList: []
+        // 上传封面列表
+        coverList: [],
+        //词条类型列表
+        typeList: [],
+        // 敏感词校验数据
+        formValidate: {}
+    },
+    created() {
+        this.formData.id = CAIMEI.getUrlParam('id')
+        this.fetchTypeList()
+        // 如果是编辑就获取表单数据
+        if(this.formData.id){
+            this.fetchEntryData()
+        }else{
+            this.initFormDataList()
+        }
+    },
+    mounted(){
+        $('.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: {
+        // 获取表单数据
+        fetchEntryData(){
+            const self = this
+            shopBikeApi.FetchEntryDetail({id: this.formData.id}, function(res){
+                self.initFormData(res.data)
+            })
+        },
+        // 初始化表单数据
+        initFormData(data){
+            for (const key in this.formData) {
+                if(data.hasOwnProperty(key)){
+                    this.formData[key] = data[key]
+                }
+            }
+            const imageList = this.formData.imageList.map(item =>{
+                return {url: item.image, type: 'image'}
+            })
+            const videoList = this.formData.videoList.map(item =>{
+                return {fileName: item.fileName, uuid: item.ossName, url: item.url, type: 'video'}
+            })
+            this.fileList = [...imageList, ...videoList]
+            if(this.formData.image){
+                this.coverList = [{ url: this.formData.image, type: 'image' }]
+            }
+            const infoSize = 4 - this.formData.infoList.length
+            const textInfoSize = 4 - this.formData.textInfoList.length
+            this.initFormDataList( infoSize, textInfoSize)
+        },
+
+        // 获取图片列表
+        filterImageList(fileList) {
+            const imageList = fileList.filter(file => file.type.indexOf('image') > -1)
+            return imageList.map(file => ({entryId: '', image: file.url}))
+        },
+        // 获取视频列表
+        filterVideoList(fileList) {
+            const imageList = fileList.filter(file => file.type.indexOf('video') > -1)
+            return imageList.map(file => ({
+                entryId: '',
+                fileTitle: file.fileName,
+                fileName: file.fileName,
+                ossName: file.uuid,
+                ossUrl: file.url
+            }))
+        },
+        // 提交表单
+        async handleConfirm() {
+            try {
+                this.formData.authUserId = GLOBAL_SHOP_ID
+                this.formData.imageList = this.filterImageList(this.fileList)
+                this.formData.videoList = this.filterVideoList(this.fileList)
+                await this.$refs.ruleForm.validate()
+                const params = {
+                    id: this.formData.id, // 词条id
+                    name: this.formData.name, // 词条名称
+                    alias: this.formData.alias, // 义项名
+                    discription: this.formData.discription, // 词条概述
+                    image: this.formData.image, // 头图地址
+                    typeId: this.formData.typeId, // 分类id
+                    seoKeyword: this.formData.seoKeyword, // seo关键字
+                    status: this.formData.status, // 状态0保存草稿箱  1已发布
+                    infoListStr: JSON.stringify(this.formData.infoList), //  信息栏集合
+                    referenceListStr:JSON.stringify(this.formData.referenceList), // 参考资料集合
+                    textInfoListStr: JSON.stringify(this.formData.textInfoList),
+                    imageListStr: JSON.stringify(this.formData.imageList), // 概述图册集合
+                    videoListStr:JSON.stringify(this.formData.videoList), // 视频集合
+                };
+                this.sensitiveWordsValidate(params)
+            } catch (e) {
+                console.log(e)
+                this.socrllToErrorWord()
+            }
+        },
+        /// 确定提交
+        onReallySave(params) {
+            const self = this
+            shopBikeApi.SaveEntrySumbit(params, function (res) {
+                CAIMEI.dialog('词条保存成功', false);
+                setTimeout(function () {
+                    self.handleBack()
+                }, 500)
+            })
+        },
+        // 获取词条分类
+        fetchTypeList() {
+            const slef = this
+            shopBikeApi.FetchTypeList(function (res) {
+                slef.typeList = res.data
+            })
+        },
+
+        // 初始化表单列表项数据
+        initFormDataList(infoSize = 4, textInfoSize = 4) {
+            for (let i = 0; i < infoSize; i++) {
+                this.formData.infoList.push(this.genereateInfo())
+            }
+            for (let i = 1; i < textInfoSize; i++) {
+                this.formData.textInfoList.push(this.genereateTextInfo(i))
+            }
+        },
+
         // ref dialog 隐藏
         handleRefDialogClose() {
             this.referenceDialog = false
             this.referenceType = 1
         },
         // 提交确定ref
-        handleConfirmReference() {
-            if (this.referenceEditType === 'add') {
-                this.referenceData.ctrlId = this.sm.parcel()
-                this.referenceList.push(deepClone(this.referenceData))
-            } else {
-                const index = this.referenceList.findIndex(ref => ref.ctrlId === this.referenceData.ctrlId);
-                this.referenceList.splice(index, 1, deepClone(this.referenceData))
+        async handleConfirmReference() {
+            try {
+                await this.$refs.referenceForm.validate()
+                if (this.referenceEditType === 'add') {
+                    this.referenceData.ctrlId = this.contentEdit.parcel()
+                    this.formData.referenceList.push(deepClone(this.referenceData))
+                } else {
+                    const index = this.formData.referenceList.findIndex(ref => ref.ctrlId === this.referenceData.ctrlId);
+                    this.formData.referenceList.splice(index, 1, deepClone(this.referenceData))
+                }
+                this.referenceDialog = false
+                this.referenceEditType = 'add'
+            } catch (e) {
+                console.log(e)
             }
-            this.referenceDialog = false
-            this.referenceEditType = 'add'
         },
-        handleSelectReference(item) {
+        handleSelectReference(item, index) {
             this.referenceDialog = false
-            this.sm.parcel(item.ctrlId)
+            this.contentEdit.parcel(item.ctrlId, index+1)
+        },
+        handleReferenceTypeChange(){
+            this.$refs.referenceForm.resetFields()
         },
         // ref tab 切换
         handleTabChange(index) {
             this.referenceType = index;
         },
+        // 新增参考资料,从已有参考资料选取
         handleToolbarClick(e) {
-            this.sm = e
+            this.contentEdit = e
             this.referenceDialog = true
         },
+        // 参考资料修改
         handleReferenceEdit(item) {
             this.referenceEditType = 'edit'
-            this.referenceData = item
+            this.referenceData = deepClone(item)
             this.referenceDialog = true
         },
+        // 参考资料删除
         handleReferenceDelete(item) {
-            this.referenceList = this.referenceList.filter(ref => ref.ctrlId !== item.ctrlId)
+            this.formData.referenceList = this.formData.referenceList.filter(ref => ref.ctrlId !== item.ctrlId)
+        },
+        // 信息栏数据
+        genereateInfo() {
+            return {
+                entryId: '',
+                infoName: '',
+                infoContent: '',
+            }
+        },
+        // 新增信息栏
+        handleInfoAdd() {
+            this.formData.infoList.push(this.genereateInfo())
+        },
+        // 删除信息栏
+        handleInfoRemove(index) {
+            this.formData.infoList.splice(index, 1)
+        },
+        // 正文目录数据
+        genereateTextInfo(type) {
+            let placeholderList = ['定义(一级目录)', '定义(二级目录)', '内容']
+            return {
+                id: '',
+                entryId: '',
+                dictionaryContent: '',
+                dictionaryType: type,
+                referenceId: '',
+                textType: '',
+                parentId: '',
+                placeholder: placeholderList[type - 1]
+            }
+        },
+        // 添加正文目录
+        handleAddTextInfo(index, type) {
+            this.formData.textInfoList.splice(index + 1, 0, this.genereateTextInfo(type))
+        },
+        // 删除正文目录
+        handleRemoveTextInfo(index, type) {
+            this.formData.textInfoList.splice(index, 1)
         },
         // 文件上传成功
         handleUploadSuccess(fileList) {
@@ -255,15 +408,70 @@ const edit = new Vue({
         // 封面上传成功
         handleCoverUploadSuccess(fileList) {
             this.coverList = fileList
-            this.formData.img = fileList[0].url
+            this.formData.image = fileList[0].url
         },
         // 封面删除
         handleCoverRemove(file) {
-            this.formData.img = ''
+            this.formData.image = ''
             this.coverList = this.coverList.filter(item => item.uuid !== file.uuid);
         },
-        handleContentEditChange(html) {
-            console.log(html)
-        }
+        // 返回文章列表页面
+        handleBack() {
+            window.open('/supplier/encyclopedia/list.html', 'supplier-entry-list');
+            window.close();
+        },
+        // 敏感词校验
+        sensitiveWordsValidate(params) {
+            const whiteList = [];
+            const self = this;
+            SupplierApi.ShopBaikeProductWordsValidate({checkPoint: 2}, function (res) {
+                let flag = true
+                for (const key in params) {
+                    if (!whiteList.includes(key)) {
+                        const target = JSON.stringify(params[key])
+                        const bool = new RegExp(res.data, 'g').test(target)
+                        if (bool) {
+                            const value = self.matchWords(target, res.data)
+                            self.formValidate[key] = value
+                            flag = false
+                        } else {
+                            self.formValidate[key] = ''
+                        }
+                    }
+                }
+                if (flag) return self.onReallySave(params)
+                const tip = '当前发布内容存在敏感词,已为您标记在输入框下方,请修改后,再进行保存发布,强行保存发布将会导致审核不通过!'
+                self.$confirm(tip, '提示', {confirmButtonText: '保存', cancelButtonText: '取消'}).then(function () {
+                    self.onReallySave(params)
+                }).catch(function () {
+                    console.log('修改敏感词')
+                    self.socrllToErrorWord() // 滚动到提示处
+                })
+            })
+        },
+
+        // 匹配敏感词
+        matchWords(word, validate) {
+            const list = []
+            const matcher = word.matchAll(new RegExp(validate, 'g'))
+            let done = false
+            while (!done) {
+                const item = matcher.next()
+                done = item.done
+                if (item.value) {
+                    list.push(item.value[0])
+                }
+            }
+            return list.join(',')
+        },
+
+        socrllToErrorWord() {
+            this.$nextTick(() => {
+                const scrollTop = $('.el-form-item__error').eq(0).parents('.el-form-item').offset().top
+                $('body,html').animate({
+                    scrollTop: scrollTop - $('#globalHead').height() - 60
+                }, 800)
+            })
+        },
     }
 })

+ 15 - 5
src/main/resources/static/js/supplier-center/encyclopedia/list.js

@@ -7,7 +7,7 @@ const list = new Vue({
         }
     },
     data: {
-        name: 'supplier-entry-list',
+        windowName: 'supplier-entry-list',
         isPC: window.innerWidth > 768,
         listQuery: {
             id: '', //词条id
@@ -42,7 +42,7 @@ const list = new Vue({
         this.fetchEntryTypeList()
     },
     mounted() {
-        window.name = this.name;
+        window.name = this.windowName
         $('.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");
     },
@@ -59,6 +59,12 @@ const list = new Vue({
         },
         getList() {
             const self = this
+            if(this.listQuery.pageNum > this.totalPage){
+                this.listQuery.pageNum = this.totalPage
+            }
+            if(this.listQuery.pageNum < 1){
+                this.listQuery.pageNum = 1
+            }
             shopBikeApi.FetchEntryList(this.listQuery, function (res) {
                 self.list = res.data.results
                 self.totalPage = res.data.totalPage
@@ -73,7 +79,7 @@ const list = new Vue({
         handlePublishEntry(item) {
             const self = this
             shopBikeApi.UpdateEntryStatus({id: item.id, status: 1}, function (res) {
-                CAIMEI.dialog('词条已保存到草稿箱', false);
+                CAIMEI.dialog('词条已发布', false);
                 self.getList()
             })
         },
@@ -81,7 +87,7 @@ const list = new Vue({
         handleStorageEntry(item) {
             const self = this
             shopBikeApi.UpdateEntryStatus({id: item.id, status: 0}, function (res) {
-                CAIMEI.dialog('词条已发布', false);
+                CAIMEI.dialog('词条已保存到草稿箱', false);
                 self.getList()
             })
         },
@@ -90,7 +96,11 @@ const list = new Vue({
             window.open('/supplier/encyclopedia/edit.html?id=' + item.id);
         },
         // 词条详情
-        handleDetailEntry() {
+        handleDetailEntry(item) {
+            if (item.auditStatus !== 2) return CAIMEI.dialog('请等待审核通过后查看!');
+            if (item.onlineStatus !== 2) return CAIMEI.dialog('请等待上线后查看!');
+            if (!item.status) return CAIMEI.dialog('请发布后查看!');
+            window.open('/encyclopedia/detail-' + item.id + '.html');
         },
         // 删除词条
         handleRemoveEntry(item) {

+ 8 - 10
src/main/resources/templates/encyclopedia/components/header.html

@@ -2,7 +2,7 @@
     <div class="bk-header">
         <div class="bk-container">
             <div class="bk-logo">
-                <a href="/encyclopedia/list.html" title="采美百科">
+                <a th:href="'/encyclopedia/list.html'" title="采美百科">
                     <h1>采美百科</h1>
                     <img src="/img/encyclopedia/assets/pc-logo.png" alt="采美百科" class="only-pc"/>
                     <img src="/img/encyclopedia/assets/h5-logo.png" alt="采美百科" class="only-mobile"/>
@@ -25,21 +25,19 @@
                     </div>
                 </form>
                 <ul class="bk-hot-keyword">
-                    <li><a href="#">MD果酸</a></li>
-                    <li><a href="#">无针水光</a></li>
-                    <li><a href="#">光子嫩肤</a></li>
-                    <li><a href="#">光子嫩肤</a></li>
+                    <li th:each="item : ${hotSeracherWords}" th:object="${item}">
+                        <a th:href="'/encyclopedia/search.html?keyword=' + *{keyWord}" th:if="*{jumpType eq 1}" th:text="*{keyWord}"></a>
+                        <a th:href="*{jumpLink}" th:if="*{jumpType eq 4}" th:text="*{keyWord}"></a>
+                    </li>
                 </ul>
             </div>
         </div>
     </div>
     <div class="bk-nav">
         <ul class="bk-navbar bk-container">
-            <li class="active"><a href="#">抗衰除皱</a></li>
-            <li><a href="#">术后修复</a></li>
-            <li><a href="#">光子嫩肤</a></li>
-            <li><a href="#">瘦身美容</a></li>
-            <li><a href="#">易耗品</a></li>
+            <li th:each="item : ${TypeList}" th:object="${item}">
+                <a th:href="'/encyclopedia/list-' + *{typeId} + '.html'" th:text="*{name}"></a>
+            </li>
             <li><a href="/encyclopedia/about.html">走进百科</a></li>
         </ul>
     </div>

+ 57 - 113
src/main/resources/templates/encyclopedia/detail.html

@@ -22,69 +22,38 @@
         <img src="/img/encyclopedia/assets/pc-banner-detail.png" alt="采美百科" class="only-pc"/>
         <img src="/img/encyclopedia/assets/h5-banner-detail.png" alt="采美百科" class="only-mobile"/>
         <div class="bk-container only-pc">
-            <div class="bk-name">透明质酸</div>
+            <div class="bk-name" th:text="${baikeproduct.name}"></div>
         </div>
     </div>
-    <div class="bk-detail bk-container">
+    <div class="bk-detail bk-container" th:object="${baikeproduct}">
         <div class="only-mobile bk-entry-name">
-            <div class="bk-name">透明质酸</div>
+            <div class="bk-name" th:text="*{name}"></div>
         </div>
         <div class="bk-detail-left">
-            <div class="bk-name">玻尿酸</div>
-            <div class="bk-overview">透明质酸,又称玻尿酸,分子式是(C14H21NO11)n,是D-葡萄糖醛酸及N-乙酰葡糖胺组成的双糖单位糖胺聚糖。</div>
+            <div class="bk-name" th:utext="*{alias}"></div>
+            <div class="bk-overview" th:utext="*{discription}"></div>
             <div class="bk-information only-pc">
-                <div class="bk-row">
-                    <div class="bk-label">中文名</div>
-                    <div class="bk-content">透明质酸</div>
-                    <div class="bk-label">化学式</div>
-                    <div class="bk-content">(C14H21NO11)n</div>
-                </div>
-                <div class="bk-row">
-                    <div class="bk-label">外文名</div>
-                    <div class="bk-content">hyaluronic acid</div>
-                    <div class="bk-label">CAS登录号</div>
-                    <div class="bk-content">9004-61-9</div>
-                </div>
-                <div class="bk-row">
-                    <div class="bk-label">别名</div>
-                    <div class="bk-content">玻尿酸</div>
-                    <div class="bk-label">安全性描述</div>
-                    <div class="bk-content">S22;S24/25</div>
+                <div class="bk-row" th:each="row : *{infoListPC}">
+                    <th:block th:each="col : ${row}">
+                        <div class="bk-label" th:text="${col.infoName}"></div>
+                        <div class="bk-content" th:utext="${col.infoContent}"></div>
+                    </th:block>
                 </div>
             </div>
             <div class="bk-information only-mobile">
-                <div class="bk-row">
-                    <div class="bk-label">中文名</div>
-                    <div class="bk-content">透明质酸</div>
-                </div>
-                <div class="bk-row">
-                    <div class="bk-label">化学式</div>
-                    <div class="bk-content">(C14H21NO11)n</div>
-                </div>
-                <div class="bk-row">
-                    <div class="bk-label">外文名</div>
-                    <div class="bk-content">hyaluronic acid</div>
-                </div>
-                <div class="bk-row">
-                    <div class="bk-label">CAS登录号</div>
-                    <div class="bk-content">9004-61-9</div>
-                </div>
-                <div class="bk-row">
-                    <div class="bk-label">别名</div>
-                    <div class="bk-content">玻尿酸</div>
-                </div>
-                <div class="bk-row">
-                    <div class="bk-label">安全性描述</div>
-                    <div class="bk-content">S22;S24/25</div>
+                <div class="bk-row" th:each="item :*{infoList}">
+                    <div class="bk-label" th:text="${item.infoName}"></div>
+                    <div class="bk-content" th:utext="${item.infoContent}"></div>
                 </div>
             </div>
             <div class="only-mobile bk-relevant">
                 <div class="bk-album">
                     <div class="bk-title">透明质酸的概述图册</div>
                     <div class="bk-album-list">
-                        <div class="bk-album-item"><img src="https://picsum.photos/280/220?random=1"></div>
-                        <div class="bk-album-item"><img src="https://picsum.photos/280/220?random=2"></div>
-                        <div class="bk-album-item"><img src="https://picsum.photos/280/220?random=3"></div>
+                        <div class="bk-album-item" th:each="item : *{imageList}">
+                            <img th:src="${item.image}" th:if="${item.type == 1}">
+                            <video th:src="${item.image}" th:if="${item.videoUrl == 2}"></video>
+                        </div>
                     </div>
                 </div>
                 <div class="bk-company">
@@ -96,59 +65,13 @@
                     <ul class="bk-directory-list" id="bk-directory-mobile"></ul>
                 </div>
             </div>
-            <div class="bk-section">
-                <div class="bk-title"><h2>主要成分</h2>
-                    <div class="line"></div>
-                </div>
-                <p>
-                    透明质酸是一种酸性粘多糖,1934年美国哥伦比亚大学眼科教授Meyer等首先从牛眼玻璃体中分离出该物质。透明质酸以其独特的分子结构和理化性质在机体内显示出多种重要的生理功能,如润滑关节,调节血管壁的通透性,调节蛋白质,水电解质扩散及运转,促进创伤愈合等。</p>
-            </div>
-            <div class="bk-section">
-                <div class="bk-title"><h2>名称</h2>
-                    <div class="line"></div>
-                </div>
-                <p>透明质酸,又名玻尿酸,hyaluronic acid的hyal 意思是像玻璃一样的、光亮透明的,而uronicacid指的是</p>
-            </div>
-            <div class="bk-section">
-                <div class="bk-title"><h2>主要用途</h2>
-                    <div class="line"></div>
-                </div>
-                <p>具有较高临床价值的生化药物,广泛应用于各类眼科手术,如晶体植入、角膜移植和抗青光眼手术等。还可用于治疗关节炎和加速
-                    伤口愈合。将其用于化妆品中,能起到独特的保护皮肤作用,可保持皮肤滋润光滑、细腻柔嫩、富有弹性,具有防皱、抗皱、美容保健
-                    和恢复皮肤生理功能的作用。</p>
-            </div>
-            <div class="bk-section">
-                <div class="bk-title"><h2>美容作用</h2>
-                    <div class="line"></div>
-                </div>
-                <h3>去除皱纹</h3>
-                <p>1、透明质酸美容应用于皱眉纹(眉间纹)及鱼尾纹过度凹陷之皱眉纹,单以肉毒素注射时,往往无法得到满意的效果,并用透明质
-                    酸注射时,效果会更佳。</p>
-                <p>2、透明质酸美容应用于嘴角纹嘟嘴时所产生的纹路,虽属动态纹路,用透明质酸将凹陷之纹路予以填补,即有不错之效果。</p>
-                <p>3、透明质酸美容应用于法令纹(鼻唇沟)法令纹的消除,是透明质酸除皱作用中最常使用的目的。依照皱鼻纹的深浅依皱纹深浅程
-                    度与部位,一般约需2针大分子之注射量,注射部位包括外侧鼻翼凹陷处、法令纹本身与嘴唇外侧下方。</p>
-            </div>
-            <div class="bk-section">
-                <div class="bk-title"><h2>注射注意事项</h2>
-                    <div class="line"></div>
-                </div>
-                <h3>1、注射前注意事项:</h3>
-                <p>在治疗前,请保持肌肤的清洁,任何化妆品和护肤品都需要清洁干净。建议使用洁面乳和收敛水来清洁皮肤。使用冷水清洁,以便
-                    毛孔收缩。强烈建议患者在治疗前至少3-4天内,不要服用消炎药(如阿司匹林等),因为其有可能会加剧注射部位出血和肿胀。</p>
-                <h3>2、注射后注意事项:</h3>
-                <p>在注射治疗后,请保持面部放松,勿做过多的面部表情。在治疗后至少两周内,请避免接触高热环境(如桑拿等),因其可能会导致面
-                    部注射的透明质酸被很快分解,从而缩短填充效果。请勿触摸或按摩注射部位。</p>
-                <h3>3、不良反应:</h3>
-                <p>皮肤出现炎性反应,通常伴随按压痛感,持续一周左右,注射部位暂时性肿胀,持续的不良反应请立刻通知注射医生。</p>
-            </div>
-            <div class="bk-section">
-                <div class="bk-title"><h2>辨别真假产品</h2>
+            <div class="bk-section" th:each="item : *{textInfoList}">
+                <div class="bk-title" th:if="${item.dictionaryType == 1}">
+                    <h2 th:utext="${item.dictionaryContent}">美容作用</h2>
                     <div class="line"></div>
                 </div>
-                <p>市面上出售的容易与透明质酸混淆的微整形注射填充材料,一般有五种,包括:奥美定(或英捷尔法乐)、硅胶油、石蜡油、纤维素、
-                    胶原蛋白。有一种简单识别奥美定的方法--有些含有奥美定的“透明质酸”绝大多数是在美容院销售和一些无资质的整形医生自带到美
-                    容院给美容院的客人注射,一个在美容院注射针剂,颞部是在针剂注射后表现的是浮肿状态,这就是奥美定的表现,满街都是假的透明
-                    质酸和胶原蛋白,不法分子用低价格博得了一些低消费能力的求美者青睐,结果受骗上当,所以需要很好的鉴别。</p>
+                <h3 th:if="${item.dictionaryType == 2}" th:utext="${item.dictionaryContent}"></h3>
+                <p th:if="${item.dictionaryType == 3}" th:utext="${item.dictionaryContent}"></p>
             </div>
             <div class="bk-literature">
                 <div class="bk-title">
@@ -156,32 +79,53 @@
                     <div class="line"></div>
                 </div>
                 <ul class="bk-literature-list">
-                    <li>[1] 王镜岩、朱胜庚、徐长法.生物化学:高等教育出版社,2002</li>
-                    <li>[2] 透明质酸.化源网[引用日期2022-10-18]</li>
-                    <li>[3] 谢仕斌,姚集鲁,郑荣琴等. 血清透明质酸,Ⅲ型前胶原,Ⅳ型胶原水平与肝纤维化的关系.《 中华传染病杂志 》,1999</li>
-                    <li>[4] 透明质酸.化源网[引用日期2022-10-18]</li>
+                    <th:block th:each="item :*{referenceList}">
+                        <li th:if="${item.referenceType == 1}" th:id="${item.ctrlId}">
+                            [<em>1</em>]
+                            <i></i>
+                            <a class="link" th:href="${item.website}" th:text="${item.articleName}"></a>.
+                            <span th:text="${item.websiteName}"></span>
+                            <span th:if="${item.acitationTimeStr}">[引用日期:<span th:text="${item.acitationTimeStr}"></span>]</span>
+                        </li>
+                        <li th:if="${item.referenceType == 2}">
+                            [<em>1</em>]
+                            <i></i>
+                            <span th:text="${item.author}"></span>
+                            <span th:text="${item.workName}"></span>:
+                            <span th:text="${item.press}"></span>,
+                            <span th:text="${item.publicationYearStr}"></span>
+                        </li>
+                        <li th:if="${item.referenceType == 3}">
+                            [<em>1</em>]
+                            <i></i>
+                            <span th:text="${item.referenceDescription}"></span>
+                            <span th:text="${item.imageDescription}"></span>
+                            <a class="image" th:href="${item.imageUrl}" th:text="${item.articleName}" target="_blank">图片</a>
+                        </li>
+                    </th:block>
                 </ul>
             </div>
             <div class="bk-pv">
-                <div class="bk-pv-item">浏览次数:<span>35</span></div>
-                <div class="bk-pv-item">2022-12-12</div>
+                <div class="bk-pv-item">浏览次数:<span th:text="*{pv}"></span></div>
+                <div class="bk-pv-item" th:text="*{publishTime}"></div>
             </div>
         </div>
         <div class="bk-detail-right only-pc">
-            <div class="bk-album">
+            <div class="bk-album" th:if="*{#lists.size(imageList) ne 0}">
                 <div class="swiper-container" id="album">
                     <div class="swiper-wrapper">
-                        <div class="swiper-slide"><img src="https://picsum.photos/280/220?random=1"></div>
-                        <div class="swiper-slide"><img src="https://picsum.photos/280/220?random=2"></div>
-                        <div class="swiper-slide"><img src="https://picsum.photos/280/220?random=3"></div>
+                        <div class="swiper-slide" th:each="item : *{imageList}">
+                            <img th:src="${item.image}" th:if="${item.type == 1}">
+                            <video th:src="${item.image}" th:if="${item.videoUrl == 2}"></video>
+                        </div>
                     </div>
                     <div class="swiper-pagination"></div>
                 </div>
-                <div class="bk-title">透明质酸的概述图册</div>
+                <div class="bk-title"><span th:text="*{name}"></span>的概述图册</div>
             </div>
-            <div class="bk-company">
-                <img src="https://picsum.photos/280/220?random=4">
-                <div class="bk-title">上海品辉医疗科技有限公司</div>
+            <div class="bk-company" th>
+                <img th:src="*{shopLogo}">
+                <div class="bk-title" th:text="*{shopName}">上海品辉医疗科技有限公司</div>
             </div>
             <div class="bk-directory">
                 <div class="bk-title">文章目录</div>

+ 14 - 24
src/main/resources/templates/encyclopedia/list.html

@@ -17,35 +17,25 @@
 
 <main>
     <!-- banner区域 -->
-    <div class="bk-banner">
-        <img src="/img/encyclopedia/assets/pc-banner.png" alt="采美百科" class="only-pc">
-        <img src="/img/encyclopedia/assets/h5-banner.png" alt="采美百科" class="only-mobile">
+    <a th:href="${Typedata.bannerLink}" th:if="Typedata.bannerLink">
+        <div class="bk-banner">
+            <img th:src="${Typedata.pcBanner}" alt="采美百科" class="only-pc">
+            <img th:src="${Typedata.appBanner}" alt="采美百科" class="only-mobile">
+        </div>
+    </a>
+    <div class="bk-banner" th:if="!Typedata.bannerLink">
+        <img th:src="${Typedata.pcBanner}" alt="采美百科" class="only-pc">
+        <img th:src="${Typedata.appBanner}" alt="采美百科" class="only-mobile">
     </div>
     <!-- banner区域 end -->
     <!-- 百科列表区域 -->
     <div class="bk-list bk-container">
-        <a href="/encyclopedia/detail-1.html" class="bk-list-item">
-            <div class="bk-cover"><img src="https://picsum.photos/160/168" alt="如何有效提升产研效率和质量"/></div>
-            <div class="bk-info">
-                <h2>如何有效提升产研效率和质量?</h2>
-                <p>在产品不断更迭的过程中,为了保证产品设计的一致性和质量,就得提升产研链路的效率。然而,面对越来越复杂的产品,如何解决团队效率和产品质量问题呢?一起来看一下吧。</p>
-                <div class="bk-info-footer"><span>浏览量:3343</span><span>2022-12-08</span></div>
-            </div>
-        </a>
-        <a href="#" class="bk-list-item">
-            <div class="bk-cover"><img src="https://picsum.photos/160/168" alt="如何有效提升产研效率和质量"/></div>
-            <div class="bk-info">
-                <h2>如何有效提升产研效率和质量?</h2>
-                <p>在产品不断更迭的过程中,为了保证产品设计的一致性和质量,就得提升产研链路的效率。然而,面对越来越复杂的产品,如何解决团队效率和产品质量问题呢?一起来看一下吧。</p>
-                <div class="bk-info-footer"><span>浏览量:3343</span><span>2022-12-08</span></div>
-            </div>
-        </a>
-        <a href="#" class="bk-list-item">
-            <div class="bk-cover"><img src="https://picsum.photos/160/168" alt="如何有效提升产研效率和质量"/></div>
+        <a th:href="'/encyclopedia/detail-' + ${item.id} + '.html'" class="bk-list-item" th:each="item : ${authUserList}" th:object="${item}">
+            <div class="bk-cover"><img th:src="*{image}" th:alt="*{name}"/></div>
             <div class="bk-info">
-                <h2>如何有效提升产研效率和质量?</h2>
-                <p>在产品不断更迭的过程中,为了保证产品设计的一致性和质量,就得提升产研链路的效率。然而,面对越来越复杂的产品,如何解决团队效率和产品质量问题呢?一起来看一下吧。</p>
-                <div class="bk-info-footer"><span>浏览量:3343</span><span>2022-12-08</span></div>
+                <h2 th:text="*{name}"></h2>
+                <p th:utext="*{discription}"></p>
+                <div class="bk-info-footer"><span>浏览量:<span th:text="*{pv lt 10000 ? pv : '9999+'}"></span></span><span th:text="*{publishTimeStr}"></span></div>
             </div>
         </a>
     </div>

+ 65 - 88
src/main/resources/templates/supplier-center/encyclopedia/edit.html

@@ -36,27 +36,28 @@
                     <el-form :rules="rules" :model="formData" ref="ruleForm" label-position="top">
                         <el-form-item label="词条名称:" prop="name">
                             <el-input v-model="formData.name" placeholder="请输入词条名称"></el-input>
-                            <div class="el-form-item__error" v-show="false">敏感词:减肥、溶脂</div>
+                            <div class="el-form-item__error" v-if="formValidate.name">{{formValidate.name}}</div>
                         </el-form-item>
                         <el-form-item label="义项名:" prop="alias">
                             <content-edit
-                                    :reference-list="referenceList"
+                                    :reference-list="formData.referenceList"
                                     @reference-edit="handleReferenceEdit"
                                     @toolbar="handleToolbarClick"
                                     v-model="formData.alias"
                             ></content-edit>
                             <el-input v-model="formData.alias" placeholder="请输入义项名,简要说明该事物区别于同名事物的显著特征"
                                       v-show="false"></el-input>
-                            <div class="el-form-item__error" v-show="false">敏感词:减肥、溶脂</div>
+                            <div class="el-form-item__error" v-if="formValidate.alias">{{formValidate.alias}}</div>
                         </el-form-item>
-                        <el-form-item label="词条概述:" prop="description">
+                        <el-form-item label="词条概述:" prop="discription">
                             <content-edit
-                                    :reference-list="referenceList"
+                                    :reference-list="formData.referenceList"
                                     @reference-edit="handleReferenceEdit"
                                     @toolbar="handleToolbarClick"
+                                    v-model="formData.discription"
                             ></content-edit>
-                            <el-input v-model="formData.description" placeholder="请输入词条概述" v-show="false"></el-input>
-                            <div class="el-form-item__error" v-show="false">敏感词:减肥、溶脂</div>
+                            <el-input v-model="formData.discription" placeholder="请输入词条概述" v-show="false"></el-input>
+                            <div class="el-form-item__error" v-if="formValidate.discription">{{formValidate.discription}}</div>
                         </el-form-item>
                         <el-form-item>
                             <label class="el-form-item__label">概述图册:<span>(注:未上传图片将不会显示在词条页上,最多上传6张)</span></label>
@@ -64,77 +65,52 @@
                             <file-upload @upload-success="handleUploadSuccess" @remove="handleFileRemove" :list="fileList" :limit="6"></file-upload>
                         </el-form-item>
                         <!-- 信息栏 -->
-                        <div class="bk-label">信息栏<span>(注:未填写的信息项将不会显示在词条页上)</span></div>
-                        <el-form-item label="中文名:">
-                            <content-edit
-                                    :reference-list="referenceList"
-                                    @reference-edit="handleReferenceEdit"
-                                    @toolbar="handleToolbarClick"
-                            ></content-edit>
-                            <el-input v-model="formData.entryName" placeholder="请输入中文名" v-show="false"></el-input>
-                            <div class="el-form-item__error" v-show="false">敏感词:减肥、溶脂</div>
-                        </el-form-item>
-                        <el-form-item label="别名:">
-                            <content-edit
-                                    :reference-list="referenceList"
-                                    @reference-edit="handleReferenceEdit"
-                                    @toolbar="handleToolbarClick"
-                            ></content-edit>
-                            <el-input v-model="formData.entryName" placeholder="请输入别名" v-show="false"></el-input>
-                            <div class="el-form-item__error" v-show="false">敏感词:减肥、溶脂</div>
-                        </el-form-item>
-                        <el-form-item label="英文名:">
-                            <content-edit
-                                    :reference-list="referenceList"
-                                    @reference-edit="handleReferenceEdit"
-                                    @toolbar="handleToolbarClick"
-                            ></content-edit>
-                            <el-input v-model="formData.entryName" placeholder="请输入英文名" v-show="false"></el-input>
-                            <div class="el-form-item__error" v-show="false">敏感词:减肥、溶脂</div>
-                        </el-form-item>
+                        <div class="bk-label">信息栏<span>(注:未填写的信息项将不会显示在词条页上)</span><span class="bk-info-add" @click="handleInfoAdd">增加信息项</span></div>
+                        <div class="bk-form-item-group" v-for="(item, index) in formData.infoList" :key="index">
+                            <span class="bk-info-remove" v-if="formData.infoList.length > 4" @click="handleInfoRemove(index)">删除</span>
+                            <el-form-item>
+                                <el-input v-model="item.infoName"></el-input>
+                                <div class="el-form-item__error" v-if="formValidate.infoList">{{formValidate.infoList}}</div>
+                            </el-form-item>
+                            <el-form-item>
+                                <content-edit
+                                        v-model="item.infoContent"
+                                        :reference-list="formData.referenceList"
+                                        @reference-edit="handleReferenceEdit"
+                                        @toolbar="handleToolbarClick">
+                                </content-edit>
+                                <el-input v-model="item.infoContent" v-show="false"></el-input>
+                                <div class="el-form-item__error" v-if="formValidate.referenceList">{{formValidate.referenceList}}</div>
+                            </el-form-item>
+                        </div>
                         <!-- 正文 -->
                         <div class="bk-label">正文<span>(注:未填写的信息项将不会显示在词条页上)</span></div>
-                        <el-form-item>
-                            <div class="bk-form-item">
-                                <el-input v-model="formData.entryName" placeholder="定义(一级目录)"></el-input>
-                                <div class="bk-section">
-                                    <span>一级目录</span>
-                                    <span>二级目录</span>
-                                    <span>内容</span>
-                                    <span class="delete">删除</span>
-                                </div>
-                            </div>
-                            <div class="el-form-item__error" v-show="false">敏感词:减肥、溶脂</div>
-                        </el-form-item>
-                        <el-form-item>
+                        <el-form-item v-for="(item, index) in formData.textInfoList" :key="index">
                             <div class="bk-form-item">
-                                <el-input v-model="formData.entryName" placeholder="定义(二级目录)"></el-input>
+                                <template v-if="item.dictionaryType !== 3">
+                                    <el-input v-model="item.dictionaryContent" :placeholder="item.placeholder"></el-input>
+                                </template>
+                                <template v-else>
+                                    <content-edit
+                                            v-model="item.dictionaryContent"
+                                            :reference-list="formData.referenceList"
+                                            @reference-edit="handleReferenceEdit"
+                                            @toolbar="handleToolbarClick">
+                                    </content-edit>
+                                </template>
                                 <div class="bk-section">
-                                    <span>一级目录</span>
-                                    <span>二级目录</span>
-                                    <span>内容</span>
-                                    <span class="delete">删除</span>
+                                    <span @click="handleAddTextInfo(index, 1)">一级目录</span>
+                                    <span @click="handleAddTextInfo(index, 2)">二级目录</span>
+                                    <span @click="handleAddTextInfo(index, 3)">内容</span>
+                                    <span class="delete" @click="handleRemoveTextInfo(index)" v-if="formData.textInfoList.length > 3">删除</span>
                                 </div>
                             </div>
-                            <div class="el-form-item__error" v-show="false">敏感词:减肥、溶脂</div>
-                        </el-form-item>
-                        <el-form-item>
-                            <div class="bk-form-item">
-                                <content-edit @toolbar="handleToolbarClick"></content-edit>
-                                <div class="bk-section">
-                                    <span>一级目录</span>
-                                    <span>二级目录</span>
-                                    <span>内容</span>
-                                    <span class="delete">删除</span>
-                                </div>
-                            </div>
-                            <el-input v-model="formData.entryName" placeholder="内容" v-show="false"></el-input>
-                            <div class="el-form-item__error" v-show="false">敏感词:减肥、溶脂</div>
+                            <div class="el-form-item__error" v-if="formValidate.textInfoList">{{formValidate.textInfoList}}</div>
                         </el-form-item>
                         <!-- 参考资料 -->
                         <div class="bk-label">参考资料</div>
                         <ul class="bk-literature-list">
-                            <li v-for="(item, index) in referenceList">
+                            <li v-for="(item, index) in formData.referenceList">
                                 <div><span>[{{index+1}}]</span><span>{{item | reference}}</span></div>
                                 <div class="bk-ref-control">
                                     <span class="edit" @click="handleReferenceEdit(item)"></span>
@@ -143,37 +119,37 @@
                             </li>
                         </ul>
                         <div class="bk-label"><em>*</em>头图<i>(建议图片尺寸210px*210px,并上传白底图片)</i></div>
-                        <el-form-item prop="img">
-                            <el-input v-show="false" v-model="formData.img"></el-input>
+                        <el-form-item prop="image">
+                            <el-input v-show="false" v-model="formData.image"></el-input>
                             <file-upload @upload-success="handleCoverUploadSuccess" @remove="handleCoverRemove" :list="coverList"></file-upload>
                         </el-form-item>
-                        <el-form-item label="分类:">
+                        <el-form-item label="分类:" prop="typeId">
                             <el-select class="max-width" v-model="formData.typeId">
-                                <el-option label="分类1" value="1"></el-option>
-                                <el-option label="分类2" value="2"></el-option>
-                                <el-option label="分类3" value="3"></el-option>
+                                <template v-for="item in typeList">
+                                    <el-option :label="item.name" :value="item.typeId"></el-option>
+                                </template>
                             </el-select>
                         </el-form-item>
                         <el-form-item label="SEO关键词:">
                             <el-input v-model="formData.seoKeyword" placeholder="例如:面膜"></el-input>
-                            <div class="el-form-item__error" v-show="false">敏感词:减肥、溶脂</div>
+                            <div class="el-form-item__error" v-if="formValidate.seoKeyword">{{formValidate.seoKeyword}}</div>
                         </el-form-item>
-                        <el-form-item>
+                        <el-form-item prop="status">
                             <div class="bk-status">
                                 <label class="el-form-item__label">状态:</label>
                                 <el-radio-group v-model="formData.status">
-                                    <el-radio :label="0">发布</el-radio>
-                                    <el-radio :label="1">保存草稿箱</el-radio>
+                                    <el-radio :label="1">发布</el-radio>
+                                    <el-radio :label="0">保存草稿箱</el-radio>
                                 </el-radio-group>
                             </div>
                         </el-form-item>
                         <el-form-item>
-                            <div class="bk-control">
-                                <button class="bk-back">返回</button>
-                                <button class="bk-confirm">保存</button>
-                            </div>
                         </el-form-item>
                     </el-form>
+                    <div class="bk-control">
+                        <button class="bk-back">返回</button>
+                        <button class="bk-confirm" @click="handleConfirm">保存</button>
+                    </div>
                 </div>
             </div>
         </div>
@@ -189,9 +165,9 @@
             </div>
             <div class="bk-dialog-content">
                 <template v-if="referenceType === 1">
-                    <el-form label-width="110px" :model="referenceData" :rules="referenceRule">
-                        <el-form-item label="参考资料类型" prop="referenceType">
-                            <el-select class="max-width" v-model="referenceData.referenceType">
+                    <el-form label-width="110px" ref="referenceForm" :model="referenceData" :rules="referenceRule">
+                        <el-form-item label="参考资料类型">
+                            <el-select class="max-width" v-model="referenceData.referenceType" @change="handleReferenceTypeChange">
                                 <el-option label="网络资料" :value="1"></el-option>
                                 <el-option label="著作资料" :value="2"></el-option>
                                 <el-option label="其它资料" :value="3"></el-option>
@@ -199,7 +175,7 @@
                         </el-form-item>
                         <template v-if="referenceData.referenceType === 1">
                             <el-form-item label="输入网址" prop="website">
-                                <el-input placeholder="请以htpp(s)://开头" v-model="referenceData.website"></el-input>
+                                <el-input placeholder="请以http(s)://开头" v-model="referenceData.website"></el-input>
                             </el-form-item>
                             <el-form-item label="文章名字" prop="articleName">
                                 <el-input placeholder="请输入文章名字" v-model="referenceData.articleName"></el-input>
@@ -262,8 +238,8 @@
                 </template>
                 <template v-if="referenceType === 2">
                     <ul class="bk-literature-list">
-                        <template v-for="(item, index) in referenceList">
-                            <li :key="item.ctrlId" @click="handleSelectReference(item)"><span>[{{index+1}}]</span><span>{{item | reference}}</span></li>
+                        <template v-for="(item, index) in formData.referenceList">
+                            <li :key="item.ctrlId" @click="handleSelectReference(item, index)"><span>[{{index+1}}]</span><span>{{item | reference}}</span></li>
                         </template>
                     </ul>
                 </template>
@@ -283,6 +259,7 @@
 <script charset="utf-8" type="text/javascript" src="/lib/aliyun-oss-sdk-6.17.1.min.js"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/lib/uuidv4.min.js}"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/js/common/serviceapi/utils.service.js(v=${version})}"></script>
+<script charset="utf-8" type="text/javascript" th:src="@{/js/common/serviceapi/supplier.service.js(v=${version})}"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/js/common/serviceapi/shopBaike.service.js(v=${version})}"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/js/oss-upload.js(v=${version})}"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/js/center.js(v=${version})}"></script>

+ 3 - 3
src/main/resources/templates/supplier-center/encyclopedia/list.html

@@ -104,7 +104,7 @@
                             <div class="bk-td">{{item.id}}</div>
                             <div class="bk-td">{{item.name}}</div>
                             <div class="bk-td">{{item.typeName}}</div>
-                            <div class="bk-td">{{item.pv}}</div>
+                            <div class="bk-td">{{item.pv || 0}}</div>
                             <template>
                                 <div class="bk-td bk-warning" v-if="item.auditStatus === 1">待审核</div>
                                 <div class="bk-td bk-success" v-if="item.auditStatus === 2">审核通过</div>
@@ -139,7 +139,7 @@
                 <div class="bk-pagination">
                     <div class="bk-pagesize">
                         <template v-for="item in pagiantion">
-                            <span v-if="item" :class="{active: item === listQuery.pageNum}" @click="hanldePageClick(item)">{{item}}</span>
+                            <span v-if="item" :class="{active: item == listQuery.pageNum}" @click="hanldePageClick(item)">{{item}}</span>
                             <i v-else>…</i>
                         </template>
                     </div>
@@ -148,7 +148,7 @@
                     </div>
                     <div class="bk-control">
                         <span>跳至</span>
-                        <input type="text" v-model="listQuery.pageNum"/>
+                        <input type="text" v-model="listQuery.pageNum" @blur="getList"/>
                         <span>页</span>
                         <button class="bk-btn" @click="getList">点击跳转</button>
                     </div>